(svn r11221) [NoAI] -Sync: with trunk r11145:11220 noai
authorglx
Sat, 06 Oct 2007 22:30:24 +0000
branchnoai
changeset 9704 197cb8c6ae17
parent 9703 d2a6acdbd665
child 9705 e460e1c9d49a
(svn r11221) [NoAI] -Sync: with trunk r11145:11220
Makefile.in
Makefile.src.in
bin/ai/regression/regression.txt
bin/ai/regression/run.sh
config.lib
docs/landscape.html
docs/landscape_grid.html
projects/openttd.vcproj
projects/openttd_vs80.vcproj
readme.txt
source.list
src/aircraft.h
src/aircraft_cmd.cpp
src/aircraft_gui.cpp
src/articulated_vehicles.cpp
src/autoslope.h
src/blitter/32bpp_base.cpp
src/blitter/8bpp_base.cpp
src/build_vehicle_gui.cpp
src/clear_cmd.cpp
src/depot_gui.cpp
src/direction.h
src/economy.cpp
src/fileio.cpp
src/functions.h
src/gfx.cpp
src/gfx.h
src/industry.h
src/industry_cmd.cpp
src/industry_gui.cpp
src/industry_map.h
src/landscape.cpp
src/lang/american.txt
src/lang/brazilian_portuguese.txt
src/lang/bulgarian.txt
src/lang/catalan.txt
src/lang/croatian.txt
src/lang/czech.txt
src/lang/danish.txt
src/lang/dutch.txt
src/lang/english.txt
src/lang/esperanto.txt
src/lang/estonian.txt
src/lang/finnish.txt
src/lang/french.txt
src/lang/galician.txt
src/lang/german.txt
src/lang/hungarian.txt
src/lang/icelandic.txt
src/lang/italian.txt
src/lang/japanese.txt
src/lang/korean.txt
src/lang/lithuanian.txt
src/lang/norwegian_bokmal.txt
src/lang/norwegian_nynorsk.txt
src/lang/piglatin.txt
src/lang/polish.txt
src/lang/portuguese.txt
src/lang/romanian.txt
src/lang/russian.txt
src/lang/simplified_chinese.txt
src/lang/slovak.txt
src/lang/slovenian.txt
src/lang/spanish.txt
src/lang/swedish.txt
src/lang/traditional_chinese.txt
src/lang/turkish.txt
src/lang/ukrainian.txt
src/lang/unfinished/afrikaans.txt
src/lang/unfinished/greek.txt
src/macros.h
src/main_gui.cpp
src/map.h
src/misc.cpp
src/misc_cmd.cpp
src/music/win32_m.cpp
src/network/network_gui.cpp
src/newgrf.cpp
src/newgrf_callbacks.h
src/newgrf_commons.cpp
src/newgrf_commons.h
src/newgrf_config.cpp
src/newgrf_gui.cpp
src/newgrf_house.cpp
src/newgrf_industries.cpp
src/newgrf_industries.h
src/newgrf_industrytiles.cpp
src/newgrf_industrytiles.h
src/newgrf_sound.cpp
src/newgrf_spritegroup.cpp
src/newgrf_spritegroup.h
src/newgrf_station.cpp
src/openttd.cpp
src/order.h
src/order_cmd.cpp
src/rail_cmd.cpp
src/road.cpp
src/road.h
src/road_cmd.cpp
src/roadveh_cmd.cpp
src/roadveh_gui.cpp
src/saveload.cpp
src/settings.cpp
src/settings_gui.cpp
src/ship_cmd.cpp
src/ship_gui.cpp
src/slope.h
src/station_cmd.cpp
src/town_cmd.cpp
src/town_gui.cpp
src/train_cmd.cpp
src/train_gui.cpp
src/tunnelbridge_cmd.cpp
src/variables.h
src/vehicle.cpp
src/vehicle_gui.cpp
src/viewport.cpp
src/viewport.h
--- a/Makefile.in	Sun Sep 23 07:37:38 2007 +0000
+++ b/Makefile.in	Sat Oct 06 22:30:24 2007 +0000
@@ -23,8 +23,6 @@
 INSTALL_ICON_DIR = "$(INSTALL_DIR)/"!!ICON_DIR!!
 INSTALL_DATA_DIR = "$(INSTALL_DIR)/"!!DATA_DIR!!
 INSTALL_PERSONAL_DIR = !!PERSONAL_DIR!!
-# TODO: ENABLE_INSTALL should be removed when the search path patch has been applied
-ENABLE_INSTALL = !!ENABLE_INSTALL!!
 TTD = !!TTD!!
 TTDS = $(SRC_DIRS:%=%/$(TTD))
 OS = !!OS!!
@@ -221,6 +219,9 @@
 ifeq ($(shell if test -n "`ls -l \"$(BIN_DIR)/scenario/heightmaps/\"* 2>/dev/null`"; then echo 1; fi), 1)
 	$(Q)cp "$(BIN_DIR)/scenario/heightmaps/"* "$(BUNDLE_DIR)/scenario/heightmap/"
 endif
+ifeq ($(TTD), openttd.exe)
+	$(Q)unix2dos "$(BUNDLE_DIR)/docs/"* "$(BUNDLE_DIR)/readme.txt" "$(BUNDLE_DIR)/COPYING"
+endif
 
 ### Packing the current bundle into several compressed file formats ###
 #
--- a/Makefile.src.in	Sun Sep 23 07:37:38 2007 +0000
+++ b/Makefile.src.in	Sat Oct 06 22:30:24 2007 +0000
@@ -102,8 +102,14 @@
 else
 # Are we a git dir?
 ifeq ($(shell if test -d $(SRC_DIR)/../.git; then echo 1; fi), 1)
-# Find the revision like: rXXXXM
-REV := g$(shell if head=`git rev-parse --verify HEAD 2>/dev/null`; then echo "$$head" | cut -c1-8; fi)$(shell if git diff-index HEAD | read dummy; then echo M; fi)$(shell git branch|grep '[*]'|sed 's/\* /-/;s/^-master$$//')
+# Find the revision like: gXXXXM-branch
+REV := g$(shell if head=`LC_ALL=C git rev-parse --verify HEAD 2>/dev/null`; then echo "$$head" | cut -c1-8; fi)$(shell if git diff-index HEAD | read dummy; then echo M; fi)$(shell git branch|grep '[*]' | sed 's/\* /-/;s/^-master$$//')
+else
+# Are we a hg (Mercurial) dir?
+ifeq ($(shell if test -d $(SRC_DIR)/../.hg; then echo 1; fi), 1)
+# Find the revision like: hXXXXM-branch
+REV := h$(shell if head=`LC_ALL=C hg tip 2>/dev/null`; then echo "$$head" | head -n 1 | cut -c19-26; fi)$(shell if hg status | grep -v '^?' | read dummy; then echo M; fi)$(shell hg branch | sed 's/^/-/;s/^-default$$//')
+endif
 endif
 endif
 endif
--- a/bin/ai/regression/regression.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/bin/ai/regression/regression.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -9,21 +9,21 @@
  abs( 21): 21
 
 --AIBase--
-  Rand():       438016824
-  Rand():       1155512394
-  Rand():       -1230912451
+  Rand():       -1692638405
+  Rand():       -1170386787
+  Rand():       190814891
   RandRange(0): 0
   RandRange(0): 0
   RandRange(0): 0
   RandRange(1): 0
   RandRange(1): 0
   RandRange(1): 0
-  RandRange(2): 1
   RandRange(2): 0
   RandRange(2): 0
-  RandRange(9): 0
-  RandRange(9): 1
-  RandRange(9): 7
+  RandRange(2): 0
+  RandRange(9): 4
+  RandRange(9): 6
+  RandRange(9): 2
   Chance(1, 2): true
   Chance(1, 2): true
   Chance(1, 2): false
@@ -137,144 +137,144 @@
     1098 => 1098
     1099 => 1099
   Randomize ListDump:
-    1 => 12862691
-    2 => -1917812707
-    1000 => 1421163554
-    1001 => -312664745
-    1002 => -2068922958
-    1003 => 1861130245
-    1004 => 1649688256
-    1005 => 15955316
-    1006 => 1355779470
-    1007 => 865353559
-    1008 => 803536462
-    1009 => -1712495000
-    1010 => -1505961326
-    1011 => -870330146
-    1012 => 126669570
-    1013 => -805020189
-    1014 => 793365509
-    1015 => 913987592
-    1016 => -720783506
-    1017 => 1926417138
-    1018 => -683369878
-    1019 => 446485522
-    1020 => 537800773
-    1021 => -615490971
-    1022 => 1776085247
-    1023 => -1869659646
-    1024 => 1353595954
-    1025 => 1880025847
-    1026 => 56594834
-    1027 => 1165500481
-    1028 => 1086094131
-    1029 => -263041456
-    1030 => 1130819676
-    1031 => 1868532194
-    1032 => 406052492
-    1033 => 529742212
-    1034 => 1549122406
-    1035 => 1528374594
-    1036 => -1586709059
-    1037 => -1866528486
-    1038 => -2123636907
-    1039 => 2060223021
-    1040 => -982427121
-    1041 => -99903420
-    1042 => 373385608
-    1043 => -1522828933
-    1044 => -1560504629
-    1045 => -2077599081
-    1046 => -782857017
-    1047 => 192681035
-    1048 => -642978559
-    1049 => 1723023122
-    1051 => 1181099329
-    1052 => -1581037797
-    1053 => -1856480328
-    1054 => -360359556
-    1055 => 2087072896
-    1056 => 1566859460
-    1057 => 490730845
-    1058 => -871118486
-    1059 => -1265136557
-    1060 => -1710287301
-    1061 => 624475954
-    1062 => 1448791554
-    1063 => -1448570564
-    1064 => -923161374
-    1065 => -1175940076
-    1066 => 1633634195
-    1067 => 474627780
-    1068 => -1754850936
-    1069 => -970278622
-    1070 => -1005842954
-    1071 => -1149168206
-    1072 => -1107909687
-    1073 => -1319038694
-    1074 => 1057817048
-    1075 => 410375978
-    1076 => 37823872
-    1077 => 2005120480
-    1078 => 2001195837
-    1079 => 2132885814
-    1080 => -809853417
-    1081 => -1575623843
-    1082 => -598915313
-    1083 => 620318589
-    1084 => -2127761983
-    1085 => -507862777
-    1086 => -245405898
-    1087 => -811840780
-    1088 => 571811265
-    1089 => 1695322056
-    1090 => 1956157477
-    1091 => -495557029
-    1092 => -1727000177
-    1093 => -1572068837
-    1094 => -1100027091
-    1095 => -677705398
-    1096 => 742793210
-    1097 => 431459282
-    1098 => -1694029724
-    1099 => 105515356
+    1 => 581150761
+    2 => 780195416
+    1000 => -1005781929
+    1001 => -304338569
+    1002 => -1743669342
+    1003 => 2052174274
+    1004 => -239846598
+    1005 => -519154508
+    1006 => 1384592592
+    1007 => 92537681
+    1008 => -783011799
+    1009 => 1020927039
+    1010 => -762645416
+    1011 => 1654042603
+    1012 => 210165652
+    1013 => -1851586478
+    1014 => 208319733
+    1015 => -1211393332
+    1016 => 2052272773
+    1017 => -1489194376
+    1018 => -438907823
+    1019 => 130289291
+    1020 => -1283324111
+    1021 => -259554489
+    1022 => 1143992540
+    1023 => -1301766703
+    1024 => 2067670203
+    1025 => 1726364654
+    1026 => 939556491
+    1027 => -1134709978
+    1028 => -110608336
+    1029 => 1339284138
+    1030 => -472993361
+    1031 => 958802835
+    1032 => 761440845
+    1033 => -1469223188
+    1034 => -721599317
+    1035 => 434887418
+    1036 => -820146882
+    1037 => 274760994
+    1038 => -522727528
+    1039 => -669489971
+    1040 => 1377115572
+    1041 => 516401345
+    1042 => 295153940
+    1043 => -1055199725
+    1044 => -1143220467
+    1045 => -686775621
+    1046 => 867901084
+    1047 => 1693214681
+    1048 => -1112224853
+    1049 => 659718584
+    1051 => -1132568097
+    1052 => -1370768491
+    1053 => -1233695197
+    1054 => 824602143
+    1055 => 1213169381
+    1056 => 1616397171
+    1057 => -1494293955
+    1058 => 168525123
+    1059 => 985183216
+    1060 => 163496891
+    1061 => -1920407820
+    1062 => 512739738
+    1063 => 1098365126
+    1064 => 1522198446
+    1065 => 152025258
+    1066 => -1654530986
+    1067 => 1386785618
+    1068 => -49512268
+    1069 => 1214031860
+    1070 => 458782250
+    1071 => -1641082778
+    1072 => -1284412562
+    1073 => 1507095104
+    1074 => -1103314033
+    1075 => -837829736
+    1076 => 1245363646
+    1077 => -1003369287
+    1078 => -729296780
+    1079 => -2042801701
+    1080 => 690945725
+    1081 => 844366079
+    1082 => 1659029417
+    1083 => 585818047
+    1084 => -1199106717
+    1085 => 680742150
+    1086 => 264108503
+    1087 => -301161571
+    1088 => -132905463
+    1089 => 1892881479
+    1090 => -1903322021
+    1091 => 1017533996
+    1092 => -976386914
+    1093 => -90625762
+    1094 => -1290852461
+    1095 => -1953934605
+    1096 => 112304592
+    1097 => 1238896913
+    1098 => 1436365455
+    1099 => 825503137
   KeepTop(10):
-    1 => 12862691
-    2 => -1917812707
-    1000 => 1421163554
-    1001 => -312664745
-    1002 => -2068922958
-    1003 => 1861130245
-    1004 => 1649688256
-    1005 => 15955316
-    1006 => 1355779470
-    1007 => 865353559
+    1 => 581150761
+    2 => 780195416
+    1000 => -1005781929
+    1001 => -304338569
+    1002 => -1743669342
+    1003 => 2052174274
+    1004 => -239846598
+    1005 => -519154508
+    1006 => 1384592592
+    1007 => 92537681
   KeepBottom(8):
-    1000 => 1421163554
-    1001 => -312664745
-    1002 => -2068922958
-    1003 => 1861130245
-    1004 => 1649688256
-    1005 => 15955316
-    1006 => 1355779470
-    1007 => 865353559
+    1000 => -1005781929
+    1001 => -304338569
+    1002 => -1743669342
+    1003 => 2052174274
+    1004 => -239846598
+    1005 => -519154508
+    1006 => 1384592592
+    1007 => 92537681
   RemoveBottom(2):
-    1000 => 1421163554
-    1001 => -312664745
-    1002 => -2068922958
-    1003 => 1861130245
-    1004 => 1649688256
-    1005 => 15955316
+    1000 => -1005781929
+    1001 => -304338569
+    1002 => -1743669342
+    1003 => 2052174274
+    1004 => -239846598
+    1005 => -519154508
   RemoveTop(2):
-    1002 => -2068922958
-    1003 => 1861130245
-    1004 => 1649688256
-    1005 => 15955316
+    1002 => -1743669342
+    1003 => 2052174274
+    1004 => -239846598
+    1005 => -519154508
   RemoveList({1003, 1004}):
-    1002 => -2068922958
-    1005 => 15955316
+    1002 => -1743669342
+    1005 => -519154508
   KeepList({1003, 1004, 1005}):
-    1005 => 15955316
+    1005 => -519154508
   IsEmpty():     true
 
 --AIAirport--
@@ -332,11 +332,11 @@
   GetHangarOfAirport(): 32119
   IsHangarTile():       true
   IsAirportTile():      true
-  GetBankBalance():     90100
+  GetBankBalance():     90052
   RemoveAirport():      true
   IsHangarTile():       false
   IsAirportTile():      false
-  GetBankBalance():     89836
+  GetBankBalance():     89788
   BuildAirport():       true
 
 --AICargo--
@@ -378,7 +378,7 @@
     IsFreight():             true
     GetCargoIncome(0, 0):    0
     GetCargoIncome(10, 10):  5
-    GetCargoIncome(100, 10): 53
+    GetCargoIncome(100, 10): 54
     GetCargoIncome(10, 100): 3
   Cargo 4
     IsValidCargo():          true
@@ -410,7 +410,7 @@
     IsFreight():             true
     GetCargoIncome(0, 0):    0
     GetCargoIncome(10, 10):  6
-    GetCargoIncome(100, 10): 60
+    GetCargoIncome(100, 10): 61
     GetCargoIncome(10, 100): 4
   Cargo 8
     IsValidCargo():          true
@@ -475,11 +475,11 @@
   SetCompanyName():     true
   SetCompanyName():     false
   GetCompanyName():            Regression
-  GetPresidentName():          L. Parker
+  GetPresidentName():          I. Gribble
   SetPresidentName():          true
   GetPresidentName():          Regression AI
   GetCompanyValue():           0
-  GetBankBalance():            84436
+  GetBankBalance():            84364
   GetCompanyName():            (null : 0x00000000)
   GetLoanAmount():             100000
   GetMaxLoanAmount():          300000
@@ -487,13 +487,13 @@
   SetLoanAmount(1):            false
   SetLoanAmount(100):          false
   SetLoanAmount(10000):        false
-  GetBankBalance():            84436
+  GetBankBalance():            84364
   GetLoanAmount():             100000
   SetMinimumLoanAmount(31337): true
-  GetBankBalance():            24436
+  GetBankBalance():            24364
   GetLoanAmount():             40000
   SetLoanAmount(10000):        true
-  GetBankBalance():            284436
+  GetBankBalance():            284364
   GetLoanAmount():             300000
 
 --Event--
@@ -1022,15 +1022,8 @@
     62 => 569
     47 => 488
   KeepAboveValue(50): done
-  Count():             7
+  Count():             0
   Production ListDump:
-    17 => 80
-    15 => 72
-    20 => 68
-    18 => 68
-    22 => 57
-    16 => 56
-    21 => 52
 
 --Map--
   GetMapSize():     65536
@@ -1065,7 +1058,7 @@
   IsBuoyTile():         false
   IsLockTile():         false
   IsCanalTile():        false
-  GetBankBalance():     284108
+  GetBankBalance():     284034
   BuildWaterDepot():    true
   BuildDock():          true
   BuildBuoy():          true
@@ -1076,7 +1069,7 @@
   IsBuoyTile():         true
   IsLockTile():         true
   IsCanalTile():        true
-  GetBankBalance():     254559
+  GetBankBalance():     254295
   RemoveWaterDepot():   true
   RemoveDock():         true
   RemoveBuoy():         true
@@ -1087,7 +1080,7 @@
   IsBuoyTile():         false
   IsLockTile():         false
   IsCanalTile():        false
-  GetBankBalance():     231914
+  GetBankBalance():     231503
   BuildWaterDepot():    true
   BuildDock():          true
 
@@ -1501,27 +1494,27 @@
   Town 0
     IsValidTown():   true
     GetName():       Planfield
-    GetPopulation(): 538
+    GetPopulation(): 754
     GetLocation():   15508
   Town 1
     IsValidTown():   true
     GetName():       Trenningville
-    GetPopulation(): 236
+    GetPopulation(): 226
     GetLocation():   46751
   Town 2
     IsValidTown():   true
     GetName():       Tondston
-    GetPopulation(): 253
+    GetPopulation(): 320
     GetLocation():   28365
   Town 3
     IsValidTown():   true
     GetName():       Tunford
-    GetPopulation(): 206
+    GetPopulation(): 211
     GetLocation():   41895
   Town 4
     IsValidTown():   true
     GetName():       Wrundtown
-    GetPopulation(): 414
+    GetPopulation(): 396
     GetLocation():   41450
   Town 5
     IsValidTown():   true
@@ -1531,22 +1524,22 @@
   Town 6
     IsValidTown():   true
     GetName():       Muningville
-    GetPopulation(): 566
+    GetPopulation(): 579
     GetLocation():   38200
   Town 7
     IsValidTown():   true
     GetName():       Hutfingford
-    GetPopulation(): 652
+    GetPopulation(): 777
     GetLocation():   59234
   Town 8
     IsValidTown():   true
     GetName():       Sadtown
-    GetPopulation(): 292
+    GetPopulation(): 290
     GetLocation():   51267
   Town 9
     IsValidTown():   true
     GetName():       Frindinghattan
-    GetPopulation(): 447
+    GetPopulation(): 459
     GetLocation():   5825
   Town 10
     IsValidTown():   true
@@ -1556,12 +1549,12 @@
   Town 11
     IsValidTown():   true
     GetName():       Fort Frindston
-    GetPopulation(): 156
+    GetPopulation(): 197
     GetLocation():   14935
   Town 12
     IsValidTown():   true
     GetName():       Ginborough
-    GetPopulation(): 766
+    GetPopulation(): 853
     GetLocation():   32740
   Town 13
     IsValidTown():   true
@@ -1571,22 +1564,22 @@
   Town 14
     IsValidTown():   true
     GetName():       Prundinghall
-    GetPopulation(): 316
+    GetPopulation(): 336
     GetLocation():   51298
   Town 15
     IsValidTown():   true
     GetName():       Benville
-    GetPopulation(): 699
+    GetPopulation(): 776
     GetLocation():   42338
   Town 16
     IsValidTown():   true
     GetName():       Kennville
-    GetPopulation(): 659
+    GetPopulation(): 717
     GetLocation():   17345
   Town 17
     IsValidTown():   true
     GetName():       Quartfingfield
-    GetPopulation(): 185
+    GetPopulation(): 170
     GetLocation():   24252
   Town 18
     IsValidTown():   true
@@ -1596,7 +1589,7 @@
   Town 19
     IsValidTown():   true
     GetName():       Mendingston
-    GetPopulation(): 221
+    GetPopulation(): 226
     GetLocation():   6511
   Town 20
     IsValidTown():   true
@@ -1606,22 +1599,22 @@
   Town 21
     IsValidTown():   true
     GetName():       Franinghead
-    GetPopulation(): 598
+    GetPopulation(): 780
     GetLocation():   9634
   Town 22
     IsValidTown():   true
     GetName():       Naborough
-    GetPopulation(): 174
+    GetPopulation(): 191
     GetLocation():   51891
   Town 23
     IsValidTown():   true
     GetName():       Lardborough
-    GetPopulation(): 657
+    GetPopulation(): 669
     GetLocation():   59622
   Town 24
     IsValidTown():   true
     GetName():       Little Fruford
-    GetPopulation(): 624
+    GetPopulation(): 636
     GetLocation():   19596
   Town 25
     IsValidTown():   true
@@ -1631,12 +1624,12 @@
   Town 26
     IsValidTown():   true
     GetName():       Bedburg
-    GetPopulation(): 336
+    GetPopulation(): 349
     GetLocation():   39505
   Town 27
     IsValidTown():   true
     GetName():       Fudinghattan
-    GetPopulation(): 382
+    GetPopulation(): 412
     GetLocation():   45525
   Town 28
     IsValidTown():   false
@@ -1753,17 +1746,17 @@
   KeepAboveValue(500): done
   Count():             11
   Population ListDump:
-    12 => 766
+    12 => 853
+    21 => 780
+    7 => 777
+    15 => 776
+    0 => 754
+    16 => 717
     10 => 702
-    15 => 699
-    16 => 659
-    23 => 657
-    7 => 652
-    24 => 624
-    21 => 598
-    6 => 566
+    23 => 669
+    24 => 636
+    6 => 579
     25 => 548
-    0 => 538
 
 --Vehicle--
   Engine -1
@@ -2530,20 +2523,20 @@
   BuildVehicle():       0
   IsValidVehicle(11):   false
   --Transaction--
-    GetCosts():         5945
+    GetCosts():         5985
     Execute():          true
   IsValidVehicle(11):   true
   CloneVehicle():       12
   --Accounting--
-    GetCosts():         11890
-    Should be:          11890
+    GetCosts():         11970
+    Should be:          11970
     ResetCosts():       (null : 0x00000000)
   SellVehicle(12):      true
   StartStopVehicle():   true
   SendVehicleToDepot(): true
   --Accounting--
-    GetCosts():         -5945
-    Should be:          -5945
+    GetCosts():         -5985
+    Should be:          -5985
   GetName():            Road Vehicle 1
   SetName():            true
   GetName():            MyVehicleName
@@ -2552,10 +2545,10 @@
     GetLocation():       33417
     GetEngineType():     153
     GetUnitNumber():     1
-    GetAge():            0
+    GetAge():            1
     GetMaxAge():         5490
-    GetAgeLeft():        5490
-    GetProfitThisYear(): 0
+    GetAgeLeft():        5489
+    GetProfitThisYear(): -1
     GetProfitLastYear(): 0
     GetVehicleType():    1
   BuildVehicle():       13
@@ -2582,18 +2575,18 @@
     13 => 1
     11 => 1
   Age ListDump:
-    15 => 1
-    13 => 1
     12 => 1
     11 => 1
+    15 => 0
+    13 => 0
   MaxAge ListDump:
     15 => 10980
     13 => 10980
     12 => 5490
     11 => 5490
   AgeLeft ListDump:
-    15 => 10979
-    13 => 10979
+    15 => 10980
+    13 => 10980
     12 => 5489
     11 => 5489
   ProfitThisYear ListDump:
--- a/bin/ai/regression/run.sh	Sun Sep 23 07:37:38 2007 +0000
+++ b/bin/ai/regression/run.sh	Sat Oct 06 22:30:24 2007 +0000
@@ -10,7 +10,7 @@
 params=""
 gdb=""
 if [ "$1" != "-r" ]; then
-	params="-snull -mnull -vnull:ticks=2000"
+	params="-snull -mnull -vnull:ticks=10000"
 fi
 if [ "$1" = "-g" ]; then
 	gdb="gdb --ex run --args "
--- a/config.lib	Sun Sep 23 07:37:38 2007 +0000
+++ b/config.lib	Sat Oct 06 22:30:24 2007 +0000
@@ -702,6 +702,9 @@
 		elif [ -d "$ROOT_DIR/.git" ] && [ -n "`git help`" ]; then
 			revision=""
 			log 1 "checking revision... git detection"
+		elif [ -d "$ROOT_DIR/.hg" ] && [ -n "`hg help`" ]; then
+			revision=""
+			log 1 "checking revision... hg detection"
 		else
 			revision=""
 			log 1 "checking revision... no detection"
@@ -2143,6 +2146,8 @@
 	echo "  --enable-translator            enable extra output for translators"
 	echo "  --enable-universal             enable universal builds (OSX ONLY)"
 	echo "  --enable-osx-g5                enables optimalizations for G5 (OSX ONLY)"
+	echo "  --disable-unicode              disable unicode support to build win9x"
+	echo "                                 version (Win32 ONLY)"
 	echo "  --disable-network              disable network support"
 	echo "  --disable-assert               disable asserts (continue on errors)"
 	echo "  --disable-strip                disable any possible stripping"
--- a/docs/landscape.html	Sun Sep 23 07:37:38 2007 +0000
+++ b/docs/landscape.html	Sat Oct 06 22:30:24 2007 +0000
@@ -973,7 +973,7 @@
       </ul>
      </li>
      <li>m2: index into the array of industries</li>
-     <li>m5: type:<br>
+     <li>m5: type (plus m6 bit 2):<br>
       <small>(note: this is not the same as the industry type, which is stored in the array of industries)</small>
 
       <table>
@@ -1272,9 +1272,17 @@
          </table>
         </td>
        </tr>
+       <tr>
+        <td nowrap valign=top><tt>AF</tt>..<tt>1FF</tt>&nbsp; </td>
+        <td align=left>NewGRF industries industry</td>
+       </tr>
       </table>
      </li>
      <li>m6 bits 1..0 : <a href="#tropic_zone">Tropic zone definition</a></li>
+     <li>m3: animation state</li>
+     <li>m4: animation loop</li>
+     <li>m6 bits 3..5: random triggers (NewGRF)</li>
+     <li>m7: random bits (NewGRF)</li>
     </ul>
    </td>
   </tr>
--- a/docs/landscape_grid.html	Sun Sep 23 07:37:38 2007 +0000
+++ b/docs/landscape_grid.html	Sat Oct 06 22:30:24 2007 +0000
@@ -200,41 +200,17 @@
       <td class="bits"><span class="free">OOOO OOOO</span></td>
     </tr>
     <tr>
-      <td rowspan=3>8</td>
+      <td>8</td>
       <td class="caption">industry</td>
       <td class="bits">XXXX XXXX</td>
       <td class="bits"><span class="abuse">X</span><span class="free">OO</span><span class="abuse">X
         XXXX</span></td>
       <td class="bits">XXXX XXXX XXXX XXXX</td>
-      <td class="bits"><span class="free">OOOO OOOO</span></td>
-      <td class="bits"><span class="free">OOOO OOOO</span></td>
-      <td class="bits">XXXX XXXX</td>
-      <td class="bits"><span class="free">OOOO OO</span>XX</td>
-      <td class="bits"><span class="free">OOOO OOOO</span></td>
-    </tr>
-    <tr>
-      <td>bubble/sugar/toffee,<BR>
-        gold/copper/coal,<BR>
-        oil wells, power station</td>
-      <td class="bits">-inherit-</td>
-      <td class="bits"><span class="abuse">X</span><span class="free">OOO OOOO</span></td>
-      <td class="bits">-inherit-</td>
-      <td class="bits">XXXX XXXX</td>
-      <td class="bits"><span class="free">OOOO OOOO</span></td>
-      <td class="bits">-inherit-</td>
-      <td class="bits">-inherit-</td>
-      <td class="bits"><span class="free">OOOO OOOO</span></td>
-    </tr>
-    <tr>
-      <td>toy factory</td>
-      <td class="bits">-inherit-</td>
-      <td class="bits"><span class="abuse">X</span><span class="free">OOO OOOO</span></td>
-      <td class="bits">-inherit-</td>
       <td class="bits">XXXX XXXX</td>
       <td class="bits">XXXX XXXX</td>
-      <td class="bits">-inherit-</td>
-      <td class="bits">-inherit-</td>
-      <td class="bits"><span class="free">OOOO OOOO</span></td>
+      <td class="bits">XXXX XXXX</td>
+      <td class="bits"><span class="free">OO</span>XX XXXX</td>
+      <td class="bits">XXXX XXXX</td>
     </tr>
     <tr>
       <td rowspan=2>9</td>
--- a/projects/openttd.vcproj	Sun Sep 23 07:37:38 2007 +0000
+++ b/projects/openttd.vcproj	Sat Oct 06 22:30:24 2007 +0000
@@ -327,6 +327,9 @@
 				RelativePath=".\..\src\rev.cpp">
 			</File>
 			<File
+				RelativePath=".\..\src\road.cpp">
+			</File>
+			<File
 				RelativePath=".\..\src\saveload.cpp">
 			</File>
 			<File
@@ -1333,10 +1336,10 @@
 				RelativePath=".\..\src\blitter\32bpp_base.hpp">
 			</File>
 			<File
-				RelativePath=".\..\src\blitter\32bpp_optimized.hpp">
+				RelativePath=".\..\src\blitter\32bpp_optimized.cpp">
 			</File>
 			<File
-				RelativePath=".\..\src\blitter\32bpp_optimized.cpp">
+				RelativePath=".\..\src\blitter\32bpp_optimized.hpp">
 			</File>
 			<File
 				RelativePath=".\..\src\blitter\32bpp_simple.cpp">
--- a/projects/openttd_vs80.vcproj	Sun Sep 23 07:37:38 2007 +0000
+++ b/projects/openttd_vs80.vcproj	Sat Oct 06 22:30:24 2007 +0000
@@ -668,6 +668,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\road.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\saveload.cpp"
 				>
 			</File>
@@ -1996,14 +2000,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\blitter\32bpp_optimized.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\blitter\32bpp_optimized.hpp"
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\blitter\32bpp_optimized.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\blitter\32bpp_simple.cpp"
 				>
 			</File>
--- a/readme.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/readme.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -10,7 +10,7 @@
 2.0) Contacting
  * 2.1 Reporting Bugs
 3.0) Supported Platforms
-4.0) Running OpenTTD
+4.0) Installing and running OpenTTD
 5.0) OpenTTD features
 6.0) Configuration File
 7.0) Compiling
@@ -80,12 +80,19 @@
   Windows              - Win32 GDI (faster) or SDL
 
 
-4.0) Running OpenTTD:
----- ----------------
+4.0) Installing and running OpenTTD:
+---- -------------------------------
+
+Installing OpenTTD is fairly straightforward. Either you have downloaded an
+archive which you have to extract to a directory where you want OpenTTD to
+be installed, or you have downloaded an installer, which will automatically
+extract OpenTTD in the given directory.
 
 Before you run OpenTTD, you need to put the game's datafiles into the data/
 subdirectory. You need the following files from the original version
-of TTD as OpenTTD makes use of the original TTD artwork.
+of TTD as OpenTTD makes use of the original TTD artwork. The Windows
+installer optionally can copy these files from your Transport Tycoon Deluxe
+CD-ROM.
 
 List of the required files:
 sample.cat
@@ -103,9 +110,6 @@
 If you want music you need to copy the gm/ folder from Windows TTD into your
 OpenTTD folder, not your data folder.
 
-You can change the data path (which contains savegames as well) in
-Makefile.config by setting DATA_DIR_PREFIX and USE_HOMEDIR.
-
 
 5.0) OpenTTD features:
 ---- -----------------
@@ -119,7 +123,6 @@
 Several important non-standard controls:
 
 * Use Ctrl to place semaphore signals
-* Ctrl-D toggles double mode in the Windows version
 * Ingame console. More information at
   http://wiki.openttd.org/index.php/Console
 
@@ -210,10 +213,6 @@
     * Please contact the development team before beginning the translation
       process! This avoids double work, as someone else may have already
       started translating to the same language.
-    * Translators must use the character set ISO 8859-15.
-      Otherwise, some characters will not display correctly in the game.
-    * Currently it is not possible to translate into character sets other than
-      Latin.
 
 8.2) Translation:
 ---- -------------------
@@ -306,7 +305,6 @@
 Thanks to:
   Josef Drexler                  - For his great work on TTDPatch.
   Marcin Grzegorczyk             - For his TTDPatch work and documentation of TTD internals and graphics (signals and track foundations)
-  Matthijs Kooijman (blathijs)   - For his many patches, suggestions and major work on maprewrite
   Petr Baudis (pasky)            - Many patches, newgrf support, etc.
   Simon Sasburg (HackyKid)       - For the many bugfixes he has blessed us with (and future PBS)
   Stefan Meißner (sign_de)       - For his work on the console
--- a/source.list	Sun Sep 23 07:37:38 2007 +0000
+++ b/source.list	Sat Oct 06 22:30:24 2007 +0000
@@ -58,6 +58,7 @@
 queue.cpp
 rail.cpp
 rev.cpp
+road.cpp
 saveload.cpp
 screenshot.cpp
 #if SDL
@@ -418,8 +419,8 @@
 blitter/32bpp_anim.hpp
 blitter/32bpp_base.cpp
 blitter/32bpp_base.hpp
+blitter/32bpp_optimized.cpp
 blitter/32bpp_optimized.hpp
-blitter/32bpp_optimized.cpp
 blitter/32bpp_simple.cpp
 blitter/32bpp_simple.hpp
 blitter/8bpp_base.cpp
--- a/src/aircraft.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/aircraft.h	Sat Oct 06 22:30:24 2007 +0000
@@ -33,20 +33,29 @@
 	return v->subtype <= AIR_AIRCRAFT;
 }
 
-/** Checks if an aircraft is buildable at the tile in question
+/** Checks if an aircraft can use the station in question
  * @param engine The engine to test
- * @param tile The tile where the hangar is
- * @return true if the aircraft can be build
+ * @param st The station
+ * @return true if the aircraft can use the station
  */
-static inline bool IsAircraftBuildableAtStation(EngineID engine, TileIndex tile)
+static inline bool CanAircraftUseStation(EngineID engine, const Station *st)
 {
-	const Station *st = GetStationByTile(tile);
 	const AirportFTAClass *apc = st->Airport();
 	const AircraftVehicleInfo *avi = AircraftVehInfo(engine);
 
 	return (apc->flags & (avi->subtype & AIR_CTOL ? AirportFTAClass::AIRPLANES : AirportFTAClass::HELICOPTERS)) != 0;
 }
 
+/** Checks if an aircraft can use the station at the tile in question
+ * @param engine The engine to test
+ * @param tile The tile where the station is
+ * @return true if the aircraft can use the station
+ */
+static inline bool CanAircraftUseStation(EngineID engine, TileIndex tile)
+{
+	return CanAircraftUseStation(engine, GetStationByTile(tile));
+}
+
 /**
  * Calculates cargo capacity based on an aircraft's passenger
  * and mail capacities.
--- a/src/aircraft_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/aircraft_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -283,7 +283,7 @@
 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
 	/* Prevent building aircraft types at places which can't handle them */
-	if (!IsAircraftBuildableAtStation(p1, tile)) return CMD_ERROR;
+	if (!CanAircraftUseStation(p1, tile)) return CMD_ERROR;
 
 	/* Allocate 2 or 3 vehicle structs, depending on type
 	 * vl[0] = aircraft, vl[1] = shadow, [vl[2] = rotor] */
@@ -365,7 +365,7 @@
 
 			v->cargo_type = cargo;
 
-			if (HASBIT(EngInfo(p1)->callbackmask, CBM_REFIT_CAPACITY)) {
+			if (HASBIT(EngInfo(p1)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
 				callback = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
 			}
 
@@ -646,7 +646,7 @@
 
 	/* Check the refit capacity callback */
 	uint16 callback = CALLBACK_FAILED;
-	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
 		/* Back up the existing cargo type */
 		CargoID temp_cid = v->cargo_type;
 		byte temp_subtype = v->cargo_subtype;
--- a/src/aircraft_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/aircraft_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -95,7 +95,7 @@
 
 		if (v->tile == _backup_orders_tile) {
 			_backup_orders_tile = 0;
-			RestoreVehicleOrders(v, _backup_orders_data);
+			RestoreVehicleOrders(v);
 		}
 		ShowVehicleViewWindow(v);
 	}
--- a/src/articulated_vehicles.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/articulated_vehicles.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -17,7 +17,7 @@
 
 uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
 {
-	if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0;
+	if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return 0;
 
 	Vehicle *v = NULL;;
 	if (!purchase_window) {
@@ -41,7 +41,7 @@
 	const Vehicle *v = vl[0];
 	Vehicle *u = vl[0];
 
-	if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return;
+	if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return;
 
 	for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, v->engine_type, v);
--- a/src/autoslope.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/autoslope.h	Sat Oct 06 22:30:24 2007 +0000
@@ -36,7 +36,9 @@
  */
 static inline bool AutoslopeEnabled()
 {
-	return (_patches.autoslope && IsValidPlayer(_current_player));
+	return (_patches.autoslope &&
+	        (IsValidPlayer(_current_player) ||
+	         (_current_player == OWNER_NONE && _game_mode == GM_EDITOR)   #define	));
 }
 
 #endif /* AUTOSLOPE_H */
--- a/src/blitter/32bpp_base.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/blitter/32bpp_base.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -56,7 +56,7 @@
 		stepx = 1;
 	}
 
-	if (x > 0 && y > 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
+	if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
 	if (dx > dy) {
 		frac = dy - (dx / 2);
 		while (x != x2) {
@@ -66,7 +66,7 @@
 			}
 			x += stepx;
 			frac += dy;
-			if (x > 0 && y > 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
+			if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
 		}
 	} else {
 		frac = dx - (dy / 2);
@@ -77,7 +77,7 @@
 			}
 			y += stepy;
 			frac += dx;
-			if (x > 0 && y > 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
+			if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
 		}
 	}
 }
--- a/src/blitter/8bpp_base.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/blitter/8bpp_base.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -60,7 +60,7 @@
 		stepx = 1;
 	}
 
-	if (x > 0 && y > 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
+	if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
 	if (dx > dy) {
 		frac = dy - (dx / 2);
 		while (x != x2) {
@@ -70,7 +70,7 @@
 			}
 			x += stepx;
 			frac += dy;
-			if (x > 0 && y > 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
+			if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
 		}
 	} else {
 		frac = dx - (dy / 2);
@@ -81,7 +81,7 @@
 			}
 			y += stepy;
 			frac += dx;
-			if (x > 0 && y > 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
+			if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, color);
 		}
 	}
 }
--- a/src/build_vehicle_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/build_vehicle_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -765,7 +765,7 @@
 	for (eid = AIRCRAFT_ENGINES_INDEX; eid < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; eid++) {
 		if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_player)) continue;
 		/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
-		if (w->window_number > VEH_END && !IsAircraftBuildableAtStation(eid, w->window_number)) continue;
+		if (w->window_number > VEH_END && !CanAircraftUseStation(eid, w->window_number)) continue;
 
 		EngList_Add(&bv->eng_list, eid);
 		if (eid == bv->sel_engine) sel_id = eid;
--- a/src/clear_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/clear_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -314,7 +314,7 @@
 				return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE);
 			}
 			/* Check tiletype-specific things, and add extra-cost */
-			CommandCost cost = _tile_type_procs[GetTileType(tile)]->terraform_tile_proc(tile, flags, z_min * TILE_HEIGHT, (Slope) tileh);
+			CommandCost cost = _tile_type_procs[GetTileType(tile)]->terraform_tile_proc(tile, flags | DC_AUTO, z_min * TILE_HEIGHT, (Slope) tileh);
 			if (CmdFailed(cost)) {
 				_terraform_err_tile = tile;
 				return cost;
--- a/src/depot_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/depot_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -928,7 +928,7 @@
 
 						if (is_engine) {
 							_backup_orders_tile = v->tile;
-							BackupVehicleOrders(v, _backup_orders_data);
+							BackupVehicleOrders(v);
 						}
 
 						switch (v->type) {
--- a/src/direction.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/direction.h	Sat Oct 06 22:30:24 2007 +0000
@@ -165,6 +165,9 @@
 	DIAGDIRDIFF_90LEFT  = 3         ///< 90 degrees left
 };
 
+/** Allow incrementing of DiagDirDiff variables */
+DECLARE_POSTFIX_INCREMENT(DiagDirDiff);
+
 /**
  * Applies a difference on a DiagDirection
  *
--- a/src/economy.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/economy.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -972,7 +972,6 @@
 static void FindSubsidyCargoRoute(FoundRoute *fr)
 {
 	Industry *i;
-	const IndustrySpec *ind;
 	int trans, total;
 	CargoID cargo;
 
@@ -980,15 +979,14 @@
 
 	fr->from = i = GetRandomIndustry();
 	if (i == NULL) return;
-	ind = GetIndustrySpec(i->type);
 
 	/* Randomize cargo type */
-	if (HASBIT(Random(), 0) && ind->produced_cargo[1] != CT_INVALID) {
-		cargo = ind->produced_cargo[1];
+	if (HASBIT(Random(), 0) && i->produced_cargo[1] != CT_INVALID) {
+		cargo = i->produced_cargo[1];
 		trans = i->last_month_pct_transported[1];
 		total = i->last_month_production[1];
 	} else {
-		cargo = ind->produced_cargo[0];
+		cargo = i->produced_cargo[0];
 		trans = i->last_month_pct_transported[0];
 		total = i->last_month_production[0];
 	}
@@ -1015,17 +1013,12 @@
 	} else {
 		/* The destination is an industry */
 		Industry *i2 = GetRandomIndustry();
-		if (i2 == NULL) {
-			return;
-		}
-
-		ind = GetIndustrySpec(i2->type);
 
 		/* The industry must accept the cargo */
-		if (i == i2 ||
-				(cargo != ind->accepts_cargo[0] &&
-				cargo != ind->accepts_cargo[1] &&
-				cargo != ind->accepts_cargo[2])) {
+		if (i2 == NULL || i == i2 ||
+				(cargo != i2->accepts_cargo[0] &&
+				cargo != i2->accepts_cargo[1] &&
+				cargo != i2->accepts_cargo[2])) {
 			return;
 		}
 		fr->distance = DistanceManhattan(i->xy, i2->xy);
@@ -1226,12 +1219,12 @@
 		indspec = GetIndustrySpec(ind->type);
 		uint i;
 
-		for (i = 0; i < lengthof(indspec->accepts_cargo); i++) {
-			if (cargo_type == indspec->accepts_cargo[i]) break;
+		for (i = 0; i < lengthof(ind->accepts_cargo); i++) {
+			if (cargo_type == ind->accepts_cargo[i]) break;
 		}
 
 		/* Check if matching cargo has been found */
-		if (i == lengthof(indspec->accepts_cargo)) continue;
+		if (i == lengthof(ind->accepts_cargo)) continue;
 
 		if (HASBIT(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) {
 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO, 0, GetReverseCargoTranslation(cargo_type, indspec->grf_prop.grffile), ind, ind->type, ind->xy);
@@ -1529,7 +1522,7 @@
 		if (v->cargo_cap == 0) continue;
 
 		byte load_amount = EngInfo(v->engine_type)->load_amount;
-		if (_patches.gradual_loading && HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_LOAD_AMOUNT)) {
+		if (_patches.gradual_loading && HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) {
 			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;
 		}
--- a/src/fileio.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/fileio.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -296,6 +296,10 @@
 		snprintf(buf, lengthof(buf), "%s%s%s", _searchpaths[sp], _subdirs[subdir], filename);
 	}
 
+#if defined(WIN32)
+	if (mode[0] == 'r' && GetFileAttributes(OTTD2FS(buf)) == INVALID_FILE_ATTRIBUTES) return NULL;
+#endif
+
 	f = fopen(buf, mode);
 #if !defined(WIN32)
 	if (f == NULL) {
--- a/src/functions.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/functions.h	Sat Oct 06 22:30:24 2007 +0000
@@ -132,7 +132,6 @@
 
 bool ScrollMainWindowToTile(TileIndex tile, bool instant = false);
 bool ScrollMainWindowTo(int x, int y, bool instant = false);
-void DrawSprite(SpriteID img, SpriteID pal, int x, int y);
 bool EnsureNoVehicle(TileIndex tile);
 bool EnsureNoVehicleOnGround(TileIndex tile);
 
--- a/src/gfx.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/gfx.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -43,7 +43,7 @@
 Colour _cur_palette[256];
 byte _stringwidth_table[FS_END][224];
 
-static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode);
+static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL);
 
 FontSize _cur_fontsize;
 static FontSize _last_fontsize;
@@ -139,6 +139,71 @@
 	blitter->DrawLine(dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, color);
 }
 
+void GfxDrawLineUnscaled(int x, int y, int x2, int y2, int color)
+{
+	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
+	DrawPixelInfo *dpi = _cur_dpi;
+
+	x -= dpi->left;
+	x2 -= dpi->left;
+	y -= dpi->top;
+	y2 -= dpi->top;
+
+	/* Check clipping */
+	if (x < 0 && x2 < 0) return;
+	if (y < 0 && y2 < 0) return;
+	if (x > dpi->width  && x2 > dpi->width)  return;
+	if (y > dpi->height && y2 > dpi->height) return;
+
+	blitter->DrawLine(dpi->dst_ptr, UnScaleByZoom(x, dpi->zoom), UnScaleByZoom(y, dpi->zoom),
+			UnScaleByZoom(x2, dpi->zoom), UnScaleByZoom(y2, dpi->zoom),
+			UnScaleByZoom(dpi->width, dpi->zoom), UnScaleByZoom(dpi->height, dpi->zoom), color);
+}
+
+/**
+ * Draws the projection of a parallelepiped.
+ * This can be used to draw boxes in world coordinates.
+ *
+ * @param x   Screen X-coordinate of top front corner.
+ * @param y   Screen Y-coordinate of top front corner.
+ * @param dx1 Screen X-length of first edge.
+ * @param dy1 Screen Y-length of first edge.
+ * @param dx2 Screen X-length of second edge.
+ * @param dy2 Screen Y-length of second edge.
+ * @param dx3 Screen X-length of third edge.
+ * @param dy3 Screen Y-length of third edge.
+ */
+void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3)
+{
+	/*           ....
+	 *         ..    ....
+	 *       ..          ....
+	 *     ..                ^
+	 *   <--__(dx1,dy1)    /(dx2,dy2)
+	 *   :    --__       /   :
+	 *   :        --__ /     :
+	 *   :            *(x,y) :
+	 *   :            |      :
+	 *   :            |     ..
+	 *    ....        |(dx3,dy3)
+	 *        ....    | ..
+	 *            ....V.
+	 */
+
+	static const byte color = 255;
+
+	GfxDrawLineUnscaled(x, y, x + dx1, y + dy1, color);
+	GfxDrawLineUnscaled(x, y, x + dx2, y + dy2, color);
+	GfxDrawLineUnscaled(x, y, x + dx3, y + dy3, color);
+
+	GfxDrawLineUnscaled(x + dx1, y + dy1, x + dx1 + dx2, y + dy1 + dy2, color);
+	GfxDrawLineUnscaled(x + dx1, y + dy1, x + dx1 + dx3, y + dy1 + dy3, color);
+	GfxDrawLineUnscaled(x + dx2, y + dy2, x + dx2 + dx1, y + dy2 + dy1, color);
+	GfxDrawLineUnscaled(x + dx2, y + dy2, x + dx2 + dx3, y + dy2 + dy3, color);
+	GfxDrawLineUnscaled(x + dx3, y + dy3, x + dx3 + dx1, y + dy3 + dy1, color);
+	GfxDrawLineUnscaled(x + dx3, y + dy3, x + dx3 + dx2, y + dy3 + dy2, color);
+}
+
 
 /** Truncate a given string to a maximum width if neccessary.
  * If the string is truncated, add three dots ('...') to show this.
@@ -587,24 +652,33 @@
 	return DoDrawString(buffer, x, y, color);
 }
 
-void DrawSprite(SpriteID img, SpriteID pal, int x, int y)
+void DrawSprite(SpriteID img, SpriteID pal, int x, int y, const SubSprite *sub)
 {
 	if (HASBIT(img, PALETTE_MODIFIER_TRANSPARENT)) {
 		_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
-		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT);
+		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT, sub);
 	} else if (pal != PAL_NONE) {
 		_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
-		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP);
+		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP, sub);
 	} else {
-		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL);
+		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL, sub);
 	}
 }
 
-static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
+static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub)
 {
 	const DrawPixelInfo *dpi = _cur_dpi;
 	Blitter::BlitterParams bp;
 
+	/* Amount of pixels to clip from the source sprite */
+	int clip_left   = (sub != NULL ? max(0,                   -sprite->x_offs + sub->left       ) : 0);
+	int clip_top    = (sub != NULL ? max(0,                   -sprite->y_offs + sub->top        ) : 0);
+	int clip_right  = (sub != NULL ? max(0, sprite->width  - (-sprite->x_offs + sub->right  + 1)) : 0);
+	int clip_bottom = (sub != NULL ? max(0, sprite->height - (-sprite->y_offs + sub->bottom + 1)) : 0);
+
+	if (clip_left + clip_right >= sprite->width) return;
+	if (clip_top + clip_bottom >= sprite->height) return;
+
 	/* Move to the correct offset */
 	x += sprite->x_offs;
 	y += sprite->y_offs;
@@ -613,12 +687,16 @@
 	bp.sprite = sprite->data;
 	bp.sprite_width = sprite->width;
 	bp.sprite_height = sprite->height;
-	bp.width = UnScaleByZoom(sprite->width, dpi->zoom);
-	bp.height = UnScaleByZoom(sprite->height, dpi->zoom);
+	bp.width = UnScaleByZoom(sprite->width - clip_left - clip_right, dpi->zoom);
+	bp.height = UnScaleByZoom(sprite->height - clip_top - clip_bottom, dpi->zoom);
 	bp.top = 0;
 	bp.left = 0;
-	bp.skip_left = 0;
-	bp.skip_top = 0;
+	bp.skip_left = UnScaleByZoom(clip_left, dpi->zoom);
+	bp.skip_top = UnScaleByZoom(clip_top, dpi->zoom);
+
+	x += ScaleByZoom(bp.skip_left, dpi->zoom);
+	y += ScaleByZoom(bp.skip_top, dpi->zoom);
+
 	bp.dst = dpi->dst_ptr;
 	bp.pitch = dpi->pitch;
 	bp.remap = _color_remap_ptr;
--- a/src/gfx.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/gfx.h	Sat Oct 06 22:30:24 2007 +0000
@@ -242,6 +242,16 @@
 void RedrawScreenRect(int left, int top, int right, int bottom);
 void GfxScroll(int left, int top, int width, int height, int xo, int yo);
 
+/**
+ * Used to only draw a part of the sprite.
+ * Draw the subsprite in the rect (sprite_x_offset + left, sprite_y_offset + top) to (sprite_x_offset + right, sprite_y_offset + bottom).
+ * Both corners are included in the drawing area.
+ */
+struct SubSprite {
+	int left, top, right, bottom;
+};
+
+void DrawSprite(SpriteID img, SpriteID pal, int x, int y, const SubSprite *sub = NULL);
 
 /* XXX doesn't really belong here, but the only
  * consumers always use it in conjunction with DoDrawString() */
@@ -268,6 +278,7 @@
 
 void GfxFillRect(int left, int top, int right, int bottom, int color);
 void GfxDrawLine(int left, int top, int right, int bottom, int color);
+void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
 
 BoundingRect GetStringBoundingBox(const char *str);
 uint32 FormatStringLinebreaks(char *str, int maxw);
--- a/src/industry.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/industry.h	Sat Oct 06 22:30:24 2007 +0000
@@ -9,17 +9,17 @@
 #include "helpers.hpp"
 #include "newgrf_storage.h"
 
-typedef byte IndustryGfx;
+typedef uint16 IndustryGfx;
 typedef uint8 IndustryType;
 
 enum {
 	INVALID_INDUSTRY       = 0xFFFF,
 	NEW_INDUSTRYOFFSET     = 37,                         ///< original number of industries
-	NUM_INDUSTRYTYPES      = 37,                         ///< total number of industries, new and old
+	NUM_INDUSTRYTYPES      = 64,                         ///< total number of industries, new and old
 	INDUSTRYTILE_NOANIM    = 0xFF,                       ///< flag to mark industry tiles as having no animation
 	NEW_INDUSTRYTILEOFFSET = 175,                        ///< original number of tiles
 	INVALID_INDUSTRYTYPE   = NUM_INDUSTRYTYPES,          ///< one above amount is considered invalid
-	NUM_INDUSTRYTILES      = NEW_INDUSTRYTILEOFFSET,     ///< total number of industry tiles, new and old
+	NUM_INDUSTRYTILES      = 512,                        ///< total number of industry tiles, new and old
 	INVALID_INDUSTRYTILE   = NUM_INDUSTRYTILES,          ///< one above amount is considered invalid
 	INDUSTRY_COMPLETED     = 3,                          ///< final stage of industry construction.
 };
@@ -105,10 +105,12 @@
 	byte width;
 	byte height;
 	const Town *town;                   ///< Nearest town
+	CargoID produced_cargo[2];          ///< 2 production cargo slots
 	uint16 produced_cargo_waiting[2];   ///< amount of cargo produced per cargo
 	uint16 incoming_cargo_waiting[3];   ///< incoming cargo waiting to be processed
 	byte production_rate[2];            ///< production rate for each cargo
 	byte prod_level;                    ///< general production level
+	CargoID accepts_cargo[3];           ///< 3 input cargo slots
 	uint16 this_month_production[2];    ///< stats of this month's production per cargo
 	uint16 this_month_transported[2];   ///< stats of this month's transport per cargo
 	byte last_month_pct_transported[2]; ///< percentage transported per cargo in the last full month
--- a/src/industry_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/industry_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -65,11 +65,16 @@
 
 	/* once performed, enable only the current climate industries */
 	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
-		_industry_specs[i].enabled = HASBIT(_origin_industry_specs[i].climate_availability, _opt.landscape);
+		_industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
+				HASBIT(_origin_industry_specs[i].climate_availability, _opt.landscape);
 	}
 
 	memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
 	memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
+
+	/* Reset any overrides that have been set. */
+	_industile_mngr.ResetOverride();
+	_industry_mngr.ResetOverride();
 }
 
 void ResetIndustryCreationProbility(IndustryType type)
@@ -357,7 +362,8 @@
 
 	for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) {
 		CargoID a = accepts_cargo[i];
-		if (a != CT_INVALID) ac[a] = acceptance[i];
+		/* Only set the value once. */
+		if (a != CT_INVALID && ac[a] == 0) ac[a] = acceptance[i];
 	}
 }
 
@@ -385,6 +391,7 @@
 	 */
 	if ((_current_player != OWNER_WATER && _game_mode != GM_EDITOR &&
 			!_cheats.magic_bulldozer.value) ||
+			((flags & DC_AUTO) != 0) ||
 			(_current_player == OWNER_WATER && (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER))) {
 		SetDParam(0, indspec->name);
 		return_cmd_error(STR_4800_IN_THE_WAY);
@@ -409,7 +416,7 @@
 
 		i->this_month_production[0] += cw;
 
-		am = MoveGoodsToStation(i->xy, i->width, i->height, indspec->produced_cargo[0], cw);
+		am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[0], cw);
 		i->this_month_transported[0] += am;
 		if (am != 0 && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
 			uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
@@ -431,7 +438,7 @@
 
 		i->this_month_production[1] += cw;
 
-		am = MoveGoodsToStation(i->xy, i->width, i->height, indspec->produced_cargo[1], cw);
+		am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[1], cw);
 		i->this_month_transported[1] += am;
 	}
 }
@@ -819,7 +826,7 @@
 
 static void GetProducedCargo_Industry(TileIndex tile, CargoID *b)
 {
-	const IndustrySpec *i = GetIndustrySpec(GetIndustryByTile(tile)->type);
+	const Industry *i = GetIndustryByTile(tile);
 
 	b[0] = i->produced_cargo[0];
 	b[1] = i->produced_cargo[1];
@@ -1176,9 +1183,27 @@
 	return t;
 }
 
-static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, int type, bool *custom_shape_check = NULL)
+bool IsSlopeRefused(Slope current, Slope refused)
+{
+	if (current != SLOPE_FLAT) {
+		if (refused & SLOPE_STEEP) return true;
+
+		Slope t = ComplementSlope(current);
+
+		if (refused & 1 && (t & SLOPE_NW)) return false;
+		if (refused & 2 && (t & SLOPE_NE)) return false;
+		if (refused & 4 && (t & SLOPE_SW)) return false;
+		if (refused & 8 && (t & SLOPE_SE)) return false;
+	}
+
+	return false;
+}
+
+static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, bool *custom_shape_check = NULL)
 {
 	_error_message = STR_0239_SITE_UNSUITABLE;
+	bool refused_slope = false;
+	bool custom_shape = false;
 
 	do {
 		IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx);
@@ -1203,8 +1228,8 @@
 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
 
 			if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
-				if (custom_shape_check != NULL) *custom_shape_check = true;
-				if (!PerformIndustryTileSlopeCheck(cur_tile, its, type, gfx)) return false;
+				custom_shape = true;
+				if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false;
 			} else {
 				if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
 					/* As soon as the tile is not water, bail out.
@@ -1219,24 +1244,7 @@
 					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 = its->slopes_refused;
-
-							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;
-						}
-					}
+					refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
 				}
 			}
 
@@ -1252,7 +1260,12 @@
 		}
 	} while ((++it)->ti.x != -0x80);
 
-	return true;
+	if (custom_shape_check != NULL) *custom_shape_check = custom_shape;
+
+	/* It is almost impossible to have a fully flat land in TG, so what we
+	 *  do is that we check if we can make the land flat later on. See
+	 *  CheckIfCanLevelIndustryPlatform(). */
+	return !refused_slope || (_patches.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape);
 }
 
 static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t)
@@ -1318,6 +1331,7 @@
 
 	/* Finds dimensions of largest variant of this industry */
 	do {
+		if (it->gfx == 0xFF) continue;  //  FF been a marquer for a check on clear water, skip it
 		if (it->ti.x > max_x) max_x = it->ti.x;
 		if (it->ti.y > max_y) max_y = it->ti.y;
 	} while ((++it)->ti.x != MKEND);
@@ -1334,15 +1348,26 @@
 	/* 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;
 
+	/* _current_player is OWNER_NONE for randomly generated industries and in editor, or the player who funded or prospected the industry.
+	 * Perform terraforming as OWNER_TOWN to disable autoslope. */
+	PlayerID old_player = _current_player;
+	_current_player = OWNER_TOWN;
+
 	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;
+			if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
+				_current_player = old_player;
+				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, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND))) return false;
+			if (CmdFailed(DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND))) {
+				_current_player = old_player;
+				return false;
+			}
 		}
 	} END_TILE_LOOP(tile_walk, size_x, size_y, cur_tile)
 
@@ -1360,6 +1385,7 @@
 		} END_TILE_LOOP(tile_walk, size_x, size_y, cur_tile)
 	}
 
+	_current_player = old_player;
 	return true;
 }
 
@@ -1377,7 +1403,7 @@
 		/* 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] == GetIndustrySpec(i->type)->accepts_cargo[0] && (
+				indspec->accepts_cargo[0] == i->accepts_cargo[0] && (
 					_game_mode != GM_EDITOR ||
 					!_patches.same_industry_close ||
 					!_patches.multiple_industry_per_town
@@ -1400,17 +1426,23 @@
 {
 	const IndustrySpec *indspec = GetIndustrySpec(type);
 	uint32 r;
-	int j;
+	uint j;
 
 	i->xy = tile;
 	i->width = i->height = 0;
 	i->type = type;
 	IncIndustryTypeCount(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) {
+	/* don't use smooth economy for industries using production callbacks */
+	if (_patches.smooth_economy  && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL))) {
 		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);
 	}
@@ -1439,6 +1471,30 @@
 	i->last_month_production[0] = i->production_rate[0] * 8;
 	i->last_month_production[1] = i->production_rate[1] * 8;
 	i->founder = _current_player;
+
+	if (HASBIT(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) {
+		uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
+		if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4);
+	}
+
+	if (HASBIT(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) {
+		for (j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
+		for (j = 0; j < lengthof(i->accepts_cargo); j++) {
+			uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
+			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
+			i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
+		}
+	}
+
+	if (HASBIT(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) {
+		for (j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
+		for (j = 0; j < lengthof(i->produced_cargo); j++) {
+			uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
+			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
+			i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
+		}
+	}
+
 	i->construction_date = _date;
 	i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
 			(_generating_world ? ICT_MAP_GENERATION : ICT_NORMAL_GAMEPLAY);
@@ -1496,7 +1552,7 @@
 	const IndustryTileTable *it = indspec->table[itspec_index];
 	bool custom_shape_check = false;
 
-	if (!CheckIfIndustryTilesAreFree(tile, it, type, &custom_shape_check)) return NULL;
+	if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL;
 
 	if (HASBIT(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
@@ -1537,7 +1593,6 @@
 {
 	int num;
 	const IndustryTileTable * const *itt;
-	const IndustryTileTable *it;
 	const IndustrySpec *indspec;
 
 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
@@ -1581,7 +1636,7 @@
 
 		do {
 			if (--num < 0) return_cmd_error(STR_0239_SITE_UNSUITABLE);
-		} while (!CheckIfIndustryTilesAreFree(tile, it = itt[num], p1));
+		} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
 
 		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
 	}
@@ -1699,10 +1754,9 @@
 {
 	byte pct;
 	bool refresh = false;
-	const IndustrySpec *indsp = GetIndustrySpec(i->type);
 
-	for (byte j = 0; j < lengthof(indsp->produced_cargo); j++) {
-		if (indsp->produced_cargo[j] != CT_INVALID) {
+	for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
+		if (i->produced_cargo[j] != CT_INVALID) {
 			pct = 0;
 			if (i->this_month_production[j] != 0) {
 				i->last_prod_year = _cur_year;
@@ -1809,6 +1863,8 @@
 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
 	bool standard = true;
 	bool suppress_message = false;
+	/* don't use smooth economy for industries using production callbacks */
+	bool smooth_economy = _patches.smooth_economy && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL));
 	byte div = 0;
 	byte mul = 0;
 
@@ -1835,7 +1891,7 @@
 		}
 	}
 
-	if (standard && monthly != _patches.smooth_economy) return;
+	if (standard && monthly != smooth_economy) return;
 
 	if (standard && indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
 
@@ -1843,9 +1899,9 @@
 		/* decrease or increase */
 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
 
-		if (_patches.smooth_economy) {
+		if (smooth_economy) {
 			closeit = true;
-			for (byte j = 0; j < 2 && indspec->produced_cargo[j] != CT_INVALID; j++){
+			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
 				uint32 r = Random();
 				int old_prod, new_prod, percent;
 				int mag;
@@ -1874,7 +1930,7 @@
 				mag = abs(percent);
 				if (mag >= 10) {
 					SetDParam(2, mag);
-					SetDParam(0, GetCargo(indspec->produced_cargo[j])->name);
+					SetDParam(0, GetCargo(i->produced_cargo[j])->name);
 					SetDParam(1, i->index);
 					AddNewsItem(
 						percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
@@ -1896,7 +1952,7 @@
 	}
 
 	if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) {
-		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, _patches.smooth_economy ? 180 : 2)) {
+		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, smooth_economy ? 180 : 2)) {
 			closeit = true;
 		}
 	}
@@ -2018,7 +2074,7 @@
 			}
 		}
 	}
-	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); // funny magic bulldozer
+	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 }
 
 extern const TileTypeProcs _tile_type_industry_procs = {
@@ -2045,10 +2101,12 @@
 	    SLE_VAR(Industry, height,                     SLE_UINT8),
 	    SLE_REF(Industry, town,                       REF_TOWN),
 	SLE_CONDNULL( 2, 2, 60),       ///< used to be industry's produced_cargo
+	SLE_CONDARR(Industry, produced_cargo,             SLE_UINT8,  2,              78, SL_MAX_VERSION),
 	SLE_CONDARR(Industry, incoming_cargo_waiting,     SLE_UINT16, 3,              70, SL_MAX_VERSION),
 	    SLE_ARR(Industry, produced_cargo_waiting,     SLE_UINT16, 2),
 	    SLE_ARR(Industry, production_rate,            SLE_UINT8,  2),
 	SLE_CONDNULL( 3, 2, 60),       ///< used to be industry's accepts_cargo
+	SLE_CONDARR(Industry, accepts_cargo,              SLE_UINT8,  3,              78, SL_MAX_VERSION),
 	    SLE_VAR(Industry, prod_level,                 SLE_UINT8),
 	    SLE_ARR(Industry, this_month_production,      SLE_UINT16, 2),
 	    SLE_ARR(Industry, this_month_transported,     SLE_UINT16, 2),
--- a/src/industry_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/industry_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -118,7 +118,7 @@
 				indsp = GetIndustrySpec(ind);
 				if (indsp->enabled && (!indsp->IsRawIndustry() || _game_mode == GM_EDITOR)) {
 					_fund_gui.index[_fund_gui.count] = ind;
-					_fund_gui.enabled[_fund_gui.count] = CheckIfCallBackAllowsAvailability(ind, IACT_USERCREATION);
+					_fund_gui.enabled[_fund_gui.count] = (_game_mode == GM_EDITOR) || CheckIfCallBackAllowsAvailability(ind, IACT_USERCREATION);
 					_fund_gui.count++;
 				}
 			}
@@ -128,7 +128,7 @@
 					indsp = GetIndustrySpec(ind);
 					if (indsp->enabled && indsp->IsRawIndustry()) {
 						_fund_gui.index[_fund_gui.count] = ind;
-						_fund_gui.enabled[_fund_gui.count] = CheckIfCallBackAllowsAvailability(ind, IACT_USERCREATION);
+						_fund_gui.enabled[_fund_gui.count] = (_game_mode == GM_EDITOR) || CheckIfCallBackAllowsAvailability(ind, IACT_USERCREATION);
 						_fund_gui.count++;
 					}
 				}
@@ -390,9 +390,8 @@
 
 static inline bool IsProductionAlterable(const Industry *i)
 {
-	const IndustrySpec *ind = GetIndustrySpec(i->type);
 	return ((_game_mode == GM_EDITOR || _cheats.setup_prod.value) &&
-			(ind->accepts_cargo[0] == CT_INVALID || ind->accepts_cargo[0] == CT_VALUABLES));
+			(i->accepts_cargo[0] == CT_INVALID || i->accepts_cargo[0] == CT_VALUABLES));
 }
 
 /** Information to store about the industry window */
@@ -410,21 +409,22 @@
 	switch (e->event) {
 	case WE_CREATE: {
 		/* Count the number of lines that we need to resize the GUI with */
-		const IndustrySpec *ind = GetIndustrySpec(GetIndustry(w->window_number)->type);
+		const Industry *i = GetIndustry(w->window_number);
+		const IndustrySpec *ind = GetIndustrySpec(i->type);
 		int lines = -3;
 
 		if (HASBIT(ind->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(ind->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) {
-			for (uint j = 0; j < 3 && ind->accepts_cargo[j] != CT_INVALID; j++) {
+			for (uint j = 0; j < lengthof(i->accepts_cargo) && i->accepts_cargo[j] != CT_INVALID; j++) {
 				if (j == 0) lines++;
 				lines++;
 			}
-		} else if (ind->accepts_cargo[0] != CT_INVALID) {
+		} else if (i->accepts_cargo[0] != CT_INVALID) {
 			lines++;
 		}
 
-		for (uint j = 0; j < 2 && ind->produced_cargo[j] != CT_INVALID; j++) {
+		for (uint j = 0; j < lengthof(i->produced_cargo) && i->produced_cargo[j] != CT_INVALID; j++) {
 			if (j == 0) {
-				if (ind->accepts_cargo[0] != CT_INVALID) lines++;
+				if (i->accepts_cargo[0] != CT_INVALID) lines++;
 				lines++;
 			}
 			lines++;
@@ -448,26 +448,26 @@
 		DrawWindowWidgets(w);
 
 		if (HASBIT(ind->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(ind->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) {
-			for (uint j = 0; j < 3 && ind->accepts_cargo[j] != CT_INVALID; j++) {
+			for (uint j = 0; j < lengthof(i->accepts_cargo) && i->accepts_cargo[j] != CT_INVALID; j++) {
 				if (j == 0) {
 					DrawString(2, y, STR_INDUSTRY_WINDOW_WAITING_FOR_PROCESSING, 0);
 					y += 10;
 				}
-				SetDParam(0, ind->accepts_cargo[j]);
+				SetDParam(0, i->accepts_cargo[j]);
 				SetDParam(1, i->incoming_cargo_waiting[j]);
 				DrawString(4, y, STR_INDUSTRY_WINDOW_WAITING_STOCKPILE_CARGO, 0);
 				y += 10;
 			}
-		} else if (ind->accepts_cargo[0] != CT_INVALID) {
+		} else if (i->accepts_cargo[0] != CT_INVALID) {
 			StringID str;
 
-			SetDParam(0, GetCargo(ind->accepts_cargo[0])->name);
+			SetDParam(0, GetCargo(i->accepts_cargo[0])->name);
 			str = STR_4827_REQUIRES;
-			if (ind->accepts_cargo[1] != CT_INVALID) {
-				SetDParam(1, GetCargo(ind->accepts_cargo[1])->name);
+			if (i->accepts_cargo[1] != CT_INVALID) {
+				SetDParam(1, GetCargo(i->accepts_cargo[1])->name);
 				str = STR_4828_REQUIRES;
-				if (ind->accepts_cargo[2] != CT_INVALID) {
-					SetDParam(2, GetCargo(ind->accepts_cargo[2])->name);
+				if (i->accepts_cargo[2] != CT_INVALID) {
+					SetDParam(2, GetCargo(i->accepts_cargo[2])->name);
 					str = STR_4829_REQUIRES;
 				}
 			}
@@ -475,15 +475,15 @@
 			y += 10;
 		}
 
-		for (uint j = 0; j < 2 && ind->produced_cargo[j] != CT_INVALID; j++) {
+		for (uint j = 0; j < lengthof(i->produced_cargo) && i->produced_cargo[j] != CT_INVALID; j++) {
 			if (j == 0) {
-				if (ind->accepts_cargo[0] != CT_INVALID) y += 10;
+				if (i->accepts_cargo[0] != CT_INVALID) y += 10;
 				DrawString(2, y, STR_482A_PRODUCTION_LAST_MONTH, 0);
 				y += 10;
 				WP(w, indview_d).production_offset_y = y;
 			}
 
-			SetDParam(0, ind->produced_cargo[j]);
+			SetDParam(0, i->produced_cargo[j]);
 			SetDParam(1, i->last_month_production[j]);
 
 			SetDParam(2, i->last_month_pct_transported[j] * 100 >> 8);
@@ -527,8 +527,7 @@
 			if (!IsProductionAlterable(i)) return;
 			x = e->we.click.pt.x;
 			line = (e->we.click.pt.y - WP(w, indview_d).production_offset_y) / 10;
-			if (e->we.click.pt.y >= WP(w, indview_d).production_offset_y && IS_INT_INSIDE(line, 0, 2) &&
-					GetIndustrySpec(i->type)->produced_cargo[line] != CT_INVALID) {
+			if (e->we.click.pt.y >= WP(w, indview_d).production_offset_y && 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) {
@@ -579,10 +578,8 @@
 
 static void UpdateIndustryProduction(Industry *i)
 {
-	const IndustrySpec *ind = GetIndustrySpec(i->type);
-
-	for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
-		if (ind->produced_cargo[j] != CT_INVALID) {
+	for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
+		if (i->produced_cargo[j] != CT_INVALID) {
 			i->last_month_production[j] = 8 * i->production_rate[j];
 		}
 	}
@@ -655,8 +652,6 @@
 {
 	const Industry* i = *(const Industry**)a;
 	const Industry* j = *(const Industry**)b;
-	const IndustrySpec *ind_i = GetIndustrySpec(i->type);
-	const IndustrySpec *ind_j = GetIndustrySpec(j->type);
 	int r;
 
 	switch (_industry_sort_order >> 1) {
@@ -670,10 +665,10 @@
 			break;
 
 		case 2: /* Sort by Production */
-			if (ind_i->produced_cargo[0] == CT_INVALID) {
-				r = (ind_j->produced_cargo[0] == CT_INVALID ? 0 : -1);
+			if (i->produced_cargo[0] == CT_INVALID) {
+				r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1);
 			} else {
-				if (ind_j->produced_cargo[0] == CT_INVALID) {
+				if (j->produced_cargo[0] == CT_INVALID) {
 					r = 1;
 				} else {
 					r =
@@ -684,23 +679,23 @@
 			break;
 
 		case 3: /* Sort by transported fraction */
-			if (ind_i->produced_cargo[0] == CT_INVALID) {
-				r = (ind_j->produced_cargo[0] == CT_INVALID ? 0 : -1);
+			if (i->produced_cargo[0] == CT_INVALID) {
+				r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1);
 			} else {
-				if (ind_j->produced_cargo[0] == CT_INVALID) {
+				if (j->produced_cargo[0] == CT_INVALID) {
 					r = 1;
 				} else {
 					int pi;
 					int pj;
 
 					pi = i->last_month_pct_transported[0] * 100 >> 8;
-					if (ind_i->produced_cargo[1] != CT_INVALID) {
+					if (i->produced_cargo[1] != CT_INVALID) {
 						int p = i->last_month_pct_transported[1] * 100 >> 8;
 						if (p < pi) pi = p;
 					}
 
 					pj = j->last_month_pct_transported[0] * 100 >> 8;
-					if (ind_j->produced_cargo[1] != CT_INVALID) {
+					if (j->produced_cargo[1] != CT_INVALID) {
 						int p = j->last_month_pct_transported[1] * 100 >> 8;
 						if (p < pj) pj = p;
 					}
@@ -781,15 +776,14 @@
 
 		while (p < _num_industry_sort) {
 			const Industry* i = _industry_sort[p];
-			const IndustrySpec *ind = GetIndustrySpec(i->type);
 
 			SetDParam(0, i->index);
-			if (ind->produced_cargo[0] != CT_INVALID) {
-				SetDParam(1, ind->produced_cargo[0]);
+			if (i->produced_cargo[0] != CT_INVALID) {
+				SetDParam(1, i->produced_cargo[0]);
 				SetDParam(2, i->last_month_production[0]);
 
-				if (ind->produced_cargo[1] != CT_INVALID) {
-					SetDParam(3, ind->produced_cargo[1]);
+				if (i->produced_cargo[1] != CT_INVALID) {
+					SetDParam(3, i->produced_cargo[1]);
 					SetDParam(4, i->last_month_production[1]);
 					SetDParam(5, i->last_month_pct_transported[0] * 100 >> 8);
 					SetDParam(6, i->last_month_pct_transported[1] * 100 >> 8);
--- a/src/industry_map.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/industry_map.h	Sat Oct 06 22:30:24 2007 +0000
@@ -109,7 +109,7 @@
 static inline byte GetIndustryConstructionStage(TileIndex tile)
 {
 	assert(IsTileType(tile, MP_INDUSTRY));
-	return GB(_m[tile].m1, 0, 2);
+	return IsIndustryCompleted(tile) ? (byte)INDUSTRY_COMPLETED : GB(_m[tile].m1, 0, 2);
 }
 
 /**
@@ -124,6 +124,12 @@
 	SB(_m[tile].m1, 0, 2, value);
 }
 
+static inline IndustryGfx GetCleanIndustryGfx(TileIndex t)
+{
+	assert(IsTileType(t, MP_INDUSTRY));
+	return _m[t].m5 | (GB(_m[t].m6, 2, 1) << 8);
+}
+
 /**
  * Get the industry graphics ID for the given industry tile
  * @param t the tile to get the gfx for
@@ -133,7 +139,7 @@
 static inline IndustryGfx GetIndustryGfx(TileIndex t)
 {
 	assert(IsTileType(t, MP_INDUSTRY));
-	return GetTranslatedIndustryTileID(_m[t].m5 | (GB(_m[t].m6, 2, 1) << 8));
+	return GetTranslatedIndustryTileID(GetCleanIndustryGfx(t));
 }
 
 /**
@@ -145,7 +151,8 @@
 static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
 {
 	assert(IsTileType(t, MP_INDUSTRY));
-	_m[t].m5 = gfx;
+	_m[t].m5 = GB(gfx, 0, 8);
+	SB(_m[t].m6, 2, 1, GB(gfx, 8, 1));
 }
 
 /**
@@ -253,12 +260,24 @@
  * @param tile TileIndex of the tile to query
  * @pre IsTileType(tile, MP_INDUSTRY)
  * @return requested bits
- * @todo implement the storage in map array
  */
 static inline byte GetIndustryRandomBits(TileIndex tile)
 {
 	assert(IsTileType(tile, MP_INDUSTRY));
-	return 0;
+	return _me[tile].m7;
+}
+
+/**
+ * Set the random bits for this tile.
+ * Used for grf callbacks
+ * @param tile TileIndex of the tile to query
+ * @param bits the random bits
+ * @pre IsTileType(tile, MP_INDUSTRY)
+ */
+static inline byte GetIndustryRandomBits(TileIndex tile, byte bits)
+{
+	assert(IsTileType(tile, MP_INDUSTRY));
+	_me[tile].m7 = bits;
 }
 
 /**
@@ -267,12 +286,11 @@
  * @param tile TileIndex of the tile to query
  * @pre IsTileType(tile, MP_INDUSTRY)
  * @return requested triggers
- * @todo implement the storage in map array
  */
 static inline byte GetIndustryTriggers(TileIndex tile)
 {
 	assert(IsTileType(tile, MP_INDUSTRY));
-	return 0;
+	return GB(_m[tile].m6, 3, 3);
 }
 
 
@@ -280,12 +298,13 @@
  * Set the activated triggers bits for this industry tile
  * Used for grf callbacks
  * @param tile TileIndex of the tile to query
+ * @param triggers the triggers to set
  * @pre IsTileType(tile, MP_INDUSTRY)
- * @todo implement the storage in map array
  */
 static inline void SetIndustryTriggers(TileIndex tile, byte triggers)
 {
 	assert(IsTileType(tile, MP_INDUSTRY));
+	SB(_m[tile].m6, 3, 3, triggers);
 }
 
 #endif /* INDUSTRY_MAP_H */
--- a/src/landscape.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/landscape.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -77,23 +77,23 @@
 	}
 
 	uint dz = IsSteepSlope(*s) ? TILE_HEIGHT : 0;
-	byte highest_corner = GetHighestSlopeCorner(*s);
+	Corner highest_corner = GetHighestSlopeCorner(*s);
 
 	switch (f) {
 		case FOUNDATION_INCLINED_X:
-			*s = (highest_corner <= 1 ? SLOPE_SW : SLOPE_NE);
+			*s = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? SLOPE_SW : SLOPE_NE);
 			break;
 
 		case FOUNDATION_INCLINED_Y:
-			*s = (((highest_corner == 1) || (highest_corner == 2)) ? SLOPE_SE : SLOPE_NW);
+			*s = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? SLOPE_SE : SLOPE_NW);
 			break;
 
 		case FOUNDATION_STEEP_LOWER:
-			*s = (Slope) (1 << highest_corner);
+			*s = SlopeWithOneCornerRaised(highest_corner);
 			break;
 
 		case FOUNDATION_STEEP_HIGHER:
-			*s = (Slope) (*s & ~SLOPE_STEEP);
+			*s = SlopeWithThreeCornersRaised(OppositeCorner(highest_corner));
 			break;
 
 		default: NOT_REACHED();
@@ -271,7 +271,7 @@
 			lower_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
 		);
 
-		byte highest_corner = GetHighestSlopeCorner(ti->tileh);
+		Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
 		ti->z += ApplyFoundationToSlope(f, &ti->tileh);
 
 		if (IsInclinedFoundation(f)) {
--- a/src/lang/american.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/american.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 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}
--- a/src/lang/brazilian_portuguese.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/brazilian_portuguese.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2021,7 +2021,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Necessário demolir o túnel primeiro
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Necessário demolir a ponte primeiro
 STR_5008_CANNOT_START_AND_END_ON                                :{WHITE}Impossí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 necessitam 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}
--- a/src/lang/bulgarian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/bulgarian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2008,7 +2008,6 @@
 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}
--- a/src/lang/catalan.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/catalan.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 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}
--- a/src/lang/croatian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/croatian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2019,7 +2019,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Najprije moraš srušiti tunel
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Najprije moraš 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 ravnini
 STR_500B_SITE_UNSUITABLE_FOR_TUNNEL                             :{WHITE}Neprikladan teren za ulaz u tunel
 STR_500D                                                        :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
--- a/src/lang/czech.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/czech.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2075,7 +2075,6 @@
 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}
--- a/src/lang/danish.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/danish.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 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}
--- a/src/lang/dutch.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/dutch.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 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}
--- a/src/lang/english.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/english.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1047,6 +1047,8 @@
 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_ALLOW_EXCLUSIVE                              :{LTBLUE}Allow buying exclusive transport rights: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_ALLOW_GIVE_MONEY                             :{LTBLUE}Allow sending money to other companies: {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}
@@ -1187,6 +1189,7 @@
 STR_CONFIG_PATCHES_LARGER_TOWNS                                 :{LTBLUE}Proportion of towns that will become cities: {ORANGE}1 in {STRING1}
 STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED                        :{LTBLUE}Proportion of towns that will become cities: {ORANGE}None
 STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER                         :{LTBLUE}Initial city size multiplier: {ORANGE}{STRING1}
+STR_CONFIG_MODIFIED_ROAD_REBUILD                                :{LTBLUE}Remove absurd road-elements during the road construction
 
 STR_CONFIG_PATCHES_GUI                                          :{BLACK}Interface
 STR_CONFIG_PATCHES_CONSTRUCTION                                 :{BLACK}Construction
@@ -2017,7 +2020,8 @@
 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_BRIDGEHEADS_NOT_SAME_HEIGHT                                 :{WHITE}Bridge heads not at the same level
+STR_BRIDGE_TOO_LOW_FOR_TERRAIN                                  :{WHITE}Bridge is too low for the terrain
 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}
--- a/src/lang/esperanto.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/esperanto.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1910,7 +1910,6 @@
 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}
--- a/src/lang/estonian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/estonian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2117,7 +2117,6 @@
 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}
--- a/src/lang/finnish.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/finnish.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2016,7 +2016,6 @@
 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}
--- a/src/lang/french.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/french.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2018,7 +2018,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Vous devez d'abord démolir le tunnel
 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}
--- a/src/lang/galician.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/galician.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1856,7 +1856,6 @@
 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}
--- a/src/lang/german.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/german.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 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}Unter der Brücke ist ebenes Land oder Wasser erforderlich
 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}
--- a/src/lang/hungarian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/hungarian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2120,7 +2120,6 @@
 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}
--- a/src/lang/icelandic.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/icelandic.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1877,7 +1877,6 @@
 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}
--- a/src/lang/italian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/italian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2019,7 +2019,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Bisogna demolire il tunnel prima
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Bisogna demolire il ponte prima
 STR_5008_CANNOT_START_AND_END_ON                                :{WHITE}Impossibile partire e finire nello stesso punto
-STR_5009_LEVEL_LAND_OR_WATER_REQUIRED                           :{WHITE}Sotto un ponte è richiesto terreno livellato 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}
--- a/src/lang/japanese.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/japanese.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2016,7 +2016,6 @@
 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}
--- a/src/lang/korean.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/korean.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2011,7 +2011,6 @@
 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}
--- a/src/lang/lithuanian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/lithuanian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1907,7 +1907,6 @@
 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 įvaziavimui į tunelį
 STR_500D                                                        :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
--- a/src/lang/norwegian_bokmal.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/norwegian_bokmal.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1931,7 +1931,6 @@
 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}
--- a/src/lang/norwegian_nynorsk.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/norwegian_nynorsk.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Må rive tunnel først
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Må rive bru først
 STR_5008_CANNOT_START_AND_END_ON                                :{WHITE}Kan ikkje starte og slutte på same felt
-STR_5009_LEVEL_LAND_OR_WATER_REQUIRED                           :{WHITE}Flatt land eller vatn trengst under brua
 STR_500A_START_AND_END_MUST_BE_IN                               :{WHITE}Start og slutt må vere på linje
 STR_500B_SITE_UNSUITABLE_FOR_TUNNEL                             :{WHITE}Feltet er uhøveleg for tunnelinngang
 STR_500D                                                        :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
--- a/src/lang/piglatin.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/piglatin.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2016,7 +2016,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Ustmay emolishday unneltay irstfay
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Ustmay emolishday idgebray irstfay
 STR_5008_CANNOT_START_AND_END_ON                                :{WHITE}Annotcay artstay andway endway inway ethay amesay otspay
-STR_5009_LEVEL_LAND_OR_WATER_REQUIRED                           :{WHITE}Evellay andlay orway aterway equiredray underway idgebray
 STR_500A_START_AND_END_MUST_BE_IN                               :{WHITE}Artstay andway endway ustmay ebay inway inelay
 STR_500B_SITE_UNSUITABLE_FOR_TUNNEL                             :{WHITE}Itesay unsuitableway orfay unneltay entranceway
 STR_500D                                                        :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
--- a/src/lang/polish.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/polish.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2127,7 +2127,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Należy najpierw usunąć tunel
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Należy najpierw usunąć 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}
--- a/src/lang/portuguese.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/portuguese.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1999,7 +1999,6 @@
 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}
--- a/src/lang/romanian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/romanian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Mai întâi trebuie demolat tunelul
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Mai întâi trebuie demolat podul
 STR_5008_CANNOT_START_AND_END_ON                                :{WHITE}Cele două capete nu se pot situa în acelaşi loc
-STR_5009_LEVEL_LAND_OR_WATER_REQUIRED                           :{WHITE}Sub pod trebuie să existe teren plat sau apă
 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}
--- a/src/lang/russian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/russian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2018,7 +2018,6 @@
 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}
--- a/src/lang/simplified_chinese.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/simplified_chinese.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1900,7 +1900,6 @@
 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}
--- a/src/lang/slovak.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/slovak.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2081,7 +2081,6 @@
 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 potrebná voda alebo údolie
 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}
--- a/src/lang/slovenian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/slovenian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2097,7 +2097,6 @@
 STR_5006_MUST_DEMOLISH_TUNNEL_FIRST                             :{WHITE}Najprej moraš porušiti predor
 STR_5007_MUST_DEMOLISH_BRIDGE_FIRST                             :{WHITE}Najprej moraš 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 predor
 STR_500D                                                        :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
--- a/src/lang/spanish.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/spanish.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2018,7 +2018,6 @@
 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}
--- a/src/lang/swedish.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/swedish.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2016,7 +2016,6 @@
 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}
--- a/src/lang/traditional_chinese.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/traditional_chinese.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2017,7 +2017,6 @@
 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}
--- a/src/lang/turkish.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/turkish.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2012,7 +2012,6 @@
 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}
--- a/src/lang/ukrainian.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/ukrainian.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -2178,7 +2178,6 @@
 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}
--- a/src/lang/unfinished/afrikaans.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/unfinished/afrikaans.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1808,7 +1808,6 @@
 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 benooding onder brug
 STR_500A_START_AND_END_MUST_BE_IN                               :{WHITE}Begin en einde moet in lyn wees
 STR_500B_SITE_UNSUITABLE_FOR_TUNNEL                             :{WHITE}Plek ongeskik vir tonnel ingang
 STR_500D                                                        :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY}
--- a/src/lang/unfinished/greek.txt	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/lang/unfinished/greek.txt	Sat Oct 06 22:30:24 2007 +0000
@@ -1640,7 +1640,6 @@
 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}
--- a/src/macros.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/macros.h	Sat Oct 06 22:30:24 2007 +0000
@@ -341,6 +341,15 @@
 #define GENERAL_SPRITE_COLOR(color) ((color) + PALETTE_RECOLOR_START)
 #define PLAYER_SPRITE_COLOR(owner) (GENERAL_SPRITE_COLOR(_player_colors[owner]))
 
+/**
+ * Whether a sprite comes from the original graphics files or a new grf file
+ * (either supplied by OpenTTD or supplied by the user).
+ *
+ * @param sprite The sprite to check
+ * @return True if it is a new sprite, or false if it is original.
+ */
+#define IS_CUSTOM_SPRITE(sprite) ((sprite) >= SPR_SIGNALS_BASE)
+
 extern const byte _ffb_64[128];
 
 /**
--- a/src/main_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/main_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -59,11 +59,13 @@
 extern void GenerateIndustries();
 extern bool GenerateTowns();
 
+bool _draw_bounding_boxes = false;
+
 
 void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
 {
 #ifdef ENABLE_NETWORK
-	if (!success) return;
+	if (!success || !_patches.give_money) return;
 
 	char msg[20];
 	/* Inform the player of this action */
@@ -2208,6 +2210,13 @@
 			break;
 		}
 
+		if (e->we.keypress.keycode == ('B' | WKC_CTRL)) {
+			e->we.keypress.cont = false;
+			_draw_bounding_boxes = !_draw_bounding_boxes;
+			MarkWholeScreenDirty();
+			break;
+		}
+
 		if (_game_mode == GM_MENU) break;
 
 		switch (e->we.keypress.keycode) {
--- a/src/map.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/map.h	Sat Oct 06 22:30:24 2007 +0000
@@ -390,6 +390,18 @@
 }
 
 /**
+ * Adds a DiagDir to a tile.
+ *
+ * @param tile The current tile
+ * @param dir The direction in which we want to step
+ * @return the moved tile
+ */
+static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
+{
+	return TILE_ADD(tile, TileOffsByDiagDir(dir));
+}
+
+/**
  * A callback function type for searching tiles.
  *
  * @param tile The tile to test
--- a/src/misc.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/misc.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -41,7 +41,7 @@
 
 #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);
+		printf("Random [%d/%d] %s:%d\n",_frame_counter, (byte)_current_player, file, line);
 #endif
 
 	s = _random_seeds[0][0];
--- a/src/misc_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/misc_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -351,6 +351,8 @@
  */
 CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	if (!_patches.give_money) return CMD_ERROR;
+
 	const Player *p = GetPlayer(_current_player);
 	CommandCost amount(min((Money)p1, (Money)20000000LL));
 
--- a/src/music/win32_m.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/music/win32_m.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -142,7 +142,11 @@
 	}
 
 	if (NULL == (_midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL))) return "Failed to create event";
-	if (NULL == (_midi.thread = CreateThread(NULL, 8192, MidiThread, 0, 0, NULL))) return "Failed to create thread";
+
+	/* The lpThreadId parameter of CreateThread (the last parameter)
+	 * may NOT be NULL on Windows 95, 98 and ME. */
+	DWORD threadId;
+	if (NULL == (_midi.thread = CreateThread(NULL, 8192, MidiThread, 0, 0, &threadId))) return "Failed to create thread";
 
 	return NULL;
 }
--- a/src/network/network_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/network/network_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -1264,8 +1264,8 @@
 	_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)) {
+		/* We are no spectator and the player we want to give money to is no spectator and money gifts are allowed */
+		if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas) && _patches.give_money) {
 			GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(_clientlist_action[i]));
 			_clientlist_proc[i++] = &ClientList_GiveMoney;
 		}
--- a/src/newgrf.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -1206,9 +1206,6 @@
 	/* Allocate house specs if they haven't been allocated already. */
 	if (_cur_grffile->housespec == NULL) {
 		_cur_grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
-
-		/* Reset any overrides that have been set. */
-		_house_mngr.ResetOverride();
 	}
 
 	for (int i = 0; i < numinfo; i++) {
@@ -1702,8 +1699,6 @@
 
 static bool IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, byte **bufp, int len)
 {
-	if (!HASBIT(_ttdpatch_flags[3], 0x07)) return true;
-
 	byte *buf = *bufp;
 	bool ret = false;
 
@@ -1715,9 +1710,6 @@
 	/* Allocate industry tile specs if they haven't been allocated already. */
 	if (_cur_grffile->indtspec == NULL) {
 		_cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
-
-		/* Reset any overrides that have been set. */
-		_industile_mngr.ResetOverride();
 	}
 
 	for (int i = 0; i < numinfo; i++) {
@@ -1772,7 +1764,7 @@
 			case 0x0C: {
 				uint16 acctp = grf_load_word(&buf);
 				tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
-				tsp->acceptance[prop - 0x0A] = GetCargoTranslation(GB(acctp, 8, 8), _cur_grffile);
+				tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
 			} break;
 
 			case 0x0D: // Land shape flags
@@ -1811,8 +1803,6 @@
 
 static bool IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp, int len)
 {
-	if (!HASBIT(_ttdpatch_flags[3], 0x07)) return true;
-
 	byte *buf = *bufp;
 	bool ret = false;
 
@@ -1826,9 +1816,6 @@
 	/* Allocate industry specs if they haven't been allocated already. */
 	if (_cur_grffile->industryspec == NULL) {
 		_cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
-
-		/* Reset any overrides that have been set. */
-		_industry_mngr.ResetOverride();
 	}
 
 	for (int i = 0; i < numinfo; i++) {
@@ -1938,6 +1925,9 @@
 								size = k + 1;
 								copy_from = itt;
 							}
+						} else if (itt[k].gfx == 0xFF) {
+							itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
+							itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
 						}
 					}
 					tile_table[j] = CallocT<IndustryTileTable>(size);
@@ -2005,11 +1995,11 @@
 				break;
 
 			case 0x17: // Probability in random game
-				indsp->appear_ingame[_opt.landscape] = grf_load_byte(&buf);
+				indsp->appear_creation[_opt.landscape] = grf_load_byte(&buf);
 				break;
 
 			case 0x18: // Probability during gameplay
-				indsp->appear_creation[_opt.landscape] = grf_load_byte(&buf);
+				indsp->appear_ingame[_opt.landscape] = grf_load_byte(&buf);
 				break;
 
 			case 0x19: // Map color
@@ -2943,8 +2933,6 @@
 
 static void IndustryMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
 {
-	if (!HASBIT(_ttdpatch_flags[3], 0x07)) return;
-
 	byte *bp = &buf[4 + idcount + cidcount * 3];
 	uint16 groupid = grf_load_word(&bp);
 
@@ -2969,8 +2957,6 @@
 
 static void IndustrytileMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
 {
-	if (!HASBIT(_ttdpatch_flags[3], 0x07)) return;
-
 	byte *bp = &buf[4 + idcount + cidcount * 3];
 	uint16 groupid = grf_load_word(&bp);
 
@@ -3056,8 +3042,8 @@
 	grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
 			feature, idcount, cidcount, wagover);
 
-	if (_cur_grffile->spriteset_start == 0 || _cur_grffile->spritegroups == 0) {
-		grfmsg(1, "FeatureMapSpriteGroup: No sprite set to work on! Skipping");
+	if (_cur_grffile->spritegroups == 0) {
+		grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
 		return;
 	}
 
@@ -3393,8 +3379,8 @@
 		case 0x8B: { // TTDPatch version
 			uint major    = 2;
 			uint minor    = 6;
-			uint revision = 0; // special case: 2.0.1 is 2.0.10
-			uint build    = 1210;
+			uint revision = 1; // special case: 2.0.1 is 2.0.10
+			uint build    = 1382;
 			return (major << 24) | (minor << 20) | (revision << 16) | build;
 		}
 
@@ -4730,7 +4716,7 @@
 	                   |                                        (0 << 0x04)  // aichoosechance
 	                   |                                        (1 << 0x05)  // resolutionwidth
 	                   |                                        (1 << 0x06)  // resolutionheight
-	                   |                                        (0 << 0x07)  // newindustries
+	                   |                                        (1 << 0x07)  // newindustries
 	                   |         ((_patches.improved_load ? 1 : 0) << 0x08)  // fifoloading
 	                   |                                        (0 << 0x09)  // townroadbranchprob
 	                   |                                        (0 << 0x0A)  // tempsnowline
@@ -4971,7 +4957,7 @@
 
 	_loaded_newgrf_features.has_2CC           = false;
 	_loaded_newgrf_features.has_newhouses     = false;
-	_loaded_newgrf_features.has_newindustries = false,
+	_loaded_newgrf_features.has_newindustries = false;
 
 	_signal_base = 0;
 	_coast_base = 0;
@@ -5492,7 +5478,7 @@
 	/* Load newgrf sprites
 	 * in each loading stage, (try to) open each file specified in the config
 	 * and load information from it. */
-	for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
+	for (GrfLoadingStage stage = GLS_LABELSCAN; stage < GLS_ACTIVATION; stage++) {
 		uint slot = file_index;
 
 		_cur_stage = stage;
@@ -5505,13 +5491,17 @@
 			if (!FioCheckFileExists(c->filename)) error("NewGRF file is missing '%s'", c->filename);
 
 			if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
-			LoadNewGRFFile(c, slot++, stage);
+			LoadNewGRFFile(c, slot, stage);
 			if (stage == GLS_RESERVE) {
 				if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
-			} else if (stage == GLS_ACTIVATION) {
+				_cur_stage = GLS_ACTIVATION;
+				LoadNewGRFFile(c, slot++, GLS_ACTIVATION);
+				_cur_stage = stage;
 				ClearTemporaryNewGRFData();
 				BuildCargoTranslationMap();
 				DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
+			} else {
+				slot++;
 			}
 		}
 	}
--- a/src/newgrf_callbacks.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_callbacks.h	Sat Oct 06 22:30:24 2007 +0000
@@ -24,6 +24,8 @@
 	/** Set when calling a randomizing trigger (almost undocumented). */
 	CBID_RANDOM_TRIGGER                  = 0x01,
 
+	/* There are no callbacks 0x02 - 0x0F. */
+
 	/** 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,
@@ -69,7 +71,7 @@
 	CBID_TRAIN_ALLOW_WAGON_ATTACH        = 0x1D,
 
 	/** Called to determine the colour of a town building. */
-	CBID_BUILDING_COLOUR                 = 0x1E,
+	CBID_HOUSE_COLOUR                    = 0x1E,
 
 	/** Called to decide how much cargo a town building can accept. */
 	CBID_HOUSE_CARGO_ACCEPTANCE          = 0x1F,
@@ -168,6 +170,8 @@
 	/** Called to determine if the industry can still accept or refuse more cargo arrival */
 	CBID_INDUSTRY_REFUSE_CARGO           = 0x3D,
 
+	/* There are no callbacks 0x3E - 0x142. */
+
 	/** Called to determine whether a town building can be destroyed. */
 	CBID_HOUSE_DENY_DESTRUCTION          = 0x143,
 
@@ -182,6 +186,20 @@
 
 	/** Add an offset to the default sprite numbers to show another sprite. */
 	CBID_CANALS_SPRITE_OFFSET            = 0x147, // not implemented
+
+	/* There is no callback 0x148.*/
+
+	/** Callback done for each tile of a station to check the slope. */
+	CBID_STATION_LAND_SLOPE_CHECK        = 0x149, // not implemented
+
+	/** Called to determine the color of an industry. */
+	CBID_INDUSTRY_DECIDE_COLOUR          = 0x14A,
+
+	/** Customize the input cargo types of a newly build industry. */
+	CBID_INDUSTRY_INPUT_CARGO_TYPES      = 0x14B,
+
+	/** Customize the output cargo types of a newly build industry. */
+	CBID_INDUSTRY_OUTPUT_CARGO_TYPES     = 0x14C,
 };
 
 /**
@@ -189,64 +207,70 @@
  * 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
+	CBM_TRAIN_WAGON_POWER      = 0, ///< Powered wagons (trains only)
+	CBM_VEHICLE_LENGTH         = 1, ///< Vehicle length (trains and road vehicles)
+	CBM_VEHICLE_LOAD_AMOUNT    = 2, ///< Load amount
+	CBM_VEHICLE_REFIT_CAPACITY = 3, ///< Cargo capacity after refit
+	CBM_VEHICLE_ARTIC_ENGINE   = 4, ///< Add articulated engines (trains only)
+	CBM_VEHICLE_CARGO_SUFFIX   = 5, ///< Show suffix after cargo name
+	CBM_VEHICLE_COLOUR_REMAP   = 6, ///< Change colour mapping of vehicle
+	CBM_VEHICLE_SOUND_EFFECT   = 7, ///< Vehicle uses custom sound effects
 };
 
 /**
  * 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
+	CBM_STATION_AVAIL                = 0, ///< Availability of station in construction window
+	CBM_STATION_SPRITE_LAYOUT        = 1, ///< Use callback to select a sprite layout to use
+	CBM_STATION_ANIMATION_NEXT_FRAME = 2, ///< Use a custom next frame callback
+	CBM_STATION_ANIMATION_SPEED      = 3, ///< Customize the animation speed of the station
+	CBM_STATION_SLOPE_CHECK          = 4, ///< Check slope of new station tiles
 };
 
 /**
  * Callback masks for houses.
  */
 enum HouseCallbackMask {
-	CBM_HOUSE_ALLOW_CONSTRUCTION  = 0,
-	CBM_ANIMATION_NEXT_FRAME      = 1,
-	CBM_ANIMATION_START_STOP      = 2,
-	CBM_CONSTRUCTION_STATE_CHANGE = 3,
-	CBM_BUILDING_COLOUR           = 4,
-	CBM_CARGO_ACCEPTANCE          = 5,
-	CBM_ANIMATION_SPEED           = 6,
-	CBM_HOUSE_DESTRUCTION         = 7,
-	CBM_HOUSE_ACCEPT_CARGO        = 8,
-	CBM_HOUSE_PRODUCE_CARGO       = 9,
-	CBM_HOUSE_DENY_DESTRUCTION    = 10,
+	CBM_HOUSE_ALLOW_CONSTRUCTION        =  0,
+	CBM_HOUSE_ANIMATION_NEXT_FRAME      =  1,
+	CBM_HOUSE_ANIMATION_START_STOP      =  2,
+	CBM_HOUSE_CONSTRUCTION_STATE_CHANGE =  3,
+	CBM_HOUSE_COLOUR                    =  4,
+	CBM_HOUSE_CARGO_ACCEPTANCE          =  5,
+	CBM_HOUSE_ANIMATION_SPEED           =  6,
+	CBM_HOUSE_DESTRUCTION               =  7,
+	CBM_HOUSE_ACCEPT_CARGO              =  8,
+	CBM_HOUSE_PRODUCE_CARGO             =  9,
+	CBM_HOUSE_DENY_DESTRUCTION          = 10,
 };
 
 /**
  * Callback masks for cargos.
  */
 enum CargoCallbackMask {
-	CBM_CARGO_PROFIT_CALC         = 0,
-	CBM_CARGO_STATION_RATING_CALC = 1,
+	CBM_CARGO_PROFIT_CALC         = 0, ///< custom profit calculation
+	CBM_CARGO_STATION_RATING_CALC = 1, ///< custom station rating for this cargo type
 };
 
 /**
  * Callback masks for Industries
  */
 enum IndustryCallbackMask {
-	CBM_IND_AVAILABLE                 = 0,  ///< industry availability callback
-	CBM_IND_PRODUCTION_CARGO_ARRIVAL  = 1,  ///< call production callback when cargo arrives at the industry
-	CBM_IND_PRODUCTION_256_TICKS      = 2,  ///< call production callback every 256 ticks
-	CBM_IND_LOCATION                  = 3,  ///< check industry construction on given area
-	CBM_IND_PRODUCTION_CHANGE         = 4,  ///< controls random production change
-	CBM_IND_MONTHLYPROD_CHANGE        = 5,  ///< controls monthly random production change
-	CBM_IND_CARGO_SUFFIX              = 6,  ///< cargo sub-type display
-	CBM_IND_FUND_MORE_TEXT            = 7,  ///< additional text in fund window
-	CBM_IND_WINDOW_MORE_TEXT          = 8,  ///< additional text in industry window
-	CBM_IND_SPECIAL_EFFECT            = 9,  ///< control special effects
+	CBM_IND_AVAILABLE                 =  0, ///< industry availability callback
+	CBM_IND_PRODUCTION_CARGO_ARRIVAL  =  1, ///< call production callback when cargo arrives at the industry
+	CBM_IND_PRODUCTION_256_TICKS      =  2, ///< call production callback every 256 ticks
+	CBM_IND_LOCATION                  =  3, ///< check industry construction on given area
+	CBM_IND_PRODUCTION_CHANGE         =  4, ///< controls random production change
+	CBM_IND_MONTHLYPROD_CHANGE        =  5, ///< controls monthly random production change
+	CBM_IND_CARGO_SUFFIX              =  6, ///< cargo sub-type display
+	CBM_IND_FUND_MORE_TEXT            =  7, ///< additional text in fund window
+	CBM_IND_WINDOW_MORE_TEXT          =  8, ///< additional text in industry window
+	CBM_IND_SPECIAL_EFFECT            =  9, ///< control special effects
 	CBM_IND_REFUSE_CARGO              = 10, ///< option out of accepting cargo
+	CBM_IND_DECIDE_COLOUR             = 11, ///< give a custom colour to newly build industries
+	CBM_IND_INPUT_CARGO_TYPES         = 12, ///< customize the cargos the industry requires
+	CBM_IND_OUTPUT_CARGO_TYPES        = 13, ///< customize the cargos the industry produces
 };
 
 /**
--- a/src/newgrf_commons.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_commons.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -105,7 +105,7 @@
 	for (id = max_offset; id < max_new_entities; id++) {
 		map = &mapping_ID[id];
 
-		if (map->entity_id == 0 && map->grfid == 0) {
+		if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) {
 			map->entity_id     = grf_local_id;
 			map->grfid         = grfid;
 			map->substitute_id = substitute_id;
@@ -188,7 +188,7 @@
  * checking what is available
  * @param inds Industryspec that comes from the grf decoding process
  */
-void IndustryOverrideManager::SetEntitySpec(const IndustrySpec *inds)
+void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
 {
 	/* First step : We need to find if this industry is already specified in the savegame data */
 	IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
@@ -206,6 +206,7 @@
 			 * Or it is a simple substitute.
 			 * In both case, we need to find a free available slot */
 			ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
+			inds->grf_prop.override = invalid_ID;  // make sure it will not be detected as overriden
 		}
 	}
 
--- a/src/newgrf_commons.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_commons.h	Sat Oct 06 22:30:24 2007 +0000
@@ -33,6 +33,7 @@
 	uint16 max_new_entities; ///< what is the amount of entities, old and new summed
 
 	uint16 invalid_ID;       ///< ID used to dected invalid entities;
+	virtual bool CheckValidNewID(uint16 testid) { return true; }
 
 public:
 	EntityIDMapping *mapping_ID; ///< mapping of ids from grf files.  Public out of convenience
@@ -70,12 +71,14 @@
 			OverrideManagerBase(offset, maximum, invalid) {}
 
 	virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id);
-	void SetEntitySpec(const IndustrySpec *inds);
+	void SetEntitySpec(IndustrySpec *inds);
 };
 
 
 struct IndustryTileSpec;
 class IndustryTileOverrideManager : public OverrideManagerBase {
+protected:
+	virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; }
 public:
 	IndustryTileOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 			OverrideManagerBase(offset, maximum, invalid) {}
--- a/src/newgrf_config.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_config.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -371,6 +371,21 @@
 	return num;
 }
 
+/**
+ * Simple sorter for GRFS
+ * @param p1 the first GRFConfig *
+ * @param p2 the second GRFConfig *
+ * @return the same strcmp would return for the name of the NewGRF.
+ */
+static int CDECL GRFSorter(const void *p1, const void *p2)
+{
+	const GRFConfig *c1 = *(const GRFConfig **)p1;
+	const GRFConfig *c2 = *(const GRFConfig **)p2;
+
+	return strcmp(c1->name != NULL ? c1->name : c1->filename,
+		c2->name != NULL ? c2->name : c2->filename);
+}
+
 /* Scan for all NewGRFs */
 void ScanNewGRFFiles()
 {
@@ -389,7 +404,30 @@
 	FOR_ALL_TARS(tar) {
 		num += ScanTar(tar);
 	}
+
 	DEBUG(grf, 1, "Scan complete, found %d files", num);
+	if (num == 0 || _all_grfs == NULL) return;
+
+	/* Sort the linked list using quicksort.
+	 * For that we first have to make an array, the qsort and
+	 * then remake the linked list. */
+	GRFConfig **to_sort = MallocT<GRFConfig*>(num);
+	if (to_sort == NULL) return; // No memory, then don't sort
+
+	uint i = 0;
+	for (GRFConfig *p = _all_grfs; p != NULL; p = p->next, i++) {
+		to_sort[i] = p;
+	}
+	/* Number of files is not necessarily right */
+	num = i;
+
+	qsort(to_sort, num, sizeof(GRFConfig*), GRFSorter);
+
+	for (i = 1; i < num; i++) {
+		to_sort[i - 1]->next = to_sort[i];
+	}
+	to_sort[num - 1]->next = NULL;
+	_all_grfs = to_sort[0];
 }
 
 
--- a/src/newgrf_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -515,6 +515,7 @@
 		case WE_RESIZE:
 			w->vscroll.cap += e->we.sizing.diff.y / 14;
 			w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1;
+			SetupNewGRFWindow(w);
 			break;
 	}
 }
--- a/src/newgrf_house.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_house.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -308,19 +308,23 @@
 	SpriteID image = dts->ground_sprite;
 	SpriteID pal   = dts->ground_pal;
 
+	if (IS_CUSTOM_SPRITE(image)) image += stage;
+
 	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
 
 	foreach_draw_tile_seq(dtss, dts->seq) {
 		if (GB(dtss->image, 0, SPRITE_WIDTH) == 0) continue;
 
-		image = dtss->image + stage;
+		image = dtss->image;
 		pal   = dtss->pal;
 
+		if (IS_CUSTOM_SPRITE(image)) image += stage;
+
 		if ((HASBIT(image, SPRITE_MODIFIER_OPAQUE) || !HASBIT(_transparent_opt, TO_HOUSES)) && HASBIT(image, PALETTE_MODIFIER_COLOR)) {
 			if (pal == 0) {
 				const HouseSpec *hs = GetHouseSpecs(house_id);
-				if (HASBIT(hs->callback_mask, CBM_BUILDING_COLOUR)) {
-					uint16 callback = GetHouseCallback(CBID_BUILDING_COLOUR, 0, 0, house_id, GetTownByTile(ti->tile), ti->tile);
+				if (HASBIT(hs->callback_mask, CBM_HOUSE_COLOUR)) {
+					uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, GetTownByTile(ti->tile), ti->tile);
 					if (callback != CALLBACK_FAILED) {
 						/* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
 						pal = HASBIT(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
@@ -342,7 +346,7 @@
 				HASBIT(_transparent_opt, TO_HOUSES)
 			);
 		} else {
-			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
+			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y, HASBIT(_transparent_opt, TO_HOUSES));
 		}
 	}
 }
@@ -375,7 +379,7 @@
 	byte animation_speed = hs->animation_speed;
 	bool frame_set_by_callback = false;
 
-	if (HASBIT(hs->callback_mask, CBM_ANIMATION_SPEED)) {
+	if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_SPEED)) {
 		uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_SPEED, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback_res != CALLBACK_FAILED) animation_speed = clamp(callback_res & 0xFF, 2, 16);
 	}
@@ -389,7 +393,7 @@
 	byte frame      = GetHouseAnimationFrame(tile);
 	byte num_frames = GB(hs->animation_frames, 0, 7);
 
-	if (HASBIT(hs->callback_mask, CBM_ANIMATION_NEXT_FRAME)) {
+	if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_NEXT_FRAME)) {
 		uint32 param = (hs->extra_flags & CALLBACK_1A_RANDOM_BITS) ? Random() : 0;
 		uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_NEXT_FRAME, param, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 
@@ -468,7 +472,7 @@
 {
 	const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
 
-	if (HASBIT(hs->callback_mask, CBM_ANIMATION_START_STOP)) {
+	if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) {
 		uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random();
 		uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_START_STOP, param, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 
@@ -491,7 +495,7 @@
 	 * MarkTileDirtyByTile(tile);
 	 */
 
-	if (HASBIT(hs->callback_mask, CBM_ANIMATION_START_STOP)) {
+	if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) {
 		/* If this house is marked as having a synchronised callback, all the
 		 * tiles will have the callback called at once, rather than when the
 		 * tile loop reaches them. This should only be enabled for the northern
--- a/src/newgrf_industries.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_industries.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -78,47 +78,44 @@
 
 /** Make an analysis of a tile and check for its belonging to the same
  * industry, and/or the same grf file
- * @param new_tile TileIndex of the tile to query
- * @param old_tile TileIndex of the reference tile
- * @param i Industry to which old_tile belongs to
+ * @param tile TileIndex of the tile to query
+ * @param i Industry to which to compare the tile to
  * @return value encoded as per NFO specs */
-uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i)
+uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i)
 {
-	if (IsTileType(new_tile, MP_INDUSTRY)) {  // Is this an industry tile?
-
-		if (GetIndustryIndex(new_tile) == i->index) {  // Does it belong to the same industry?
-			IndustryGfx gfx = GetIndustryGfx(new_tile);
-			const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
-			const IndustryTileSpec *indold = GetIndustryTileSpec(GetIndustryGfx(old_tile));
+	if (!IsTileType(tile, MP_INDUSTRY) || GetIndustryIndex(tile) == i->index) {
+		/* No industry and/or the tile does not have the same industry as the one we match it with */
+		return 0xFFFF;
+	}
 
-			if (gfx < NEW_INDUSTRYOFFSET) {  // Does it belongs to an old type?
-				/* It is an old tile.  We have to see if it's been overriden */
-				if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) {  // has it been overridden?
-					return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
-				} else { // yes.  FInd out if it is from the same grf file or not
-					const IndustryTileSpec *old_tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
+	IndustryGfx gfx = GetCleanIndustryGfx(tile);
+	const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
+	const IndustrySpec *indold = GetIndustrySpec(i->type);
 
-					if (old_tile_ovr->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {
-						return old_tile_ovr->grf_prop.local_id; // same grf file
-					} else {
-						return 0xFFFE; // not the same grf file
-					}
-				}
-			} else {
-				if (indtsp->grf_prop.spritegroup != NULL) {  // tile has a spritegroup ?
-					if (indtsp->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {  // same industry, same grf ?
-						return indtsp->grf_prop.local_id;
-					} else {
-						return 0xFFFE;  // Defined in another grf file
-					}
-				} else {  // tile has no spritegroup
-					return 0xFF << 8 | indtsp->grf_prop.subst_id;  // so just give him the substitute
-				}
-			}
+	if (gfx < NEW_INDUSTRYOFFSET) { // Does it belongs to an old type?
+		/* It is an old tile.  We have to see if it's been overriden */
+		if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) { // has it been overridden?
+			return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
+		}
+		/* Not overriden */
+		const IndustryTileSpec *tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
+
+		if (tile_ovr->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {
+			return tile_ovr->grf_prop.local_id; // same grf file
+		} else {
+			return 0xFFFE; // not the same grf file
 		}
 	}
-
-	return 0xFFFF; // tile is not an industry one or  does not belong to the current industry
+	/* Not an 'old type' tile */
+	if (indtsp->grf_prop.spritegroup != NULL) { // tile has a spritegroup ?
+		if (indtsp->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) { // same industry, same grf ?
+			return indtsp->grf_prop.local_id;
+		} else {
+			return 0xFFFE; // Defined in another grf file
+		}
+	}
+	/* The tile has no spritegroup */
+	return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give him the substitute
 }
 
 static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Industry *current)
@@ -156,8 +153,8 @@
 			break;
 
 		case 0xFFFFFFFF: // current grf
-			ind_index = GetIndustrySpec(current->type)->grf_prop.grffile->grfid;
-			/*Fall through*/
+			GrfID = GetIndustrySpec(current->type)->grf_prop.grffile->grfid;
+			/* Fall through */
 
 		default: //use the grfid specified in register 100h
 			ind_index = MapNewGRFIndustryType(param_setID, GrfID);
@@ -209,27 +206,47 @@
 		}
 
 		/* Manhattan distance of closes dry/water tile */
-		case 0x43: return GetClosestWaterDistance(tile, (object->u.industry_location.spec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
+		case 0x43: return GetClosestWaterDistance(tile, (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
 
 		/* Layout number */
 		case 0x44: return industry->selected_layout;
 
+		/* player info */
+		case 0x45: {
+			byte colours;
+			bool is_ai = false;
+
+			if (IsValidPlayer(industry->founder)) {
+				const Player *p = GetPlayer(industry->founder);
+				const Livery *l = &p->livery[LS_DEFAULT];
+
+				is_ai = p->is_ai;
+				colours = l->colour1 + l->colour2 * 16;
+			} else {
+				colours = GB(Random(), 0, 8);
+			}
+
+			return industry->founder | (is_ai ? 0x10000 : 0) | (colours << 24);
+		}
+
 		/* Get industry ID at offset param */
-		case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), tile, industry);
+		case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), industry);
 
-		case 0x61: return 0; // Get random tile bits at offset param
+		/* Get random tile bits at offset param */
+		case 0x61:
+			tile = GetNearbyTile(parameter, tile);
+			return (IsTileType(tile, MP_INDUSTRY) && GetIndustryByTile(tile) == industry) ? GetIndustryRandomBits(tile) : 0;
 
 		/* Land info of nearby tiles */
 		case 0x62: return GetNearbyIndustryTileInformation(parameter, tile, INVALID_INDUSTRY);
 
 		/* Animation stage of nearby tiles */
-		case 0x63: {
+		case 0x63:
 			tile = GetNearbyTile(parameter, tile);
 			if (IsTileType(tile, MP_INDUSTRY) && GetIndustryByTile(tile) == industry) {
 				return GetIndustryAnimationState(tile);
 			}
 			return 0xFFFFFFFF;
-		}
 
 		/* Distance of nearest industry of given type */
 		case 0x64: return GetClosestIndustry(tile, MapNewGRFIndustryType(parameter, indspec->grf_prop.grffile->grfid), industry);
@@ -258,7 +275,7 @@
 		case 0x87: return industry->height;// xy dimensions
 		/*  */
 		case 0x88:
-		case 0x89: return indspec->produced_cargo[variable - 0x88];
+		case 0x89: return industry->produced_cargo[variable - 0x88];
 		case 0x8A: return industry->produced_cargo_waiting[0];
 		case 0x8B: return GB(industry->produced_cargo_waiting[0], 8, 8);
 		case 0x8C: return industry->produced_cargo_waiting[1];
@@ -267,7 +284,7 @@
 		case 0x8F: return industry->production_rate[variable - 0x8E];
 		case 0x90:
 		case 0x91:
-		case 0x92: return indspec->accepts_cargo[variable - 0x90];
+		case 0x92: return industry->accepts_cargo[variable - 0x90];
 		case 0x93: return industry->prod_level;
 		/* amount of cargo produced so far THIS month. */
 		case 0x94: return industry->this_month_production[0];
@@ -318,11 +335,27 @@
 	return NULL;
 }
 
+static uint32 IndustryGetRandomBits(const ResolverObject *object)
+{
+	return object->u.industry.ind == NULL ? 0 : 0; //object->u.industry.ind->random_bits;
+}
+
+static uint32 IndustryGetTriggers(const ResolverObject *object)
+{
+	return object->u.industry.ind == NULL ? 0 : 0; //object->u.industry.ind->triggers;
+}
+
+static void IndustrySetTriggers(const ResolverObject *object, int triggers)
+{
+	if (object->u.industry.ind == NULL) return;
+	//object->u.industry.ind->triggers = triggers;
+}
+
 static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus)
 {
-	res->GetRandomBits = IndustryTileGetRandomBits;
-	res->GetTriggers   = IndustryTileGetTriggers;
-	res->SetTriggers   = IndustryTileSetTriggers;
+	res->GetRandomBits = IndustryGetRandomBits;
+	res->GetTriggers   = IndustryGetTriggers;
+	res->SetTriggers   = IndustrySetTriggers;
 	res->GetVariable   = IndustryGetVariable;
 	res->ResolveReal   = IndustryResolveReal;
 
@@ -357,55 +390,47 @@
 
 uint32 IndustryLocationGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 {
-	TileIndex tile = object->u.industry_location.tile;
+	const Industry *industry = object->u.industry.ind;
+	TileIndex tile = object->u.industry.tile;
 
 	if (object->scope == VSG_SCOPE_PARENT) {
-		return TownGetVariable(variable, parameter, available, ClosestTownFromTile(tile, (uint)-1));
+		return TownGetVariable(variable, parameter, available, industry->town);
 	}
 
 	switch (variable) {
-		/* Land info of nearby tiles */
-		case 0x62: return GetNearbyIndustryTileInformation(parameter, tile, INVALID_INDUSTRY);
-
-		/* Distance of nearest industry of given type */
-		case 0x64: return GetClosestIndustry(tile, MapNewGRFIndustryType(parameter, object->u.industry_location.spec->grf_prop.grffile->grfid), NULL);
-
-		/* Location where to build the industry */
 		case 0x80: return tile;
 		case 0x81: return GB(tile, 8, 8);
 
 		/* Pointer to the town the industry is associated with */
-		case 0x82: return ClosestTownFromTile(tile, (uint)-1)->index;
+		case 0x82: return industry->town->index;
 		case 0x83:
 		case 0x84:
 		case 0x85: DEBUG(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
 
 		/* Number of the layout */
-		case 0x86: return object->u.industry_location.itspec_index;
+		case 0x86: return industry->selected_layout;
 
 		/* Ground type */
 		case 0x87: return GetTerrainType(tile);
 
 		/* Town zone */
-		case 0x88: return GetTownRadiusGroup(ClosestTownFromTile(tile, (uint)-1), tile);
+		case 0x88: return GetTownRadiusGroup(industry->town, tile);
 
 		/* Manhattan distance of the closest town */
-		case 0x89: return min(DistanceManhattan(ClosestTownFromTile(tile, (uint)-1)->xy, tile), 255);
+		case 0x89: return min(DistanceManhattan(industry->town->xy, tile), 255);
 
 		/* Lowest height of the tile */
 		case 0x8A: return GetTileZ(tile);
 
 		/* Distance to the nearest water/land tile */
-		case 0x8B: return GetClosestWaterDistance(tile, (object->u.industry_location.spec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
+		case 0x8B: return GetClosestWaterDistance(tile, (GetIndustrySpec(industry->type)->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
 
 		/* Square of Euclidian distance from town */
-		case 0x8D: return min(DistanceSquare(ClosestTownFromTile(tile, (uint)-1)->xy, tile), 65535);
+		case 0x8D: return min(DistanceSquare(industry->town->xy, tile), 65535);
 	}
 
-	DEBUG(grf, 1, "Unhandled location industry property 0x%X", variable);
-
-	*available = false;
-	return (uint32)-1;
+	/* None of the special ones, so try the general ones */
+	return IndustryGetVariable(object, variable, parameter, available);
 }
 
 bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index)
@@ -415,16 +440,23 @@
 	ResolverObject object;
 	const SpriteGroup *group;
 
-	NewIndustryResolver(&object, tile, NULL);
+	Industry ind;
+	ind.index = INVALID_INDUSTRY;
+	ind.xy = tile;
+	ind.width = 0;
+	ind.type = type;
+	ind.selected_layout = itspec_index;
+	ind.town = ClosestTownFromTile(tile, (uint)-1);
+
+	NewIndustryResolver(&object, tile, &ind);
 	object.GetVariable = IndustryLocationGetVariable;
 	object.callback = CBID_INDUSTRY_LOCATION;
-	object.u.industry_location.tile = tile;
-	object.u.industry_location.spec = indspec;
-	object.u.industry_location.itspec_index = itspec_index;
 
 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
 
-	if (group == NULL || group->type != SGT_CALLBACK) return false;
+	/* Unlike the "normal" cases, not having a valid result means we allow
+	 * the building of the industry, as that's how it's done in TTDP. */
+	if (group == NULL || group->type != SGT_CALLBACK) return true;
 
 	switch (group->g.callback.result) {
 		case 0x400: return true;
--- a/src/newgrf_industries.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_industries.h	Sat Oct 06 22:30:24 2007 +0000
@@ -8,10 +8,20 @@
 #include "industry.h"
 #include "newgrf_spritegroup.h"
 
+/** When should the industry(tile) be triggered for random bits? */
+enum IndustryTrigger {
+	/** Triggered each tile loop */
+	INDUSTRY_TRIGGER_TILELOOP_PROCESS = 1,
+	/** Triggered (whole industry) each 256 ticks */
+	INDUSTRY_TRIGGER_256_TICKS        = 2,
+	/** Triggered on cargo delivery */
+	INDUSTRY_TRIGGER_CARGO_DELIVERY   = 4,
+};
+
 /* in newgrf_industry.cpp */
 uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available);
 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile);
-uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i);
+uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i);
 void IndustryProductionCallback(Industry *ind, int reason);
 bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index);
 bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCallType creation_type);
@@ -19,10 +29,6 @@
 IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id);
 
 /* in newgrf_industrytiles.cpp*/
-uint32 IndustryTileGetRandomBits(const ResolverObject *object);
-uint32 IndustryTileGetTriggers(const ResolverObject *object);
-void IndustryTileSetTriggers(const ResolverObject *object, int triggers);
-
 uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index);
 
 #endif /* NEWGRF_INDUSTRIES_H */
--- a/src/newgrf_industrytiles.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_industrytiles.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -99,7 +99,7 @@
 		}
 
 		/* Get industry tile ID at offset */
-		case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), tile, inds);
+		case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), inds);
 	}
 
 	DEBUG(grf, 1, "Unhandled industry tile property 0x%X", variable);
@@ -114,22 +114,30 @@
 	return NULL;
 }
 
-uint32 IndustryTileGetRandomBits(const ResolverObject *object)
+static uint32 IndustryTileGetRandomBits(const ResolverObject *object)
 {
 	const TileIndex tile = object->u.industry.tile;
-	return (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) ? 0 : GetIndustryRandomBits(tile);
+	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
+	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryRandomBits(tile) : 0; //GetIndustryByTile(tile)->random_bits;
 }
 
-uint32 IndustryTileGetTriggers(const ResolverObject *object)
+static uint32 IndustryTileGetTriggers(const ResolverObject *object)
 {
 	const TileIndex tile = object->u.industry.tile;
-	return (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) ? 0 : GetIndustryTriggers(tile);
+	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
+	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : 0; //GetIndustryByTile(tile)->triggers;
 }
 
-void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
+static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
 {
 	const TileIndex tile = object->u.industry.tile;
-	if (IsTileType(tile, MP_INDUSTRY)) SetIndustryTriggers(tile, triggers);
+	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return;
+
+	if (object->scope != VSG_SCOPE_SELF) {
+		SetIndustryTriggers(tile, triggers);
+	} else {
+		//GetIndustryByTile(tile)->triggers = triggers;
+	}
 }
 
 static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIndex tile, Industry *indus)
@@ -161,14 +169,18 @@
 	SpriteID image = dts->ground_sprite;
 	SpriteID pal   = dts->ground_pal;
 
+	if (IS_CUSTOM_SPRITE(image)) image += stage;
+
 	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
 
 	foreach_draw_tile_seq(dtss, dts->seq) {
 		if (GB(dtss->image, 0, SPRITE_WIDTH) == 0) continue;
 
-		image = dtss->image + stage;
+		image = dtss->image;
 		pal   = dtss->pal;
 
+		if (IS_CUSTOM_SPRITE(image)) image += stage;
+
 		if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
 			pal = GENERAL_SPRITE_COLOR(rnd_color);
 		} else {
@@ -184,7 +196,7 @@
 				!HASBIT(image, SPRITE_MODIFIER_OPAQUE) && HASBIT(_transparent_opt, TO_INDUSTRIES)
 			);
 		} else {
-			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
+			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y, HASBIT(_transparent_opt, TO_INDUSTRIES));
 		}
 	}
 }
@@ -235,18 +247,23 @@
 	}
 }
 
-bool PerformIndustryTileSlopeCheck(TileIndex tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx)
+extern bool IsSlopeRefused(Slope current, Slope refused);
+
+bool PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index)
 {
 	Industry ind;
-	ind.xy = 0;
+	ind.index = INVALID_INDUSTRY;
+	ind.xy = ind_base_tile;
 	ind.width = 0;
 	ind.type = type;
 
-	uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, 0, gfx, &ind, tile);
+	uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, itspec_index, gfx, &ind, ind_tile);
+	if (callback_res == CALLBACK_FAILED) {
+		return !IsSlopeRefused(GetTileSlope(ind_tile, NULL), its->slopes_refused);
+	}
 	if (its->grf_prop.grffile->grf_version < 7) {
 		return callback_res != 0;
 	}
-	if (callback_res == CALLBACK_FAILED) return false;
 
 	switch (callback_res) {
 		case 0x400: return true;
@@ -350,8 +367,11 @@
 	uint32 random = Random();
 	BEGIN_TILE_LOOP(tile, ind->width, ind->height, ind->xy)
 		if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == ind->index) {
-			ret &= StartStopIndustryTileAnimation(tile, iat, random);
-			SB(random, 0, 16, Random());
+			if (StartStopIndustryTileAnimation(tile, iat, random)) {
+				SB(random, 0, 16, Random());
+			} else {
+				ret = false;
+			}
 		}
 	END_TILE_LOOP(tile, ind->width, ind->height, ind->xy)
 
--- a/src/newgrf_industrytiles.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_industrytiles.h	Sat Oct 06 22:30:24 2007 +0000
@@ -15,7 +15,7 @@
 
 bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds);
 uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile);
-bool PerformIndustryTileSlopeCheck(TileIndex tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx);
+bool PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index);
 
 void AnimateNewIndustryTile(TileIndex tile);
 bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random());
--- a/src/newgrf_sound.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_sound.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -59,7 +59,7 @@
 	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;
+	if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_SOUND_EFFECT)) return false;
 
 	callback = GetVehicleCallback(CBID_VEHICLE_SOUND_EFFECT, event, 0, v->engine_type, v);
 	if (callback == CALLBACK_FAILED) return false;
--- a/src/newgrf_spritegroup.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_spritegroup.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -212,7 +212,7 @@
 		switch (object->callback) {
 			/* All these functions are 15 bit callbacks */
 			case CBID_VEHICLE_REFIT_CAPACITY:
-			case CBID_BUILDING_COLOUR:
+			case CBID_HOUSE_COLOUR:
 			case CBID_HOUSE_CARGO_ACCEPTANCE:
 			case CBID_INDUSTRY_LOCATION:
 			case CBID_INDTILE_CARGO_ACCEPTANCE:
--- a/src/newgrf_spritegroup.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_spritegroup.h	Sat Oct 06 22:30:24 2007 +0000
@@ -231,11 +231,6 @@
 			IndustryGfx gfx;
 		} industry;
 		struct {
-			TileIndex tile;
-			const IndustrySpec *spec;
-			uint itspec_index;
-		} industry_location;
-		struct {
 			const struct CargoSpec *cs;
 		} cargo;
 	} u;
--- a/src/newgrf_station.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/newgrf_station.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -751,7 +751,7 @@
 
 	relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE);
 
-	if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+	if (HASBIT(statspec->callbackmask, CBM_STATION_SPRITE_LAYOUT)) {
 		uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE);
 		if (callback != CALLBACK_FAILED) tile = callback;
 	}
--- a/src/openttd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/openttd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -2191,6 +2191,19 @@
 		}
 	}
 
+	if (CheckSavegameVersion(78)) {
+		Industry *i;
+		uint j;
+		FOR_ALL_INDUSTRIES(i) {
+			const IndustrySpec *indsp = GetIndustrySpec(i->type);
+			for (j = 0; j < lengthof(i->produced_cargo); j++) {
+				i->produced_cargo[j] = indsp->produced_cargo[j];
+			}
+			for (j = 0; j < lengthof(i->accepts_cargo); j++) {
+				i->accepts_cargo[j] = indsp->accepts_cargo[j];
+			}
+		}
+	}
 
 	return true;
 }
--- a/src/order.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/order.h	Sat Oct 06 22:30:24 2007 +0000
@@ -116,18 +116,18 @@
 	void FreeChain();
 };
 
-#define MAX_BACKUP_ORDER_COUNT 40
+struct BackuppedOrders {
+	BackuppedOrders() : order(NULL) { }
 
-struct BackuppedOrders {
 	VehicleID clone;
 	VehicleOrderID orderindex;
-	Order order[MAX_BACKUP_ORDER_COUNT + 1];
+	Order *order;
 	uint16 service_interval;
 	char name[32];
 };
 
 VARDEF TileIndex _backup_orders_tile;
-VARDEF BackuppedOrders _backup_orders_data[1];
+VARDEF BackuppedOrders _backup_orders_data;
 
 static inline VehicleOrderID GetMaxOrderIndex()
 {
@@ -200,8 +200,8 @@
 }
 
 /* Functions */
-void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order);
-void RestoreVehicleOrders(const Vehicle* v, const BackuppedOrders* order);
+void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order = &_backup_orders_data);
+void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *order = &_backup_orders_data);
 void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
 void InvalidateVehicleOrder(const Vehicle *v);
 bool VehicleHasDepotOrders(const Vehicle *v);
--- a/src/order_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/order_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -19,6 +19,7 @@
 #include "vehicle_gui.h"
 #include "cargotype.h"
 #include "strings.h"
+#include "aircraft.h"
 
 DEFINE_OLD_POOL_GENERIC(Order, Order)
 
@@ -198,7 +199,9 @@
 					break;
 
 				case VEH_AIRCRAFT:
-					if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
+					if (!(st->facilities & FACIL_AIRPORT) || !CanAircraftUseStation(v->engine_type, st)) {
+						return CMD_ERROR;
+					}
 					break;
 
 				default: return CMD_ERROR;
@@ -239,7 +242,8 @@
 
 				if (!CheckOwnership(st->owner) ||
 						!(st->facilities & FACIL_AIRPORT) ||
-						st->Airport()->nof_depots == 0) {
+						st->Airport()->nof_depots == 0 ||
+						!CanAircraftUseStation(v->engine_type, st)) {
 					return CMD_ERROR;
 				}
 			} else {
@@ -317,10 +321,6 @@
 
 	if (!HasOrderPoolFree(1)) 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);
-
 	if (v->type == VEH_SHIP &&
 			IsHumanPlayer(v->owner) &&
 			!_patches.new_pathfinding_all) {
@@ -920,6 +920,10 @@
  */
 void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *bak)
 {
+	/* Make sure we always have freed the stuff */
+	free(bak->order);
+	bak->order = NULL;
+
 	/* Save general info */
 	bak->orderindex       = v->cur_order_index;
 	bak->service_interval = v->service_interval;
@@ -939,13 +943,21 @@
 		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;
 
+
+		/* Count the number of orders */
+		uint cnt = 0;
+		const Order *order;
+		FOR_VEHICLE_ORDERS(v, order) cnt++;
+
+		/* Allocate memory for the orders plus an end-of-orders marker */
+		bak->order = MallocT<Order>(cnt + 1);
+
+		Order *dest = bak->order;
+
 		/* Copy the orders */
 		FOR_VEHICLE_ORDERS(v, order) {
 			*dest = *order;
@@ -961,12 +973,10 @@
  * Restore vehicle orders that are backupped via BackupVehicleOrders
  *
  */
-void RestoreVehicleOrders(const Vehicle* v, const BackuppedOrders* bak)
+void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *bak)
 {
-	uint i;
-
 	/* If we have a custom name, process that */
-	if (bak->name[0] != 0) {
+	if (!StrEmpty(bak->name)) {
 		_cmd_text = bak->name;
 		DoCommandP(0, v->index, 0, NULL, CMD_NAME_VEHICLE);
 	}
@@ -981,7 +991,7 @@
 	 *  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].IsValid(); i++) {
+	for (uint i = 0; bak->order[i].IsValid(); i++) {
 		if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
 			break;
 	}
@@ -1032,7 +1042,7 @@
 	switch (v->type) {
 		default: NOT_REACHED();
 		case VEH_TRAIN:     return st->train_tile;
-		case VEH_AIRCRAFT:  return st->airport_tile;
+		case VEH_AIRCRAFT:  return CanAircraftUseStation(v->engine_type, st) ? st->airport_tile : 0;
 		case VEH_SHIP:      return st->dock_tile;
 		case VEH_ROAD:
 			if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) {
--- a/src/rail_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/rail_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -1065,6 +1065,7 @@
 
 		if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
 			/* Update build vehicle window related to this depot */
+			InvalidateWindowData(WC_VEHICLE_DEPOT, tile);
 			InvalidateWindowData(WC_BUILD_VEHICLE, tile);
 		}
 
@@ -1516,7 +1517,7 @@
 				const Station* st = ComposeWaypointStation(ti->tile);
 				uint gfx = 2;
 
-				if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+				if (HASBIT(statspec->callbackmask, CBM_STATION_SPRITE_LAYOUT)) {
 					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
 					if (callback != CALLBACK_FAILED) gfx = callback;
 				}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/road.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -0,0 +1,69 @@
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "rail_map.h"
+#include "road.h"
+#include "road_map.h"
+#include "water_map.h"
+#include "macros.h"
+
+bool IsPossibleCrossing(const TileIndex tile, Axis ax)
+{
+	return (IsTileType(tile, MP_RAILWAY) &&
+		!HasSignals(tile) &&
+		GetTrackBits(tile) == (ax == AXIS_X ?  TRACK_BIT_Y : TRACK_BIT_X) &&
+		GetTileSlope(tile, NULL) == SLOPE_FLAT);
+}
+
+RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
+{
+	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
+		const TileIndex neighbor_tile = TileAddByDiagDir(tile, dir);
+
+		/* Get the Roadbit pointing to the neighbor_tile */
+		const RoadBits target_rb = DiagDirToRoadBits(dir);
+
+		/* If the roadbit is in the current plan */
+		if (org_rb & target_rb) {
+			bool connective = false;
+			const RoadBits mirrored_rb = MirrorRoadBits(target_rb);
+
+			switch (GetTileType(neighbor_tile)) {
+				/* Allways connective ones */
+				case MP_CLEAR: case MP_TREES:
+					connective = true;
+					break;
+
+				/* The conditionaly connective ones */
+				case MP_TUNNELBRIDGE:
+				case MP_STATION:
+				case MP_ROAD: {
+					const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM);
+
+					/* Accept only connective tiles */
+					connective = (neighbor_rb & mirrored_rb) || // Neighbor has got the fitting RoadBit
+							COUNTBITS(neighbor_rb) == 1; // Neighbor has got only one Roadbit
+
+				} break;
+
+				case MP_RAILWAY:
+					connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir));
+					break;
+
+				case MP_WATER:
+					/* Check for real water tile */
+					connective = !IsWater(neighbor_tile);
+					break;
+
+				/* The defentetly not connective ones */
+				default: break;
+			}
+
+			/* If the neighbor tile is inconnective remove the planed road connection to it */
+			if (!connective) org_rb ^= target_rb;
+
+		}
+	}
+
+	return org_rb;
+}
--- a/src/road.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/road.h	Sat Oct 06 22:30:24 2007 +0000
@@ -116,6 +116,36 @@
 }
 
 /**
+ * Calculate the mirrored RoadBits
+ *
+ * Simply move the bits to their new position.
+ *
+ * @param r The given RoadBits value
+ * @return the mirrored
+ */
+static inline RoadBits MirrorRoadBits(RoadBits r)
+{
+	return (RoadBits)(GB(r, 0, 2) << 2 | GB(r, 2, 2));
+}
+
+/**
+ * Calculate rotated RoadBits
+ *
+ * Move the Roadbits clockwise til they are in their final position.
+ *
+ * @param r The given RoadBits value
+ * @param rot The given Rotation angle
+ * @return the rotated
+ */
+static inline RoadBits RotateRoadBits(RoadBits r, DiagDirDiff rot)
+{
+	for (; rot > (DiagDirDiff)0; rot--){
+		r = (RoadBits)(GB(r, 0, 1) << 3 | GB(r, 1, 3));
+	}
+	return r;
+}
+
+/**
  * Create the road-part which belongs to the given DiagDirection
  *
  * This function returns a RoadBits value which belongs to
@@ -130,6 +160,16 @@
 }
 
 /**
+ * Return if the tile is a valid tile for a crossing.
+ *
+ * @note function is overloaded
+ * @param tile the curent tile
+ * @param ax the axis of the road over the rail
+ * @return true if it is a valid tile
+ */
+bool IsPossibleCrossing(const TileIndex tile, Axis ax);
+
+/**
  * Checks whether the trackdir means that we are reversing.
  * @param dir the trackdir to check
  * @return true if it is a reversing road trackdir
@@ -150,6 +190,14 @@
 }
 
 /**
+ * Clean up unneccesary RoadBits of a planed tile.
+ * @param tile current tile
+ * @param org_rb planed RoadBits
+ * @return optimised RoadBits
+ */
+RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb);
+
+/**
  * Is it allowed to remove the given road bits from the given tile?
  * @param tile      the tile to remove the road from
  * @param remove    the roadbits that are going to be removed
--- a/src/road_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/road_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -259,70 +259,121 @@
 static const RoadBits _valid_tileh_slopes_road[][15] = {
 	/* set of normal ones */
 	{
-		ROAD_ALL, ROAD_NONE, ROAD_NONE,
-		ROAD_X,   ROAD_NONE, ROAD_NONE,  // 3, 4, 5
-		ROAD_Y,   ROAD_NONE, ROAD_NONE,
-		ROAD_Y,   ROAD_NONE, ROAD_NONE,  // 9, 10, 11
-		ROAD_X,   ROAD_NONE, ROAD_NONE
+		ROAD_ALL,  // SLOPE_FLAT
+		ROAD_NONE, // SLOPE_W
+		ROAD_NONE, // SLOPE_S
+
+		ROAD_X,    // SLOPE_SW
+		ROAD_NONE, // SLOPE_E
+		ROAD_NONE, // SLOPE_EW
+
+		ROAD_Y,    // SLOPE_SE
+		ROAD_NONE, // SLOPE_WSE
+		ROAD_NONE, // SLOPE_N
+
+		ROAD_Y,    // SLOPE_NW
+		ROAD_NONE, // SLOPE_NS
+		ROAD_NONE, // SLOPE_NE
+
+		ROAD_X,    // SLOPE_ENW
+		ROAD_NONE, // SLOPE_SEN
+		ROAD_NONE  // SLOPE_ELEVATED
 	},
 	/* allowed road for an evenly raised platform */
 	{
-		ROAD_NONE,
-		ROAD_SW | ROAD_NW,
-		ROAD_SW | ROAD_SE,
-		ROAD_Y  | ROAD_SW,
+		ROAD_NONE,         // SLOPE_FLAT
+		ROAD_SW | ROAD_NW, // SLOPE_W
+		ROAD_SW | ROAD_SE, // SLOPE_S
 
-		ROAD_SE | ROAD_NE, // 4
-		ROAD_ALL,
-		ROAD_X  | ROAD_SE,
-		ROAD_ALL,
+		ROAD_Y  | ROAD_SW, // SLOPE_SW
+		ROAD_SE | ROAD_NE, // SLOPE_E
+		ROAD_ALL,          // SLOPE_EW
 
-		ROAD_NW | ROAD_NE, // 8
-		ROAD_X  | ROAD_NW,
-		ROAD_ALL,
-		ROAD_ALL,
+		ROAD_X  | ROAD_SE, // SLOPE_SE
+		ROAD_ALL,          // SLOPE_WSE
+		ROAD_NW | ROAD_NE, // SLOPE_N
 
-		ROAD_Y  | ROAD_NE, // 12
-		ROAD_ALL,
-		ROAD_ALL
+		ROAD_X  | ROAD_NW, // SLOPE_NW
+		ROAD_ALL,          // SLOPE_NS
+		ROAD_ALL,          // SLOPE_NE
+
+		ROAD_Y  | ROAD_NE, // SLOPE_ENW
+		ROAD_ALL,          // SLOPE_SEN
+		ROAD_ALL           // SLOPE_ELEVATED
+	},
+	/* Singe bits on slopes */
+	{
+		ROAD_ALL,          // SLOPE_FLAT
+		ROAD_NE | ROAD_SE, // SLOPE_W
+		ROAD_NE | ROAD_NW, // SLOPE_S
+
+		ROAD_NE,           // SLOPE_SW
+		ROAD_NW | ROAD_SW, // SLOPE_E
+		ROAD_ALL,          // SLOPE_EW
+
+		ROAD_NW,           // SLOPE_SE
+		ROAD_ALL,          // SLOPE_WSE
+		ROAD_SE | ROAD_SW, // SLOPE_N
+
+		ROAD_SE,           // SLOPE_NW
+		ROAD_ALL,          // SLOPE_NS
+		ROAD_ALL,          // SLOPE_NE
+
+		ROAD_SW,           // SLOPE_ENW
+		ROAD_ALL,          // SLOPE_SEN
+		ROAD_ALL,          // SLOPE_ELEVATED
 	},
 };
 
-
+/**
+ * Calculate the costs for roads on slopes
+ *  Aside modify the RoadBits to fit on the slopes
+ *
+ * @note The RoadBits are modified too!
+ * @param tileh The current slope
+ * @param pieces The RoadBits we want to add
+ * @param existing The existent RoadBits
+ * @return The costs for these RoadBits on this slope
+ */
 static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
 {
-	RoadBits road_bits;
-
 	if (IsSteepSlope(tileh)) {
-		/* force full pieces. */
-		*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
-		*pieces |= (RoadBits)((*pieces & 0x3) << 2);
+		/* Force straight roads. */
+		*pieces |= MirrorRoadBits(*pieces);
 
-		if (existing == 0 || existing == *pieces) {
+		if (existing == ROAD_NONE || existing == *pieces) {
 			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
 		}
 		return CMD_ERROR;
 	}
-	road_bits = *pieces | existing;
+
+	RoadBits road_bits = *pieces | existing;
+
+	/* Single bits on slopes.
+	 * We check for the roads that need at least 2 bits */
+	if (_patches.build_on_slopes &&
+			existing == ROAD_NONE && COUNTBITS(*pieces) == 1 &&
+			(_valid_tileh_slopes_road[2][tileh] & *pieces) == ROAD_NONE) {
+		return CommandCost(_price.terraform);
+	}
 
 	/* no special foundation */
-	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
+	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == ROAD_NONE) {
 		/* force that all bits are set when we have slopes */
 		if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
 		return CommandCost(); // no extra cost
 	}
 
 	/* foundation is used. Whole tile is leveled up */
-	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
-		return CommandCost(existing != 0 ? 0 : _price.terraform);
+	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == ROAD_NONE) {
+		return CommandCost(existing != ROAD_NONE ? 0 : _price.terraform);
 	}
 
-	*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
-	*pieces |= (RoadBits)((*pieces & 0x3) << 2);
+	/* Force straight roads. */
+	*pieces |= MirrorRoadBits(*pieces);
 
 	/* partly leveled up tile, only if there's no road on that tile */
-	if ((existing == 0 || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
-		/* force full pieces. */
+	if ((existing == ROAD_NONE || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
 		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
 	}
 	return CMD_ERROR;
@@ -602,7 +653,7 @@
 	/* On the X-axis, we have to swap the initial bits, so they
 	 * will be interpreted correctly in the GTTS. Futhermore
 	 * when you just 'click' on one tile to build them. */
-	if (HASBIT(p2, 2) == (start_tile == end_tile)) drd ^= DRD_BOTH;
+	if (HASBIT(p2, 2) == (start_tile == end_tile && HASBIT(p2, 0) == HASBIT(p2, 1))) drd ^= DRD_BOTH;
 	/* No disallowed direction bits have to be toggled */
 	if (!HASBIT(p2, 5)) drd = DRD_NONE;
 
@@ -785,10 +836,11 @@
 		case ROAD_TILE_NORMAL: {
 			RoadBits b = GetAllRoadBits(tile);
 
-#define M(x) (1 << (x))
 			/* Clear the road if only one piece is on the tile OR the AI tries
 			 * to clear town road OR we are not using the DC_AUTO flag */
-			if ((M(b) & (M(ROAD_NW) | M(ROAD_SW) | M(ROAD_SE) | M(ROAD_NE))) || !(flags & DC_AUTO)) {
+			if ((COUNTBITS(b) == 1 && GetRoadBits(tile, ROADTYPE_TRAM) == ROAD_NONE) ||
+			    IsTileOwner(tile, OWNER_TOWN) || !(flags & DC_AUTO)
+				) {
 				RoadTypes rts = GetRoadTypes(tile);
 				CommandCost ret;
 				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
@@ -802,7 +854,6 @@
 			}
 			return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
 		}
-#undef M
 
 		case ROAD_TILE_CROSSING: {
 			RoadTypes rts = GetRoadTypes(tile);
@@ -1179,8 +1230,8 @@
 
 	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) return;
 
+	const Town* t = ClosestTownFromTile(tile, (uint)-1);
 	if (!HasRoadWorks(tile)) {
-		const Town* t = ClosestTownFromTile(tile, (uint)-1);
 		int grp = 0;
 
 		if (t != NULL) {
@@ -1189,8 +1240,8 @@
 			/* 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 && (GetAllRoadBits(tile) == ROAD_X || GetAllRoadBits(tile) == ROAD_Y)) {
-				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) {
+					GetRoadTileType(tile) == ROAD_TILE_NORMAL && COUNTBITS(GetAllRoadBits(tile)) > 1 ) {
+				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 40)) {
 					StartRoadWorks(tile);
 
 					SndPlayTileFx(SND_21_JACKHAMMER, tile);
@@ -1228,6 +1279,17 @@
 		}
 	} else if (IncreaseRoadWorksCounter(tile)) {
 		TerminateRoadWorks(tile);
+
+		if (_patches.mod_road_rebuild) {
+			/* Generate a nicer town surface */
+			const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
+			const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
+
+			if (old_rb != new_rb) {
+				DoCommand(tile, (old_rb ^ new_rb), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_REMOVE_ROAD);
+			}
+		}
+
 		MarkTileDirtyByTile(tile);
 	}
 }
--- a/src/roadveh_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/roadveh_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -1001,7 +1001,7 @@
 	const Vehicle* u;
 	const Vehicle* v;
 	TileIndex tile;
-	byte tilebits;
+	uint16 tilebits;
 };
 
 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
@@ -1017,9 +1017,10 @@
 {
 	uint32 bits;
 
-	bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes) & 0x3F;
+	bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes);
+	bits |= bits >> 8;
 
-	if (!(od->tilebits & bits) || (bits & 0x3C) || (bits & 0x3F3F0000))
+	if (!(od->tilebits & bits) || (bits & 0x3C3C) || (bits & 0x3F3F0000))
 		return true;
 	return VehicleFromPos(od->tile, od, EnumFindVehToOvertake) != NULL;
 }
@@ -1027,7 +1028,7 @@
 static void RoadVehCheckOvertake(Vehicle *v, Vehicle *u)
 {
 	OvertakeData od;
-	byte tt;
+	uint16 tt;
 
 	od.v = v;
 	od.u = u;
@@ -1041,6 +1042,9 @@
 	/* Trams can't overtake other trams */
 	if (v->u.road.roadtype == ROADTYPE_TRAM) return;
 
+	/* Don't overtake in stations */
+	if (IsTileType(v->tile, MP_STATION)) return;
+
 	/* For now, articulated road vehicles can't overtake anything. */
 	if (RoadVehHasArticPart(v)) return;
 
@@ -1049,7 +1053,10 @@
 	/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
 	if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return;
 
-	tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes) & 0x3F;
+	tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
+	tt |= tt >> 8;
+	tt &= 0x3F;
+
 	if ((tt & 3) == 0) return;
 	if ((tt & 0x3C) != 0) return;
 
@@ -1650,9 +1657,9 @@
 		Vehicle* u = RoadVehFindCloseTo(v, x, y, new_dir);
 
 		if (u != NULL) {
-			v->cur_speed = u->cur_speed;
 			/* There is a vehicle in front overtake it if possible */
 			if (v->u.road.overtaking == 0) RoadVehCheckOvertake(v, u);
+			if (v->u.road.overtaking == 0) v->cur_speed = u->cur_speed;
 			return false;
 		}
 	}
@@ -2026,7 +2033,7 @@
 
 		if (v->cargo_cap == 0) continue;
 
-		if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+		if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
 			/* Back up the cargo type */
 			CargoID temp_cid = v->cargo_type;
 			byte temp_subtype = v->cargo_subtype;
--- a/src/roadveh_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/roadveh_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -128,7 +128,7 @@
 	v = GetVehicle(_new_vehicle_id);
 	if (v->tile == _backup_orders_tile) {
 		_backup_orders_tile = 0;
-		RestoreVehicleOrders(v, _backup_orders_data);
+		RestoreVehicleOrders(v);
 	}
 	ShowVehicleViewWindow(v);
 }
--- a/src/saveload.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/saveload.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -29,7 +29,7 @@
 #include "strings.h"
 #include <list>
 
-extern const uint16 SAVEGAME_VERSION = 76;
+extern const uint16 SAVEGAME_VERSION = 79;
 uint16 _sl_version;       ///< the major savegame version identifier
 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
 
--- a/src/settings.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/settings.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -1423,6 +1423,8 @@
 	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_CONDBOOL(Patches, exclusive_rights,           79, SL_MAX_VERSION, 0, 0, true,           STR_CONFIG_PATCHES_ALLOW_EXCLUSIVE, NULL),
+	SDT_CONDBOOL(Patches, give_money,                 79, SL_MAX_VERSION, 0, 0, true,           STR_CONFIG_PATCHES_ALLOW_GIVE_MONEY, 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),
@@ -1432,6 +1434,7 @@
 	SDT_CONDVAR(Patches, town_growth_rate,  SLE_UINT8, 54, SL_MAX_VERSION, 0, MS, 2, 0,   4, 0, STR_CONFIG_PATCHES_TOWN_GROWTH,          NULL),
 	SDT_CONDVAR(Patches, larger_towns,      SLE_UINT8, 54, SL_MAX_VERSION, 0, D0, 4, 0, 255, 1, STR_CONFIG_PATCHES_LARGER_TOWNS,         NULL),
 	SDT_CONDVAR(Patches, initial_city_size, SLE_UINT8, 56, SL_MAX_VERSION, 0, 0,  2, 1,  10, 1, STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER, NULL),
+	SDT_CONDBOOL(Patches, mod_road_rebuild,            77, SL_MAX_VERSION, 0, 0, false,         STR_CONFIG_MODIFIED_ROAD_REBUILD,        NULL),
 
 	/***************************************************************************/
 	/* AI section of the GUI-configure patches window */
--- a/src/settings_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/settings_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -672,7 +672,6 @@
 	"drag_signals_density",
 	"oil_refinery_limit",
 	"semaphore_build_before",
-	"town_layout",
 };
 
 static const char *_patches_stations[] = {
@@ -696,10 +695,14 @@
 	"multiple_industry_per_town",
 	"same_industry_close",
 	"bribe",
+	"exclusive_rights",
+	"give_money",
 	"colored_news_year",
 	"ending_year",
 	"smooth_economy",
 	"allow_shares",
+	"town_layout",
+	"mod_road_rebuild",
 	"town_growth_rate",
 	"larger_towns",
 	"initial_city_size",
--- a/src/ship_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/ship_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -1079,7 +1079,7 @@
 	SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
 
 	/* Check the refit capacity callback */
-	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
 		/* Back up the existing cargo type */
 		CargoID temp_cid = v->cargo_type;
 		byte temp_subtype = v->cargo_subtype;
--- a/src/ship_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/ship_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -35,7 +35,7 @@
 	v = GetVehicle(_new_vehicle_id);
 	if (v->tile == _backup_orders_tile) {
 		_backup_orders_tile = 0;
-		RestoreVehicleOrders(v, _backup_orders_data);
+		RestoreVehicleOrders(v);
 	}
 	ShowVehicleViewWindow(v);
 }
--- a/src/slope.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/slope.h	Sat Oct 06 22:30:24 2007 +0000
@@ -41,6 +41,16 @@
 };
 
 /**
+ * Enumeration of tile corners
+ */
+enum Corner {
+	CORNER_W = 0,
+	CORNER_S = 1,
+	CORNER_E = 2,
+	CORNER_N = 3,
+};
+
+/**
  * Checks if a slope is steep.
  *
  * @param s The given #Slope.
@@ -73,19 +83,19 @@
  *
  * @pre      The slope must be a slope with one corner raised or a steep slope.
  * @param s  The #Slope.
- * @return   Number of the highest corner. (0 west, 1 south, 2 east, 3 north)
+ * @return   Highest corner.
  */
-static inline byte GetHighestSlopeCorner(Slope s)
+static inline Corner GetHighestSlopeCorner(Slope s)
 {
 	switch (s) {
 		case SLOPE_W:
-		case SLOPE_STEEP_W: return 0;
+		case SLOPE_STEEP_W: return CORNER_W;
 		case SLOPE_S:
-		case SLOPE_STEEP_S: return 1;
+		case SLOPE_STEEP_S: return CORNER_S;
 		case SLOPE_E:
-		case SLOPE_STEEP_E: return 2;
+		case SLOPE_STEEP_E: return CORNER_E;
 		case SLOPE_N:
-		case SLOPE_STEEP_N: return 3;
+		case SLOPE_STEEP_N: return CORNER_N;
 		default: NOT_REACHED();
 	}
 }
@@ -103,6 +113,40 @@
 	return TILE_HEIGHT;
 }
 
+/**
+ * Returns the opposite corner.
+ *
+ * @param corner A #Corner.
+ * @return The opposite corner to "corner".
+ */
+static inline Corner OppositeCorner(Corner corner)
+{
+	return (Corner)(corner ^ 2);
+}
+
+/**
+ * Returns the slope with a specific corner raised.
+ *
+ * @param corner The #Corner.
+ * @return The #Slope with corner "corner" raised.
+ */
+static inline Slope SlopeWithOneCornerRaised(Corner corner)
+{
+	assert(IS_INT_INSIDE(corner, 0, 4));
+	return (Slope)(1 << corner);
+}
+
+/**
+ * Returns the slope with all except one corner raised.
+ *
+ * @param corner The #Corner.
+ * @return The #Slope with all corners but "corner" raised.
+ */
+static inline Slope SlopeWithThreeCornersRaised(Corner corner)
+{
+	return ComplementSlope(SlopeWithOneCornerRaised(corner));
+}
+
 
 /**
  * Enumeration for Foundations.
--- a/src/station_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/station_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -165,14 +165,14 @@
 	/* No industry */
 	if (!IsTileType(tile, MP_INDUSTRY)) return false;
 
-	const IndustrySpec *indsp = GetIndustrySpec(GetIndustryByTile(tile)->type);
+	const Industry *ind = GetIndustryByTile(tile);
 
 	/* No extractive industry */
-	if ((indsp->life_type & INDUSTRYLIFE_EXTRACTIVE) == 0) return false;
-
-	for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) {
+	if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_EXTRACTIVE) == 0) return false;
+
+	for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
 		/* The industry extracts something non-liquid, i.e. no oil or plastic, so it is a mine */
-		if (indsp->produced_cargo[i] != CT_INVALID && (GetCargo(indsp->produced_cargo[i])->classes & CC_LIQUID) == 0) return true;
+		if (ind->produced_cargo[i] != CT_INVALID && (GetCargo(ind->produced_cargo[i])->classes & CC_LIQUID) == 0) return true;
 	}
 
 	return false;
@@ -208,14 +208,14 @@
 	/* No industry */
 	if (!IsTileType(tile, MP_INDUSTRY)) return false;
 
-	const IndustrySpec *indsp = GetIndustrySpec(GetIndustryByTile(tile)->type);
+	const Industry *ind = GetIndustryByTile(tile);
 
 	/* No extractive industry */
-	if ((indsp->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
-
-	for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) {
+	if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
+
+	for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
 		/* The industry produces wood. */
-		if (indsp->produced_cargo[i] != CT_INVALID && GetCargo(indsp->produced_cargo[i])->label == 'WOOD') return true;
+		if (ind->produced_cargo[i] != CT_INVALID && GetCargo(ind->produced_cargo[i])->label == 'WOOD') return true;
 	}
 
 	return false;
@@ -1732,7 +1732,7 @@
 	}
 
 	BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
-		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
+		if (!EnsureNoVehicleOnGround(tile_cur)) return CMD_ERROR;
 
 		if (flags & DC_EXEC) {
 			DeleteAnimatedTile(tile_cur);
@@ -2054,7 +2054,7 @@
 
 			relocation = GetCustomStationRelocation(statspec, st, ti->tile);
 
-			if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+			if (HASBIT(statspec->callbackmask, CBM_STATION_SPRITE_LAYOUT)) {
 				uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
 				if (callback != CALLBACK_FAILED) tile = (callback & ~1) + GetRailStationAxis(ti->tile);
 			}
@@ -2115,7 +2115,7 @@
 				HASBIT(_transparent_opt, TO_BUILDINGS)
 			);
 		} else {
-			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
+			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y, HASBIT(_transparent_opt, TO_BUILDINGS));
 		}
 	}
 }
--- a/src/town_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/town_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -98,6 +98,13 @@
 // Local
 static int _grow_town_result;
 
+/* Describe the possible states */
+enum TownGrowthResult {
+	GROWTH_SUCCEED         = -1,
+	GROWTH_SEARCH_STOPPED  =  0
+//	GROWTH_SEARCH_RUNNING >=  1
+};
+
 static bool BuildTownHouse(Town *t, TileIndex tile);
 static void DoBuildTownHouse(Town *t, TileIndex tile);
 
@@ -133,18 +140,6 @@
 }
 
 /**
- * Move a TileIndex into a diagonal direction.
- *
- * @param tile The current tile
- * @param dir The direction in which we want to step
- * @return the moved tile
- */
-static inline TileIndex AddDiagDirToTileIndex(TileIndex tile, DiagDirection dir)
-{
-	return TILE_ADD(tile, TileOffsByDiagDir(dir));
-}
-
-/**
  * House Tile drawing handler.
  * Part of the tile loop process
  * @param ti TileInfo of the tile to draw
@@ -359,7 +354,7 @@
 	if (GetHouseConstructionTick(tile) != 0) return;
 
 	/* Check and/or  */
-	if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_CONSTRUCTION_STATE_CHANGE)) {
+	if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_HOUSE_CONSTRUCTION_STATE_CHANGE)) {
 		uint16 callback_res = GetHouseCallback(CBID_HOUSE_CONSTRUCTION_STATE_CHANGE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res);
 	}
@@ -547,7 +542,7 @@
 	}
 
 	/* Check for custom cargo acceptance */
-	if (HASBIT(hs->callback_mask, CBM_CARGO_ACCEPTANCE)) {
+	if (HASBIT(hs->callback_mask, CBM_HOUSE_CARGO_ACCEPTANCE)) {
 		uint16 callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
 		if (callback != CALLBACK_FAILED) {
 			if (accepts[0] != CT_INVALID) ac[accepts[0]] = GB(callback, 0, 4);
@@ -661,7 +656,7 @@
  */
 static bool IsNeighborRoadTile(TileIndex tile, DiagDirection dir, uint dist_multi)
 {
-	static TileIndexDiff tid_lt[3]; ///< lookup table for the used diff values
+	static TileIndexDiff tid_lt[3]; // lookup table for the used diff values
 	tid_lt[0] = TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT));
 	tid_lt[1] = TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT));
 	tid_lt[2] = TileOffsByDiagDir(ReverseDiagDir(dir));
@@ -681,7 +676,7 @@
 		cur += tid_lt[(pos & 1) ? 0 : 1];
 		if (pos & 2) cur += tid_lt[2];
 
-		cur = (uint)(pos / 4) * cur; ///< Multiply for the fitting distance
+		cur = (uint)(pos / 4) * cur; // Multiply for the fitting distance
 		if (GetTownRoadBits(TILE_ADD(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
 	}
 	return false;
@@ -797,7 +792,7 @@
 static RoadBits GetTownRoadGridElement(Town* t, TileIndex tile, DiagDirection dir)
 {
 	/* align the grid to the downtown */
-	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); ///< Vector from downtown to the tile
+	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
 	RoadBits rcmd = ROAD_NONE;
 
 	switch (_patches.town_layout) {
@@ -849,32 +844,110 @@
 }
 
 /**
- * Check there are enough neighbor house tiles next to the current tile
+ * Grows the town with an extra house.
+ *  Check if there are enough neighbor house tiles
+ *  next to the current tile. If there are enough
+ *  add another house.
  *
- * @param tile current tile
- * @return true if there are more than 2 house tiles next
- *  to the current one
+ * @param t The current town
+ * @param tile The target tile for the extra house
+ * @return true if an extra house has been added
  */
-static bool AreNeighborsHouseTiles(TileIndex tile)
+static bool GrowTownWithExtraHouse(Town *t, TileIndex tile)
 {
-	uint counter = 0; ///< counts the house neighbor tiles
-
 	/* We can't look further than that. */
-	if (TileX(tile) < 1 || TileY(tile) < 1) {
-		return false;
+	if (TileX(tile) < 2 || TileY(tile) < 2 || MapMaxX() <= TileX(tile) || MapMaxY() <= TileY(tile)) return false;
+
+	uint counter = 0; // counts the house neighbor tiles
+
+	/* Check the tiles E,N,W and S of the current tile for houses */
+	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
+
+		if (IsTileType(TileAddByDiagDir(tile, dir), MP_HOUSE)) counter++;
+
+		/* If there are enough neighbors stop here */
+		if (counter >= 3) {
+			if (BuildTownHouse(t, tile)) {
+				_grow_town_result = GROWTH_SUCCEED;
+				return true;
+			}
+			return false;
+		}
 	}
-
-	/* Check the tiles E,N,W and S of the current tile. */
-	for (DiagDirection i = DIAGDIR_BEGIN; i < DIAGDIR_END; i++) {
-		if (IsTileType(AddDiagDirToTileIndex(tile, i), MP_HOUSE)) {
-			counter++;
+	return false;
+}
+
+/**
+ * Grows the town with a road piece.
+ *
+ * @param t The current town
+ * @param tile The current tile
+ * @param rcmd The RoadBits we want to build on the tile
+ * @return true if the RoadBits have been added else false
+ */
+static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
+{
+	if (CmdSucceeded(DoCommand(tile, rcmd, t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
+		_grow_town_result = GROWTH_SUCCEED;
+		return true;
+	}
+	return false;
+}
+
+/**
+ * Grows the town with a bridge.
+ *  At first we check if a bridge is reasonable.
+ *  If so we check if we are able to build it.
+ *
+ * @param t The current town
+ * @param tile The current tile
+ * @param rcmd The RoadBits which are possible on this tile
+ * @return true if a bridge has been build else false
+ */
+static bool GrowTownWithBridge(const Town *t, TileIndex tile, RoadBits rcmd)
+{
+	DiagDirection bridge_dir; // The direction of a bridge we maybe want to build
+
+	/* Determine direction of slope,
+	 *  and build a road if not a special slope. */
+	switch (GetTileSlope(tile, NULL)) {
+		case SLOPE_SW: bridge_dir = DIAGDIR_NE; break;
+		case SLOPE_SE: bridge_dir = DIAGDIR_NW; break;
+		case SLOPE_NW: bridge_dir = DIAGDIR_SE; break;
+		case SLOPE_NE: bridge_dir = DIAGDIR_SW; break;
+
+		default: return false;
+	}
+
+	/* Check if the bridge will be compatible to the RoadBits */
+	if (!(rcmd & DiagDirToRoadBits(ReverseDiagDir(bridge_dir)))) return false;
+
+	/* We are in the right direction */
+	uint32 bridge_length = 0;     // This value stores the length of the possible bridge
+	TileIndex bridge_tile = tile; // Used to store the other waterside
+
+	do {
+		if (bridge_length++ >= 11) {
+			/* Max 11 tile long bridges */
+			return false;
 		}
-
-		/* If there are enougth neighbor's stop it here */
-		if (counter >= 3) {
+		bridge_tile = TILE_MASK(bridge_tile + TileOffsByDiagDir(bridge_dir));
+	} while (IsClearWaterTile(bridge_tile));
+
+	/* no water tiles in between? */
+	if (bridge_length == 1) return false;
+
+	for (uint8 times = 0; times <= 22; times++) {
+		byte bridge_type = RandomRange(MAX_BRIDGES - 1);
+
+		/* Can we actually build the bridge? */
+		if (CmdSucceeded(DoCommand(tile, bridge_tile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE))) {
+			DoCommand(tile, bridge_tile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE);
+			_grow_town_result = GROWTH_SUCCEED;
 			return true;
 		}
 	}
+	/* Quit if it selecting an appropiate bridge type fails a large number of times. */
 	return false;
 }
 
@@ -882,32 +955,31 @@
  * Grows the given town.
  * There are at the moment 3 possible way's for
  * the town expansion:
- * @li Generate a random tile and check if there is a road allowed
- * 	@li TL_ORIGINAL
- * 	@li TL_BETTER_ROADS
- * @li Check if the town geometry allows a road and which one
- * 	@li TL_2X2_GRID
- * 	@li TL_3X3_GRID
- * @li Forbid roads, only build houses
- * 	@li TL_NO_ROADS
+ *  @li Generate a random tile and check if there is a road allowed
+ *  @li TL_ORIGINAL
+ *  @li TL_BETTER_ROADS
+ *  @li Check if the town geometry allows a road and which one
+ *  @li TL_2X2_GRID
+ *  @li TL_3X3_GRID
+ *  @li Forbid roads, only build houses
+ *  @li TL_NO_ROADS
  *
  * @param tile_ptr The current tile
  * @param cur_rb The current tiles RoadBits
  * @param target_dir The target road dir
  * @param t1 The current town
  */
-static void GrowTownInTile(TileIndex* tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town* t1)
+static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1)
 {
-	RoadBits rcmd = ROAD_NONE;  ///< RoadBits for the road construction command
-	TileIndex tmptile;          ///< Dummy tile for various things
-	TileIndex tile = *tile_ptr; ///< The main tile on which we base our growth
+	RoadBits rcmd = ROAD_NONE;  // RoadBits for the road construction command
+	TileIndex tile = *tile_ptr; // The main tile on which we base our growth
 
 	TILE_ASSERT(tile);
 
 	if (cur_rb == ROAD_NONE) {
 		/* Tile has no road. First reset the status counter
 		 * to say that this is the last iteration. */
-		_grow_town_result = 0;
+		_grow_town_result = GROWTH_SEARCH_STOPPED;
 
 		/* Remove hills etc */
 		LevelTownLand(tile);
@@ -936,14 +1008,14 @@
 					do target_dir = RandomDiagDir(); while (target_dir == source_dir);
 				}
 
-				if (!IsRoadAllowedHere(AddDiagDirToTileIndex(tile, target_dir), target_dir)) {
+				if (!IsRoadAllowedHere(TileAddByDiagDir(tile, target_dir), target_dir)) {
 					/* A road is not allowed to continue the randomized road,
 					 *  return if the road we're trying to build is curved. */
 					if (target_dir != ReverseDiagDir(source_dir)) return;
 
 					/* Return if neither side of the new road is a house */
-					if (!IsTileType(AddDiagDirToTileIndex(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90RIGHT)), MP_HOUSE) &&
-							!IsTileType(AddDiagDirToTileIndex(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90LEFT)), MP_HOUSE)) {
+					if (!IsTileType(TileAddByDiagDir(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90RIGHT)), MP_HOUSE) &&
+							!IsTileType(TileAddByDiagDir(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90LEFT)), MP_HOUSE)) {
 						return;
 					}
 
@@ -955,11 +1027,11 @@
 				break;
 		}
 
-	} else if (target_dir < (DiagDirection)5 && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
+	} else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
 		/* Continue building on a partial road.
 		 * Should be allways OK, so we only generate
 		 * the fitting RoadBits */
-		_grow_town_result = 0;
+		_grow_town_result = GROWTH_SEARCH_STOPPED;
 
 		switch (_patches.town_layout) {
 			default: NOT_REACHED();
@@ -978,8 +1050,7 @@
 				break;
 		}
 	} else {
-		bool allow_house = false; ///< Value which decides if we want to construct a house
-		TileIndex tmptile2;       ///< Yet another dummy tile
+		bool allow_house = false; // Value which decides if we want to construct a house
 
 		/* Reached a tunnel/bridge? Then continue at the other side of it. */
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
@@ -997,10 +1068,10 @@
 		if (cur_rb & DiagDirToRoadBits(target_dir)) return;
 
 		/* This is the tile we will reach if we extend to this direction. */
-		tmptile = AddDiagDirToTileIndex(tile, target_dir);
+		TileIndex house_tile = TileAddByDiagDir(tile, target_dir); // position of a possible house
 
 		/* Don't walk into water. */
-		if (IsClearWaterTile(tmptile)) return;
+		if (IsClearWaterTile(house_tile)) return;
 
 		switch (_patches.town_layout) {
 			default: NOT_REACHED();
@@ -1010,98 +1081,54 @@
 				break;
 
 			case TL_3X3_GRID: /* Use 2x2 grid afterwards! */
-				/* Fill gap if house has enougth neighbors */
-				tmptile2 = AddDiagDirToTileIndex(tmptile, target_dir);
-				if (AreNeighborsHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) {
-					_grow_town_result = -1;
-				}
+				GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
+				/* FALL THROUGH */
 
 			case TL_2X2_GRID:
-				rcmd = GetTownRoadGridElement(t1, tmptile, target_dir);
+				rcmd = GetTownRoadGridElement(t1, house_tile, target_dir);
 				allow_house = (rcmd == ROAD_NONE);
 				break;
 
 			case TL_BETTER_ROADS: /* Use original afterwards! */
-				/* Fill gap if house has enougth neighbors */
-				tmptile2 = AddDiagDirToTileIndex(tmptile, target_dir);
-				if (AreNeighborsHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) {
-					_grow_town_result = -1;
-				}
+				GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
+				/* FALL THROUGH */
 
 			case TL_ORIGINAL:
 				 /* Allow a house at the edge. 60% chance or
 				  * always ok if no road allowed. */
 				rcmd = DiagDirToRoadBits(target_dir);
-				allow_house = (!IsRoadAllowedHere(tmptile, target_dir) || CHANCE16(6, 10));
+				allow_house = (!IsRoadAllowedHere(house_tile, target_dir) || CHANCE16(6, 10));
 				break;
 		}
 
 		if (allow_house) {
 			/* Build a house, but not if there already is a house there. */
-			if (!IsTileType(tmptile, MP_HOUSE)) {
+			if (!IsTileType(house_tile, MP_HOUSE)) {
 				/* Level the land if possible */
-				LevelTownLand(tmptile);
+				LevelTownLand(house_tile);
 
 				/* And build a house.
 				 * Set result to -1 if we managed to build it. */
-				if (BuildTownHouse(t1, tmptile)) {
-					_grow_town_result = -1;
+				if (BuildTownHouse(t1, house_tile)) {
+					_grow_town_result = GROWTH_SUCCEED;
 				}
 			}
 			return;
 		}
 
-		_grow_town_result = 0;
+		_grow_town_result = GROWTH_SEARCH_STOPPED;
 	}
 
 	/* Return if a water tile */
 	if (IsClearWaterTile(tile)) return;
 
-	DiagDirection bridge_dir; ///< The direction of a bridge we maybe want to build
-	/* Determine direction of slope,
-	 *  and build a road if not a special slope. */
-	switch (GetTileSlope(tile, NULL)) {
-		case SLOPE_SW: bridge_dir = DIAGDIR_NE; break;
-		case SLOPE_SE: bridge_dir = DIAGDIR_NW; break;
-		case SLOPE_NW: bridge_dir = DIAGDIR_SE; break;
-		case SLOPE_NE: bridge_dir = DIAGDIR_SW; break;
-
-		default:
-build_road_and_exit:
-			if (CmdSucceeded(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
-				_grow_town_result = -1;
-			}
-			return;
-	}
-
-	/* Check if the bridge is in the right direction */
-	if (!(rcmd & DiagDirToRoadBits(bridge_dir))) goto build_road_and_exit;
-
-	/* We are in the right direction */
-	uint32 bridge_length = 0; ///< This value stores the length of the possible bridge
-	tmptile = tile;           ///< Now we use this dummy to store the other waterside
-	do {
-		if (bridge_length++ >= 11) {
-			/* Max 11 tile long bridges */
-			goto build_road_and_exit;
-		}
-		tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(bridge_dir));
-	} while (IsClearWaterTile(tmptile));
-
-	/* no water tiles in between? */
-	if (bridge_length == 1) goto build_road_and_exit;
-
-	for (uint times = 0; times <= 22; times++) {
-		byte bridge_type = RandomRange(MAX_BRIDGES - 1);
-
-		/* Can we actually build the bridge? */
-		if (CmdSucceeded(DoCommand(tile, tmptile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE))) {
-			DoCommand(tile, tmptile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE);
-			_grow_town_result = -1;
-			return;
-		}
-	}
-	/* Quit if it selecting an appropiate bridge type fails a large number of times. */
+	/* Make the roads look nicer */
+	rcmd = CleanUpRoadBits(tile, rcmd);
+	if (rcmd == ROAD_NONE) return;
+
+	if (GrowTownWithBridge(t1, tile, rcmd)) return;
+
+	GrowTownWithRoad(t1, tile, rcmd);
 }
 
 /** Returns "growth" if a house was built, or no if the build failed.
@@ -1114,7 +1141,7 @@
 	/* Special case.
 	 * @see GrowTownInTile Check the else if
 	 */
-	DiagDirection target_dir = (DiagDirection)5; ///< The direction in which we want to extend the town
+	DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
 
 	TILE_ASSERT(tile);
 
@@ -1137,7 +1164,7 @@
 	}
 
 	do {
-		RoadBits cur_rb = GetTownRoadBits(tile); ///< The RoadBits of the current tile
+		RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
 
 		/* Try to grow the town from this point */
 		GrowTownInTile(&tile, cur_rb, target_dir, t);
@@ -1151,12 +1178,12 @@
 		/* Select a random bit from the blockmask, walk a step
 		 * and continue the search from there. */
 		do target_dir = RandomDiagDir(); while (!(cur_rb & DiagDirToRoadBits(target_dir)));
-		tile = AddDiagDirToTileIndex(tile, target_dir);
+		tile = TileAddByDiagDir(tile, target_dir);
 
 		if (IsTileType(tile, MP_ROAD)) {
 			/* Don't allow building over roads of other cities */
 			if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) {
-				_grow_town_result = -1;
+				_grow_town_result = GROWTH_SUCCEED;
 			} 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) */
@@ -1220,7 +1247,7 @@
 	PlayerID old_player = _current_player;
 	_current_player = OWNER_TOWN;
 
-	TileIndex tile = t->xy; ///< The tile we are working with ATM
+	TileIndex tile = t->xy; // The tile we are working with ATM
 
 	/* Find a road that we can base the construction on. */
 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
@@ -1994,6 +2021,9 @@
 
 static void TownActionBuyRights(Town* t)
 {
+	/* Check if it's allowed to by the rights */
+	if (!_patches.exclusive_rights) return;
+
 	t->exclusive_counter = 12;
 	t->exclusivity = _current_player;
 
@@ -2110,8 +2140,8 @@
 	/** Towns are processed every TOWN_GROWTH_FREQUENCY ticks, and this is the
 	 * number of times towns are processed before a new building is built. */
 	static const uint16 _grow_count_values[2][6] = {
-		{ 120, 120, 120, 100,  80,  60 }, ///< Fund new buildings has been activated
-		{ 320, 420, 300, 220, 160, 100 }  ///< Normal values
+		{ 120, 120, 120, 100,  80,  60 }, // Fund new buildings has been activated
+		{ 320, 420, 300, 220, 160, 100 }  // Normal values
 	};
 
 	if (t->fund_buildings_months != 0) {
@@ -2252,9 +2282,9 @@
 /* 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
+	{  0, 128, 384}, // Permissive
+	{ 48, 192, 480}, // Neutral
+	{ 96, 384, 768}, // Hostile
 };
 
 bool CheckforTownRating(uint32 flags, Town *t, byte type)
@@ -2499,4 +2529,7 @@
 {
 	memset(&_house_specs, 0, sizeof(_house_specs));
 	memcpy(&_house_specs, &_original_house_specs, sizeof(_original_house_specs));
+
+	/* Reset any overrides that have been set. */
+	_house_mngr.ResetOverride();
 }
--- a/src/town_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/town_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -20,19 +20,49 @@
 #include "variables.h"
 #include "helpers.hpp"
 
+enum TownAuthorityWidget {
+	TWA_CLOSEBOX = 0,
+	TWA_CAPTION,
+	TWA_RATING_INFO,
+	TWA_COMMAND_LIST,
+	TWA_SCROLLBAR,
+	TWA_ACTION_INFO,
+	TWA_EXECUTE,
+};
+
 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},
+{   WWT_CLOSEBOX,   RESIZE_NONE,    13,     0,    10,     0,    13, STR_00C5,                 STR_018B_CLOSE_WINDOW},              // TWA_CLOSEBOX
+{    WWT_CAPTION,   RESIZE_NONE,    13,    11,   316,     0,    13, STR_2022_LOCAL_AUTHORITY, STR_018C_WINDOW_TITLE_DRAG_THIS},    // TWA_CAPTION
+{      WWT_PANEL,   RESIZE_NONE,    13,     0,   316,    14,   105, 0x0,                      STR_NULL},                           // TWA_RATING_INFO
+{      WWT_PANEL,   RESIZE_NONE,    13,     0,   304,   106,   157, 0x0,                      STR_2043_LIST_OF_THINGS_TO_DO_AT},   // TWA_COMMAND_LIST
+{  WWT_SCROLLBAR,   RESIZE_NONE,    13,   305,   316,   106,   157, 0x0,                      STR_0190_SCROLL_BAR_SCROLLS_LIST},   // TWA_SCROLLBAR
+{      WWT_PANEL,   RESIZE_NONE,    13,     0,   316,   158,   209, 0x0,                      STR_NULL},                           // TWA_ACTION_INFO
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,    13,     0,   316,   210,   221, STR_2042_DO_IT,           STR_2044_CARRY_OUT_THE_HIGHLIGHTED}, // TWA_EXECUTE
 {   WIDGETS_END},
 };
 
 extern const byte _town_action_costs[8];
 
+enum TownActions {
+	TACT_NONE             = 0x00,
+
+	TACT_ADVERTISE_SMALL  = 0x01,
+	TACT_ADVERTISE_MEDIUM = 0x02,
+	TACT_ADVERTISE_LARGE  = 0x04,
+	TACT_ROAD_REBUILD     = 0x08,
+	TACT_BUILD_STATUE     = 0x10,
+	TACT_FOUND_BUILDINGS  = 0x20,
+	TACT_BUY_RIGHTS       = 0x40,
+	TACT_BRIBE            = 0x80,
+
+	TACT_ADVERTISE        = TACT_ADVERTISE_SMALL | TACT_ADVERTISE_MEDIUM | TACT_ADVERTISE_LARGE,
+	TACT_CONSTRUCTION     = TACT_ROAD_REBUILD | TACT_BUILD_STATUE | TACT_FOUND_BUILDINGS,
+	TACT_FUNDS            = TACT_BUY_RIGHTS | TACT_BRIBE,
+	TACT_ALL              = TACT_ADVERTISE | TACT_CONSTRUCTION | TACT_FUNDS,
+};
+
+DECLARE_ENUM_AS_BIT_SET(TownActions);
+
 /** 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
@@ -41,41 +71,38 @@
  */
 uint GetMaskOfTownActions(int *nump, PlayerID pid, const Town *t)
 {
-	Money 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;
+	TownActions buttons = TACT_NONE;
 
-		/* 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
-			}
-		}
+	/* Spectators and unwanted have no options */
+	if (pid != PLAYER_SPECTATOR && !(_patches.bribe && t->unwanted[pid])) {
 
 		/* Things worth more than this are not shown */
-		avail = GetPlayer(pid)->player_money + _price.station_value * 200;
-		ref = _price.build_industry >> 8;
+		Money avail = GetPlayer(pid)->player_money + _price.station_value * 200;
+		Money 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);
+		/* Check the action bits for validity and
+		 * if they are valid add them */
+		for (uint i = 0; i != lengthof(_town_action_costs); i++) {
+			const TownActions cur = (TownActions)(1 << i);
+
+			/* Is the player not able to bribe ? */
+			if (cur == TACT_BRIBE && (!_patches.bribe || t->ratings[pid] >= RATING_BRIBE_MAXIMUM))
+				continue;
+
+			/* Is the player not able to buy exclusive rights ? */
+			if (cur == TACT_BUY_RIGHTS && !_patches.exclusive_rights)
+				continue;
+
+			/* Is the player not able to build a statue ? */
+			if (cur == TACT_BUILD_STATUE && HASBIT(t->statues, pid))
+				continue;
+
+			if (avail >= _town_action_costs[i] * ref) {
+				buttons |= cur;
 				num++;
 			}
 		}
-
-		/* Disable build statue if already built */
-		if (HASBIT(t->statues, pid)) {
-			CLRBIT(buttons, 4);
-			num--;
-		}
-
 	}
 
 	if (nump != NULL) *nump = num;
@@ -161,9 +188,9 @@
 				y += 10;
 			}
 			for (i = 0; buttons; i++, buttons >>= 1) {
-				if (pos <= -5) break;
+				if (pos <= -5) break; ///< Draw only the 5 fitting lines
 
-				if (buttons&1 && --pos < 0) {
+				if ((buttons & 1) && --pos < 0) {
 					DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, 6);
 					y += 10;
 				}
@@ -185,7 +212,7 @@
 	case WE_DOUBLE_CLICK:
 	case WE_CLICK:
 		switch (e->we.click.widget) {
-		case 3: { /* listbox */
+		case TWA_COMMAND_LIST: {
 			const Town *t = GetTown(w->window_number);
 			int y = (e->we.click.pt.y - 0x6B) / 10;
 
@@ -200,7 +227,7 @@
 			if (e->event != WE_DOUBLE_CLICK || y < 0) break;
 		}
 
-		case 6: { /* carry out the action */
+		case TWA_EXECUTE: {
 			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;
 		}
--- a/src/train_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/train_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -194,7 +194,7 @@
 
 		if (!IsArticulatedPart(u)) {
 			/* Check powered wagon / visual effect callback */
-			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) {
+			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_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;
@@ -1626,7 +1626,7 @@
 	if (p2) {
 		/* turn a single unit around */
 
-		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
+		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
 		}
 
@@ -1717,7 +1717,7 @@
 		if (v->cargo_cap != 0) {
 			uint16 amount = CALLBACK_FAILED;
 
-			if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
+			if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
 				/* Back up the vehicle's cargo type */
 				CargoID temp_cid = v->cargo_type;
 				byte temp_subtype = v->cargo_subtype;
--- a/src/train_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/train_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -54,7 +54,7 @@
 	v = GetVehicle(_new_vehicle_id);
 	if (tile == _backup_orders_tile) {
 		_backup_orders_tile = 0;
-		RestoreVehicleOrders(v, _backup_orders_data);
+		RestoreVehicleOrders(v);
 	}
 	ShowVehicleViewWindow(v);
 }
--- a/src/tunnelbridge_cmd.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/tunnelbridge_cmd.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -256,7 +256,7 @@
 	if (IsSteepSlope(tileh_end)) z_end += TILE_HEIGHT;
 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh_end)) z_end += TILE_HEIGHT;
 
-	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
+	if (z_start != z_end) return_cmd_error(STR_BRIDGEHEADS_NOT_SAME_HEIGHT);
 
 	/* Towns are not allowed to use bridges on slopes. */
 	allow_on_slopes = ( _current_player != OWNER_TOWN && _patches.build_on_slopes);
@@ -366,7 +366,7 @@
 	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 (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) return_cmd_error(STR_BRIDGE_TOO_LOW_FOR_TERRAIN);
 
 		if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile) && !replace_bridge) {
 			/* Disallow crossing bridges for the time being */
@@ -531,29 +531,12 @@
 
 	/* slope of end tile must be complementary to the slope of the start tile */
 	if (end_tileh != ComplementSlope(start_tileh)) {
-		/*
-		 * A lot of things can be autosloped, but then there is still a structure with
-		 * on top of a tunnel entrance which is bad. Therefor we disallow those.
-		 * Furthermore half road bits (not tram bits) can always be removed, so we
-		 * need to preserve that behaviour here too.
-		 */
-		switch (GetTileType(end_tile)) {
-			default: return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
+		/* Check if there is a structure on the terraformed tile. Do not add the cost, that will be done by the terraforming */
+		ret = DoCommand(end_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR);
+		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
 
-			/* Tiles that can be (safely) "auto" terraformed for tunnels */
-			case MP_ROAD:
-				if (GetRoadTileType(end_tile) != ROAD_TILE_NORMAL ||       // Depots and crossings can't be removed
-						(GetRoadTypes(end_tile) & ROADTYPES_TRAMHWAY) != 0 ||      // Half tram bits must not be removed
-						COUNTBITS(GetRoadBits(end_tile, ROADTYPE_ROAD)) > 1) { // Non-half road bits must not be removed either
-					return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
-				}
-				/* FALL THROUGH */
-			case MP_CLEAR:
-			case MP_TREES:
-				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);
-				break;
-		}
+		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;
--- a/src/variables.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/variables.h	Sat Oct 06 22:30:24 2007 +0000
@@ -241,6 +241,11 @@
 	bool timetable_in_ticks; ///< Whether to show the timetable in ticks rather than days.
 
 	bool autoslope;          ///< Allow terraforming under things.
+
+	bool mod_road_rebuild;   ///< Roadworks remove unneccesary RoadBits
+
+	bool exclusive_rights;   ///< allow buying exclusive rights
+	bool give_money;         ///< allow giving other players money
 };
 
 VARDEF Patches _patches;
@@ -334,6 +339,8 @@
 
 extern const TileTypeProcs * const _tile_type_procs[16];
 
+extern bool _draw_bounding_boxes;
+
 /* misc */
 VARDEF char _screenshot_name[128];
 VARDEF byte _vehicle_design_names;
--- a/src/vehicle.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/vehicle.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -2619,7 +2619,7 @@
 	SpriteID map = PAL_NONE;
 
 	/* Check if we should use the colour map callback */
-	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) {
+	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_VEHICLE_COLOUR_REMAP)) {
 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
 		/* A return value of 0xC000 is stated to "use the default two-color
 		 * maps" which happens to be the failure action too... */
--- a/src/vehicle_gui.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/vehicle_gui.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -208,7 +208,7 @@
 			if (!HASBIT(cmask, cid)) continue;
 
 			/* Check the vehicle's callback mask for cargo suffixes */
-			if (HASBIT(callbackmask, CBM_CARGO_SUFFIX)) {
+			if (HASBIT(callbackmask, CBM_VEHICLE_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;
--- a/src/viewport.cpp	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/viewport.cpp	Sat Oct 06 22:30:24 2007 +0000
@@ -66,6 +66,7 @@
 struct TileSpriteToDraw {
 	SpriteID image;
 	SpriteID pal;
+	const SubSprite *sub;           ///< only draw a rectangular part of the sprite
 	TileSpriteToDraw *next;
 	int32 x;
 	int32 y;
@@ -75,6 +76,7 @@
 struct ChildScreenSpriteToDraw {
 	SpriteID image;
 	SpriteID pal;
+	const SubSprite *sub;           ///< only draw a rectangular part of the sprite
 	int32 x;
 	int32 y;
 	ChildScreenSpriteToDraw *next;
@@ -83,6 +85,7 @@
 struct ParentSpriteToDraw {
 	SpriteID image;                 ///< sprite to draw
 	SpriteID pal;                   ///< palette to use
+	const SubSprite *sub;           ///< only draw a rectangular part of the sprite
 
 	int32 x;                        ///< screen X coordinate of sprite
 	int32 y;                        ///< screen Y coordinate of sprite
@@ -428,7 +431,18 @@
 	InvalidateWidget(w, widget_zoom_out);
 }
 
-void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z)
+/**
+ * Draws a ground sprite at a specific world-coordinate.
+ *
+ * @param image the image to draw.
+ * @param pal the provided palette.
+ * @param x position x of the sprite.
+ * @param y position y of the sprite.
+ * @param z position z of the sprite.
+ * @param sub Only draw a part of the sprite.
+ *
+ */
+void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub)
 {
 	ViewportDrawer *vd = _cur_vd;
 	TileSpriteToDraw *ts;
@@ -445,6 +459,7 @@
 
 	ts->image = image;
 	ts->pal = pal;
+	ts->sub = sub;
 	ts->next = NULL;
 	ts->x = x;
 	ts->y = y;
@@ -453,14 +468,22 @@
 	vd->last_tile = &ts->next;
 }
 
-void DrawGroundSprite(SpriteID image, SpriteID pal)
+/**
+ * Draws a ground sprite for the current tile.
+ * If the current tile is drawn on top of a foundation the sprite is added as child sprite to the "foundation"-ParentSprite.
+ *
+ * @param image the image to draw.
+ * @param pal the provided palette.
+ * @param sub Only draw a part of the sprite.
+ */
+void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub)
 {
 	if (_offset_ground_sprites) {
 		/* offset ground sprite because of foundation? */
-		AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
+		AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y, false, sub);
 	} else {
 		_added_tile_sprite = true;
-		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z);
+		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z, sub);
 	}
 }
 
@@ -472,7 +495,18 @@
 	_offset_ground_sprites = true;
 }
 
-static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z)
+/**
+ * Adds a child sprite to a parent sprite.
+ * In contrast to "AddChildSpriteScreen()" the sprite position is in world coordinates
+ *
+ * @param image the image to draw.
+ * @param pal the provided palette.
+ * @param x position x of the sprite.
+ * @param y position y of the sprite.
+ * @param z position z of the sprite.
+ * @param sub Only draw a part of the sprite.
+ */
+static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z, const SubSprite *sub)
 {
 	const ViewportDrawer *vd = _cur_vd;
 	Point pt = RemapCoords(x, y, z);
@@ -484,17 +518,18 @@
 			pt.y + spr->y_offs + spr->height <= vd->dpi.top)
 		return;
 
-	AddChildSpriteScreen(image, pal, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top);
+	AddChildSpriteScreen(image, pal, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top, false, sub);
 }
 
 /** Draw a (transparent) sprite at given coordinates with a given bounding box.
  * The bounding box extends from (x + bb_offset_x, y + bb_offset_y, z + bb_offset_z) to (x + w - 1, y + h - 1, z + dz - 1), both corners included.
+ * Bounding boxes with bb_offset_x == w or bb_offset_y == h or bb_offset_z == dz are allowed and produce thin slices.
  *
  * @note Bounding boxes are normally specified with bb_offset_x = bb_offset_y = bb_offset_z = 0. The extent of the bounding box in negative direction is
  *       defined by the sprite offset in the grf file.
  *       However if modifying the sprite offsets is not suitable (e.g. when using existing graphics), the bounding box can be tuned by bb_offset.
  *
- * @pre w > bb_offset_x, h > bb_offset_y, dz > bb_offset_z. Else w, h or dz are ignored.
+ * @pre w >= bb_offset_x, h >= bb_offset_y, dz >= bb_offset_z. Else w, h or dz are ignored.
  *
  * @param image the image to combine and draw,
  * @param pal the provided palette,
@@ -508,13 +543,14 @@
  * @param bb_offset_x bounding box extent towards negative X (world),
  * @param bb_offset_y bounding box extent towards negative Y (world),
  * @param bb_offset_z bounding box extent towards negative Z (world)
+ * @param sub Only draw a part of the sprite.
  */
-void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z)
+void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
 {
 	ViewportDrawer *vd = _cur_vd;
 	ParentSpriteToDraw *ps;
 	Point pt;
-	int32 right, bottom;
+	int32 left, right, top, bottom;
 
 	assert((image & SPRITE_MASK) < MAX_SPRITES);
 
@@ -525,7 +561,7 @@
 	}
 
 	if (vd->combine_sprites == 2) {
-		AddCombinedSprite(image, pal, x, y, z);
+		AddCombinedSprite(image, pal, x, y, z, sub);
 		return;
 	}
 
@@ -551,22 +587,32 @@
 	pt = RemapCoords(x, y, z);
 	ps->x = pt.x;
 	ps->y = pt.y;
+
+	/* Compute screen extents of sprite */
 	if (image == SPR_EMPTY_BOUNDING_BOX) {
-		ps->left = RemapCoords(x + w          , y + bb_offset_y, z + bb_offset_z).x;
-		right    = RemapCoords(x + bb_offset_x, y + h          , z + bb_offset_z).x;
-		ps->top  = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y;
-		bottom   = RemapCoords(x + w          , y + h          , z + bb_offset_z).y;
+		left = ps->left = RemapCoords(x + w          , y + bb_offset_y, z + bb_offset_z).x;
+		right           = RemapCoords(x + bb_offset_x, y + h          , z + bb_offset_z).x + 1;
+		top  = ps->top  = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y;
+		bottom          = RemapCoords(x + w          , y + h          , z + bb_offset_z).y + 1;
 	} else {
 		const Sprite *spr = GetSprite(image & SPRITE_MASK);
-		ps->left = (pt.x += spr->x_offs);
-		right    = (pt.x +  spr->width );
-		ps->top  = (pt.y += spr->y_offs);
-		bottom   = (pt.y +  spr->height);
+		left = ps->left = (pt.x += spr->x_offs);
+		right           = (pt.x +  spr->width );
+		top  = ps->top  = (pt.y += spr->y_offs);
+		bottom          = (pt.y +  spr->height);
 	}
-	if (ps->left >= vd->dpi.left + vd->dpi.width ||
-	    right    <= vd->dpi.left ||
-	    ps->top  >= vd->dpi.top + vd->dpi.height ||
-	    bottom   <= vd->dpi.top) {
+	if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) {
+		/* Compute maximal extents of sprite and it's bounding box */
+		left   = min(left  , RemapCoords(x + w          , y + bb_offset_y, z + bb_offset_z).x);
+		right  = max(right , RemapCoords(x + bb_offset_x, y + h          , z + bb_offset_z).x + 1);
+		top    = min(top   , RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y);
+		bottom = max(bottom, RemapCoords(x + w          , y + h          , z + bb_offset_z).y + 1);
+	}
+	/* Do not add the sprite to the viewport, if it is outside */
+	if (left   >= vd->dpi.left + vd->dpi.width ||
+	    right  <= vd->dpi.left ||
+	    top    >= vd->dpi.top + vd->dpi.height ||
+	    bottom <= vd->dpi.top) {
 		return;
 	}
 
@@ -574,14 +620,15 @@
 
 	ps->image = image;
 	ps->pal = pal;
+	ps->sub = sub;
 	ps->xmin = x + bb_offset_x;
-	ps->xmax = x + max(bb_offset_x, w - 1);
+	ps->xmax = x + max(bb_offset_x, w) - 1;
 
 	ps->ymin = y + bb_offset_y;
-	ps->ymax = y + max(bb_offset_y, h - 1);
+	ps->ymax = y + max(bb_offset_y, h) - 1;
 
 	ps->zmin = z + bb_offset_z;
-	ps->zmax = z + max(bb_offset_z, dz - 1);
+	ps->zmax = z + max(bb_offset_z, dz) - 1;
 
 	ps->comparison_done = false;
 	ps->child = NULL;
@@ -602,19 +649,36 @@
 	_cur_vd->combine_sprites = 0;
 }
 
-void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y)
+/**
+ * Add a child sprite to a parent sprite.
+ *
+ * @param image the image to draw.
+ * @param pal the provided palette.
+ * @param x sprite x-offset (screen coordinates) relative to parent sprite.
+ * @param y sprite y-offset (screen coordinates) relative to parent sprite.
+ * @param transparent if true, switch the palette between the provided palette and the transparent palette,
+ * @param sub Only draw a part of the sprite.
+ */
+void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent, const SubSprite *sub)
 {
 	ViewportDrawer *vd = _cur_vd;
 	ChildScreenSpriteToDraw *cs;
 
 	assert((image & SPRITE_MASK) < MAX_SPRITES);
 
+	/* make the sprites transparent with the right palette */
+	if (transparent) {
+		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+		pal = PALETTE_TO_TRANSPARENT;
+	}
+
 	if (vd->spritelist_mem >= vd->eof_spritelist_mem) {
 		DEBUG(sprite, 0, "Out of sprite memory");
 		return;
 	}
 	cs = (ChildScreenSpriteToDraw*)vd->spritelist_mem;
 
+	/* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */
 	if (vd->last_child == NULL) return;
 
 	vd->spritelist_mem += sizeof(ChildScreenSpriteToDraw);
@@ -624,6 +688,7 @@
 
 	cs->image = image;
 	cs->pal = pal;
+	cs->sub = sub;
 	cs->x = x;
 	cs->y = y;
 	cs->next = NULL;
@@ -667,6 +732,17 @@
 	}
 }
 
+/**
+ * Draws a selection rectangle on a tile.
+ *
+ * @param ti TileInfo Tile that is being drawn
+ * @param pal Palette to apply.
+ */
+static void DrawTileSelectionRect(const TileInfo *ti, SpriteID pal)
+{
+	DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], pal, ti);
+}
+
 static bool IsPartOfAutoLine(int px, int py)
 {
 	px -= _thd.selstart.x;
@@ -700,17 +776,38 @@
 #include "table/autorail.h"
 
 /**
+ * Draws autorail highlights.
+ *
+ * @param *ti TileInfo Tile that is being drawn
+ * @param autorail_type Offset into _AutorailTilehSprite[][]
+ */
+static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type)
+{
+	SpriteID image;
+	SpriteID pal;
+	int offset;
+
+	offset = _AutorailTilehSprite[ti->tileh][autorail_type];
+	if (offset >= 0) {
+		image = SPR_AUTORAIL_BASE + offset;
+		pal = PAL_NONE;
+	} else {
+		image = SPR_AUTORAIL_BASE - offset;
+		pal = PALETTE_SEL_TILE_RED;
+	}
+
+	DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
+}
+
+/**
  * Checks if the specified tile is selected and if so draws selection using correct selectionstyle.
  * @param *ti TileInfo Tile that is being drawn
  */
 static void DrawTileSelection(const TileInfo *ti)
 {
-	SpriteID image;
-	SpriteID pal;
-
 	/* Draw a red error square? */
 	if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
-		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti);
+		DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING);
 		return;
 	}
 
@@ -721,8 +818,7 @@
 	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];
-			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti);
+			DrawTileSelectionRect(ti, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE);
 		} else if (_thd.drawstyle & HT_POINT) {
 			/* Figure out the Z coordinate for the single dot. */
 			byte z = ti->z;
@@ -734,25 +830,12 @@
 		} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
 			/* autorail highlight piece under cursor */
 			uint type = _thd.drawstyle & 0xF;
-			int offset;
-
 			assert(type <= 5);
-
-			offset = _AutorailTilehSprite[ti->tileh][_AutorailType[type][0]];
-			if (offset >= 0) {
-				image = SPR_AUTORAIL_BASE + offset;
-				pal = PAL_NONE;
-			} else {
-				image = SPR_AUTORAIL_BASE - offset;
-				pal = PALETTE_TO_RED;
-			}
-
-			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
+			DrawAutorailSelection(ti, _AutorailType[type][0]);
 
 		} else if (IsPartOfAutoLine(ti->x, ti->y)) {
 			/* autorail highlighting long line */
 			int dir = _thd.drawstyle & ~0xF0;
-			int offset;
 			uint side;
 
 			if (dir < 2) {
@@ -762,16 +845,7 @@
 				side = delta(delta(TileX(start), TileX(ti->tile)), delta(TileY(start), TileY(ti->tile)));
 			}
 
-			offset = _AutorailTilehSprite[ti->tileh][_AutorailType[dir][side]];
-			if (offset >= 0) {
-				image = SPR_AUTORAIL_BASE + offset;
-				pal = PAL_NONE;
-			} else {
-				image = SPR_AUTORAIL_BASE - offset;
-				pal = PALETTE_TO_RED;
-			}
-
-			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
+			DrawAutorailSelection(ti, _AutorailType[dir][side]);
 		}
 		return;
 	}
@@ -782,7 +856,7 @@
 			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(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti);
+		DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE);
 		return;
 	}
 }
@@ -1152,7 +1226,7 @@
 {
 	do {
 		Point pt = RemapCoords(ts->x, ts->y, ts->z);
-		DrawSprite(ts->image, ts->pal, pt.x, pt.y);
+		DrawSprite(ts->image, ts->pal, pt.x, pt.y, ts->sub);
 		ts = ts->next;
 	} while (ts != NULL);
 }
@@ -1223,14 +1297,34 @@
 		const ParentSpriteToDraw* ps = *psd;
 		const ChildScreenSpriteToDraw* cs;
 
-		if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y);
+		if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y, ps->sub);
 
 		for (cs = ps->child; cs != NULL; cs = cs->next) {
-			DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y);
+			DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub);
 		}
 	}
 }
 
+/**
+ * Draws the bounding boxes of all ParentSprites
+ * @param psd Array of ParentSprites
+ */
+static void ViewportDrawBoundingBoxes(ParentSpriteToDraw *psd[])
+{
+	for (; *psd != NULL; psd++) {
+		const ParentSpriteToDraw* ps = *psd;
+		Point pt1 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmax + 1); // top front corner
+		Point pt2 = RemapCoords(ps->xmin    , ps->ymax + 1, ps->zmax + 1); // top left corner
+		Point pt3 = RemapCoords(ps->xmax + 1, ps->ymin    , ps->zmax + 1); // top right corner
+		Point pt4 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmin    ); // bottom front corner
+
+		DrawBox(        pt1.x,         pt1.y,
+		        pt2.x - pt1.x, pt2.y - pt1.y,
+		        pt3.x - pt1.x, pt3.y - pt1.y,
+		        pt4.x - pt1.x, pt4.y - pt1.y);
+	}
+}
+
 static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss)
 {
 	DrawPixelInfo dp;
@@ -1354,6 +1448,7 @@
 
 	ViewportSortParentSprites(parent_list);
 	ViewportDrawParentSprites(parent_list);
+	if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(parent_list);
 
 	if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);
 
--- a/src/viewport.h	Sun Sep 23 07:37:38 2007 +0000
+++ b/src/viewport.h	Sat Oct 06 22:30:24 2007 +0000
@@ -57,11 +57,11 @@
 
 void OffsetGroundSprite(int x, int y);
 
-void DrawGroundSprite(SpriteID image, SpriteID pal);
-void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z);
-void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0);
+void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub = NULL);
+void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub = NULL);
+void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0, const SubSprite *sub = NULL);
 void *AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint64 params_2);
-void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y);
+void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent = false, const SubSprite *sub = NULL);
 
 
 void StartSpriteCombine();