[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#683376: unblock: openttd/1.2.2-1 or openttd/1.2.1-2



Hi Julien and others,

here's a new debdiff, made against the 1.2.2 release. I've filtered out
the irrelevant stuff (translations, documentation, packaging for other
os's, svn $Id keyword changes, version number changes, constant value
changes).

Upstream has kindly added some extra annotations to the debdiff,
separating out some of the bigger or important changes.

The upstream changelog for this version is:

- Fix: In some cases ships could be covered with land [CVE-2012-3436] [FS#5254] (r24449, r24439)
- Fix: Copy constructor and assignment operator cannot be implicit template specialisations [FS#5255] (r24448)
- Fix: Make (non-refittable) vehicles with invalid default cargo unavailable [FS#5256] (r24438)
- Fix: CFLAGS/CXXFLAGS ignored for helper binaries (r24432, r24429, r24427, r24365)
- Fix: [Windows] Unbreak NewGRF MD5 sum calculation. Macros and side effects do not mix, especially if there is some obscure '#define min' in a windows header that nobody thinks of [FS#5231] (r24416)
- Fix: Disallow removing roadtypes from bridges when not dragging in bridge direction [FS#5221] (r24414)
- Fix: Draw wires under low bridges if the bridge is transparent, not if the wire is transparent (r24403)
- Fix: Station properties 11 and 14 were combined incorrectly [FS#5243] (r24402)
- Fix: [Windows] Changing resolution did not resize the window (r24394)
- Fix: Use the 'all vehicles' group for the autoreplace window from the vehicle list [FS#5239] (r24392)
- Fix: Do not consider not finding a particular base set critical; just load a different one and display an in-game error later on [FS#5233] (r24388)
- Fix: Make IsInDepot() functions behave consistent across vehicle types and add IsChainInDepot instead, if that is what shall be checked [FS#5188] (r24384)
- Fix: Call Vehicle::IsStoppedInDepot only for the first vehicle in a chain (i.e. primary vehicle or free wagon) (r24382)
- Fix: Do not resize the object GUI when selecting objects. Rather clip the object name (r24379)
- Fix: ReInit could crash for windows with NWidgetMatrix widgets [FS#5218] (r24378)
- Fix: [NewGRF] Extended action A1 did not work correctly [FS#5227] (r24369, r24361)
- Fix: [NewGRF] Ship-specific 80+x variables were missing for unknown reason [FS#5224] (r24360)
- Fix: When airport construction was denied due to noise, the error message named the wrong town (r24354)
- Fix: [NoAI] A TileIndex is not a station id, so do not use it as one [FS#5215] (r24353)
- Fix: When highlighting the drop position for vehicles in depots, make space for all articulated parts (r24352)
- Fix: Short vehicles were not properly positioned at the cursor when dragging for RTL languages (r24351)
- Fix: EQUALSIZE widget containers within EQUALSIZE containers were initialised with wrong sizes (r24346)
- Fix: The cursor in the company password window was not blinking due to wrong magic constants (r24335)
- Fix: [NewGRF] Change the length of 8/8 roadvehicles in vehicle lists to 32 pixels; this is in fact the correct length as can be seen in corners for short articulated parts following each other [FS#2553] (r24332)
- Fix: [NewGRF] Group vehicles in the purchase list properly by source GRF, but also consider engine GRFID overrides [FS#4254] (r24330, r24321)
- Fix: Make the AI settings window behave more like the other settings window by closing the query window whenever selecting a different row (r24315)
- Fix: Editing NewGRF parameters using the query window showed wrong values, if there was no direct relation between parameter index and parameter register (r24314)
- Fix: Center object previews in 1- and 2-view selectors based on the 4-view selector layout [FS#5057] (r24299)
- Fix: Increase the left and right margins of the text in the yes/no query window (r24293)
- Fix: [NewGRF] GetReverseCargoTranslation() was unnecessary complicated and also returned the wrong thing for cargos not present in the translation table (r24273)
- Fix: [NewGRF] Load cargo- and railtype-translation during both reservation and activation stage. That way they can be selected using Action7 depending on present cargo- or railtypes (r24272)
- Fix: Use the same colour scheme for the script selection window as in other comparable windows (r24268)
- Fix: Make the oilrig-vehicle list accessible to spectators and colour its caption neutrally grey [FS#5126] (r24260)

For ease of comparison, I've also attached the debdiff for the 1.2.1-2
CVE-bugfix-backport option. This debdiff is identical to the one I
linked to before.

Thanks,

Matthijs
File lists identical (after any substitutions)

Control files of package openttd: lines which differ (wdiff format)
-------------------------------------------------------------------
Depends: libc6 (>= 2.11), libfontconfig1 (>= [-2.8.0),-] {+2.9.0),+} libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libicu48 (>= 4.8-1), liblzma5 (>= [-5.1.1alpha+20110809),-] {+5.1.1alpha+20120614),+} liblzo2-2, libpng12-0 (>= 1.2.13-4), libsdl1.2debian (>= 1.2.11), libstdc++6 (>= 4.6), zlib1g (>= 1:1.1.4), openttd-data (= [-1.2.1-1)-] {+1.2.1-2)+}
Installed-Size: [-5654-] {+5685+}
Version: [-1.2.1-1-] {+1.2.1-2+}

Control files of package openttd-data: lines which differ (wdiff format)
------------------------------------------------------------------------
Version: [-1.2.1-1-] {+1.2.1-2+}

Control files of package openttd-dbg: lines which differ (wdiff format)
-----------------------------------------------------------------------
Depends: openttd (= [-1.2.1-1)-] {+1.2.1-2)+}
Installed-Size: [-44139-] {+48063+}
Version: [-1.2.1-1-] {+1.2.1-2+}
diff -Nru openttd-1.2.1/debian/changelog openttd-1.2.1/debian/changelog
--- openttd-1.2.1/debian/changelog	2012-06-01 21:24:34.000000000 +0200
+++ openttd-1.2.1/debian/changelog	2012-08-01 23:21:04.000000000 +0200
@@ -1,3 +1,11 @@
+openttd (1.2.1-2) unstable; urgency=high
+
+  * [e7a5026] Fix CVE-2012-3436 (Denial of service using ships on half
+    tiles and landscaping). See
+    http://security.openttd.org/en/CVE-2012-3436 for details.
+
+ -- Matthijs Kooijman <matthijs@stdin.nl>  Wed, 01 Aug 2012 23:20:31 +0200
+
 openttd (1.2.1-1) unstable; urgency=low
 
   * [306c3ac] New upstream release 1.2.1.
diff -Nru openttd-1.2.1/debian/patches/cve-2012-3436.patch openttd-1.2.1/debian/patches/cve-2012-3436.patch
--- openttd-1.2.1/debian/patches/cve-2012-3436.patch	1970-01-01 01:00:00.000000000 +0100
+++ openttd-1.2.1/debian/patches/cve-2012-3436.patch	2012-08-01 23:21:04.000000000 +0200
@@ -0,0 +1,72 @@
+Subject: fix for vulnerability CVE-2012-3436 for OpenTTD 1.2.0 - 1.2.1 (Denial of service (server) using ships on half tiles and landscaping.)
+From: OpenTTD developer team <info@openttd.org>
+Origin: backport, http://vcs.openttd.org/svn/changeset/24439 http://vcs.openttd.org/svn/changeset/24449 
+Bug: http://bugs.openttd.org/task/5254 
+
+Denial of service using ships on half tiles and landscaping.
+
+Simple steps to reproduce the issue, and show the severity:
+ start a new game. For this reproduction you do not need to start a server;
+   you can see the crash locally, but due to the nature of OpenTTD the crash
+   will also happen on the server you're playing on with multiplayer.
+ build some horizontal or vertical track at the coast, so that half of the
+   tile remains water or coast. The tile should either have
+   one corner raised with flat water on one half tile (case 1)
+   or two adjacent corners raised with coast on the sloped half tile (case 2)
+ build a ship depot, a ship and a dock at the coast, and start the ship
+ obstruct the path of the ship in a way so that it enters the tile with half
+   railtrack and half water
+ landscape the tile by raising the water corner while the ship is on it
+   (only needed in case 1)
+ both cases will make the ship end up on land
+ remove the track using the "remove track" tool while the ship is on the tile
+ server segfaults due to NULL pointer dereference.
+
+The problem is caused by incorrectly handling the water/coast aspect of tiles
+which also have railtracks on one half.
+The fix adds the correct checks to the landscaping and movement code.
+
+If you try to reproduce this with the patch applied you'll see that,
+in case 1, step 5 will deny the terraforming and in case 2 the ship simply
+won't try to enter the coast tile.
+
+This bug was triggered incidentally by a user playing online when landscaping
+near a ship. We have not seen any signs of this bug being exploited forcefully.
+
+
+--- a/src/rail_cmd.cpp
++++ b/src/rail_cmd.cpp
+@@ -2604,7 +2604,7 @@
+ static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
+ {
+ 	/* Case of half tile slope with water. */
+-	if (mode == TRANSPORT_WATER && IsPlainRail(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER) {
++	if (mode == TRANSPORT_WATER && IsPlainRail(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(GetTileSlope(tile))) {
+ 		TrackBits tb = GetTrackBits(tile);
+ 		switch (tb) {
+ 			default: NOT_REACHED();
+@@ -2925,6 +2925,14 @@
+ 	return  cost;
+ }
+ 
++/**
++ * Test-procedure for HasVehicleOnPos to check for a ship.
++ */
++static Vehicle *EnsureNoShipProc(Vehicle *v, void *data)
++{
++	return v->type == VEH_SHIP ? v : NULL;
++}
++
+ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
+ {
+ 	int z_old;
+@@ -2934,6 +2942,9 @@
+ 		/* Is there flat water on the lower halftile that must be cleared expensively? */
+ 		bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old));
+ 
++		/* Allow clearing the water only if there is no ship */
++		if (was_water && HasVehicleOnPos(tile, NULL, &EnsureNoShipProc)) return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY);
++
+ 		/* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */
+ 		CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits);
+ 
diff -Nru openttd-1.2.1/debian/patches/series openttd-1.2.1/debian/patches/series
--- openttd-1.2.1/debian/patches/series	2012-06-01 21:24:34.000000000 +0200
+++ openttd-1.2.1/debian/patches/series	2012-08-01 23:21:04.000000000 +0200
@@ -1 +1,2 @@
 run-openttd-wrapper.patch
+cve-2012-3436.patch
File lists identical (after any substitutions)

Control files of package openttd: lines which differ (wdiff format)
-------------------------------------------------------------------
Depends: libc6 (>= 2.11), libfontconfig1 (>= [-2.8.0),-] {+2.9.0),+} libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libicu48 (>= 4.8-1), liblzma5 (>= [-5.1.1alpha+20110809),-] {+5.1.1alpha+20120614),+} liblzo2-2, libpng12-0 (>= 1.2.13-4), libsdl1.2debian (>= 1.2.11), libstdc++6 (>= 4.6), zlib1g (>= 1:1.1.4), openttd-data (= [-1.2.1-1)-] {+1.2.2-1)+}
Installed-Size: [-5654-] {+5686+}
Version: [-1.2.1-1-] {+1.2.2-1+}

Control files of package openttd-data: lines which differ (wdiff format)
------------------------------------------------------------------------
Installed-Size: [-7182-] {+7200+}
Version: [-1.2.1-1-] {+1.2.2-1+}

Control files of package openttd-dbg: lines which differ (wdiff format)
-----------------------------------------------------------------------
Depends: openttd (= [-1.2.1-1)-] {+1.2.2-1)+}
Installed-Size: [-44139-] {+48120+}
Version: [-1.2.1-1-] {+1.2.2-1+}
###############################################################################
# Debian packaging changes
###############################################################################

diff -Nru openttd-1.2.1/debian/changelog openttd-1.2.2/debian/changelog
--- openttd-1.2.1/debian/changelog	2012-06-01 21:24:34.000000000 +0200
+++ openttd-1.2.2/debian/changelog	2012-08-24 21:38:58.000000000 +0200
@@ -1,3 +1,11 @@
+openttd (1.2.2-1) unstable; urgency=high
+
+  * [6aae009] New upstream release 1.2.2.
+  * [de8c2b6] Use dpkg-buildflags for utilities running on the build
+    machine as well.
+
+ -- Matthijs Kooijman <matthijs@stdin.nl>  Fri, 24 Aug 2012 21:27:26 +0200
+
 openttd (1.2.1-1) unstable; urgency=low

   * [306c3ac] New upstream release 1.2.1.
diff -Nru openttd-1.2.1/debian/rules openttd-1.2.2/debian/rules
--- openttd-1.2.1/debian/rules	2012-06-01 21:24:34.000000000 +0200
+++ openttd-1.2.2/debian/rules	2012-08-24 21:38:58.000000000 +0200
@@ -29,7 +29,7 @@
 # to be explicit about the dependencies, in case we're not running in a
 # clean build root.
 override_dh_auto_configure:
-	./configure $(CROSS) --prefix-dir=/usr --install-dir=debian/tmp --without-allegro --with-zlib --with-sdl --with-png --with-freetype --with-fontconfig --with-icu --with-liblzo2 --with-liblzma --without-iconv --disable-strip CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)"
+	./configure $(CROSS) --prefix-dir=/usr --install-dir=debian/tmp --without-allegro --with-zlib --with-sdl --with-png --with-freetype --with-fontconfig --with-icu --with-liblzo2 --with-liblzma --without-iconv --disable-strip CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" CFLAGS_BUILD="$(CFLAGS) $(CPPFLAGS)" LDFLAGS_BUILD="$(LDFLAGS)"

 # Do some extra installation
 override_dh_auto_install:


###############################################################################
# Build system change to allow hardening flags be passed to helper binaries
###############################################################################

diff -Nru openttd-1.2.1/config.lib openttd-1.2.2/config.lib
--- openttd-1.2.1/config.lib	2012-05-31 22:55:16.000000000 +0200
+++ openttd-1.2.2/config.lib	2012-08-16 20:41:43.000000000 +0200
@@ -164,7 +164,7 @@
 		with_ccache
 		with_grfcodec
 		with_nforenum
-	CC CXX CFLAGS CXXFLAGS LDFLAGS"
+	CC CXX CFLAGS CXXFLAGS LDFLAGS CFLAGS_BUILD CXXFLAGS_BUILD LDFLAGS_BUILD"
 }

 detect_params() {
@@ -442,6 +442,9 @@
 			CFLAGS=* | --CFLAGS=*)        CFLAGS="$optarg";;
 			CXXFLAGS=* | --CXXFLAGS=*)    CXXFLAGS="$optarg";;
 			LDFLAGS=* | --LDFLAGS=*)      LDFLAGS="$optarg";;
+			CFLAGS_BUILD=* | --CFLAGS_BUILD=*)     CFLAGS_BUILD="$optarg";;
+			CXXFLAGS_BUILD=* | --CXXFLAGS_BUILD=*) CXXFLAGS_BUILD="$optarg";;
+			LDFLAGS_BUILD=* | --LDFLAGS_BUILD=*)   LDFLAGS_BUILD="$optarg";;

 			--ignore-extra-parameters)    ignore_extra_parameters="1";;

@@ -1386,11 +1389,11 @@

 make_cflags_and_ldflags() {
 	# General CFlags for BUILD
-	CFLAGS_BUILD=""
+	CFLAGS_BUILD="$CFLAGS_BUILD"
 	# Special CXXFlags for BUILD
-	CXXFLAGS_BUILD=""
+	CXXFLAGS_BUILD="$CXXFLAGS_BUILD"
 	# LDFLAGS for BUILD
-	LDFLAGS_BUILD=""
+	LDFLAGS_BUILD="$LDFLAGS_BUILD"
 	# FEATURES for BUILD (lto)
 	FEATURES_BUILD=""
 	# General CFlags for HOST
@@ -1771,6 +1774,7 @@

 	if [ "$enable_assert" = "0" ]; then
 		CFLAGS="$CFLAGS -DNDEBUG"
+		CFLAGS_BUILD="$CFLAGS_BUILD -DNDEBUG"
 	fi

 	if [ "$enable_desync_debug" != "0" ]; then
@@ -1806,6 +1810,9 @@
 		fi
 	fi

+	log 1 "using CFLAGS_BUILD... $CFLAGS_BUILD"
+	log 1 "using CXXFLAGS_BUILD... $CXXFLAGS_BUILD"
+	log 1 "using LDFLAGS_BUILD... $LDFLAGS_BUILD"
 	log 1 "using CFLAGS... $CFLAGS"
 	log 1 "using CXXFLAGS... $CXXFLAGS"
 	log 1 "using LDFLAGS... $LIBS $LDFLAGS"
diff -Nru openttd-1.2.1/Makefile.lang.in openttd-1.2.2/Makefile.lang.in
--- openttd-1.2.1/Makefile.lang.in	2012-05-31 22:55:16.000000000 +0200
+++ openttd-1.2.2/Makefile.lang.in	2012-08-16 20:41:43.000000000 +0200
@@ -14,6 +14,7 @@
 LANGS         = $(LANGS_SRC:$(LANG_DIR)/%.txt=%.lng)
 CXX_BUILD     = !!CXX_BUILD!!
 CFLAGS_BUILD  = !!CFLAGS_BUILD!!
+CXXFLAGS_BUILD= !!CXXFLAGS_BUILD!!
 LDFLAGS_BUILD = !!LDFLAGS_BUILD!!
 STRGEN_FLAGS  = !!STRGEN_FLAGS!!
 STAGE         = !!STAGE!!
@@ -44,23 +45,23 @@

 strgen_base.o: $(SRC_DIR)/strgen/strgen_base.cpp $(SRC_DIR)/strgen/strgen.h endian_host.h $(SRC_DIR)/table/control_codes.h $(SRC_DIR)/table/strgen_tables.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSTRGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $<

 strgen.o: $(SRC_DIR)/strgen/strgen.cpp $(SRC_DIR)/strgen/strgen.h endian_host.h $(SRC_DIR)/table/control_codes.h $(SRC_DIR)/table/strgen_tables.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSTRGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $<

 string.o: $(SRC_DIR)/string.cpp endian_host.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSTRGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $<

 alloc_func.o: $(SRC_DIR)/core/alloc_func.cpp endian_host.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSTRGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $<

 getoptdata.o: $(SRC_DIR)/misc/getoptdata.cpp $(SRC_DIR)/misc/getoptdata.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/misc/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSTRGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $<

 lang/english.txt: $(LANG_DIR)/english.txt
 	$(Q)mkdir -p lang
@@ -68,7 +69,7 @@

 $(STRGEN): alloc_func.o string.o strgen_base.o strgen.o getoptdata.o
 	$(E) '$(STAGE) Compiling and Linking $@'
-	$(Q)$(CXX_BUILD) $(LDFLAGS_BUILD) $^ -o $@
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $^ -o $@

 table/strings.h: lang/english.txt $(STRGEN)
 	$(E) '$(STAGE) Generating $@'
@@ -87,7 +88,7 @@

 $(ENDIAN_CHECK): $(SRC_DIR)/endian_check.cpp
 	$(E) '$(STAGE) Compiling and Linking $@'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $< -o $@
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $< -o $@

 depend:

diff -Nru openttd-1.2.1/Makefile.setting.in openttd-1.2.2/Makefile.setting.in
--- openttd-1.2.1/Makefile.setting.in	2012-05-31 22:55:16.000000000 +0200
+++ openttd-1.2.2/Makefile.setting.in	2012-08-16 20:41:43.000000000 +0200
@@ -10,6 +10,7 @@
 SRC_DIR          = !!SRC_DIR!!
 CXX_BUILD        = !!CXX_BUILD!!
 CFLAGS_BUILD     = !!CFLAGS_BUILD!!
+CXXFLAGS_BUILD   = !!CXXFLAGS_BUILD!!
 LDFLAGS_BUILD    = !!LDFLAGS_BUILD!!
 STAGE            = !!STAGE!!
 SETTING_OBJS_DIR = !!SETTING_OBJS_DIR!!
@@ -29,27 +30,27 @@

 settingsgen.o: $(SRC_DIR)/settingsgen/settingsgen.cpp $(SRC_DIR)/string_func.h $(SRC_DIR)/strings_type.h $(SRC_DIR)/misc/getoptdata.h $(SRC_DIR)/ini_type.h $(SRC_DIR)/core/smallvec_type.hpp
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<

 alloc_func.o: $(SRC_DIR)/core/alloc_func.cpp endian_host.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<

 getoptdata.o: $(SRC_DIR)/misc/getoptdata.cpp $(SRC_DIR)/misc/getoptdata.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/misc/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<

 string.o: $(SRC_DIR)/string.cpp endian_host.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<

 ini_load.o: $(SRC_DIR)/ini_load.cpp $(SRC_DIR)/core/alloc_func.hpp $(SRC_DIR)/core/mem_func.hpp $(SRC_DIR)/ini_type.h $(SRC_DIR)/string_func.h
 	$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $<

 $(SETTINGSGEN): alloc_func.o string.o ini_load.o settingsgen.o getoptdata.o
 	$(E) '$(STAGE) Compiling and Linking $@'
-	$(Q)$(CXX_BUILD) $(LDFLAGS_BUILD) $^ -o $@
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $^ -o $@

 table/settings.h: $(SETTINGSGEN) $(SRC_DIR)/table/settings.h.preamble $(SRC_DIR)/table/settings.h.postamble $(SRC_DIR)/table/*.ini
 	$(E) '$(STAGE) Generating $@'
@@ -64,7 +65,7 @@

 $(ENDIAN_CHECK): $(SRC_DIR)/endian_check.cpp
 	$(E) '$(STAGE) Compiling and Linking $@'
-	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $< -o $@
+	$(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $< -o $@

 depend:


###############################################################################
# CVE-2012-3436
###############################################################################


diff -Nru openttd-1.2.1/src/rail_cmd.cpp openttd-1.2.2/src/rail_cmd.cpp
--- openttd-1.2.1/src/rail_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/rail_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -2604,7 +2604,7 @@
 static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
 {
 	/* Case of half tile slope with water. */
-	if (mode == TRANSPORT_WATER && IsPlainRail(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER) {
+	if (mode == TRANSPORT_WATER && IsPlainRail(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(GetTileSlope(tile))) {
 		TrackBits tb = GetTrackBits(tile);
 		switch (tb) {
 			default: NOT_REACHED();
@@ -2925,6 +2925,14 @@
 	return  cost;
 }

+/**
+ * Test-procedure for HasVehicleOnPos to check for a ship.
+ */
+static Vehicle *EnsureNoShipProc(Vehicle *v, void *data)
+{
+	return v->type == VEH_SHIP ? v : NULL;
+}
+
 static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
 {
 	int z_old;
@@ -2934,6 +2942,9 @@
 		/* Is there flat water on the lower halftile that must be cleared expensively? */
 		bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old));

+		/* Allow clearing the water only if there is no ship */
+		if (was_water && HasVehicleOnPos(tile, NULL, &EnsureNoShipProc)) return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY);
+
 		/* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */
 		CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits);



###############################################################################
# The copy constructor and assignment operator do not work properly with
# implicit template specialisations; invalid sizes and such.
###############################################################################

diff -Nru openttd-1.2.1/src/core/smallvec_type.hpp openttd-1.2.2/src/core/smallvec_type.hpp
--- openttd-1.2.1/src/core/smallvec_type.hpp	2012-05-31 22:55:02.000000000 +0200
+++ openttd-1.2.2/src/core/smallvec_type.hpp	2012-08-16 20:41:36.000000000 +0200
@@ -39,21 +39,39 @@
 	 * Copy constructor.
 	 * @param other The other vector to copy.
 	 */
+	SmallVector(const SmallVector &other) : data(NULL), items(0), capacity(0)
+	{
+		this->Assign(other);
+	}
+
+	/**
+	 * Generic copy constructor.
+	 * @param other The other vector to copy.
+	 */
 	template <uint X>
 	SmallVector(const SmallVector<T, X> &other) : data(NULL), items(0), capacity(0)
 	{
-		MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
+		this->Assign(other);
 	}

 	/**
 	 * Assignment.
-	 * @param other The new vector that.
+	 * @param other The other vector to assign.
+	 */
+	SmallVector &operator=(const SmallVector &other)
+	{
+		this->Assign(other);
+		return *this;
+	}
+
+	/**
+	 * Generic assignment.
+	 * @param other The other vector to assign.
 	 */
 	template <uint X>
 	SmallVector &operator=(const SmallVector<T, X> &other)
 	{
-		this->Reset();
-		MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
+		this->Assign(other);
 		return *this;
 	}

@@ -63,6 +81,18 @@
 	}

 	/**
+	 * Assign items from other vector.
+	 */
+	template <uint X>
+	inline void Assign(const SmallVector<T, X> &other)
+	{
+		if ((const void *)&other == (void *)this) return;
+
+		this->Clear();
+		if (other.Length() > 0) MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
+	}
+
+	/**
 	 * Remove all items from the list.
 	 */
 	inline void Clear()


###############################################################################
# The configuration UIs behaved inconsistently
###############################################################################


diff -Nru openttd-1.2.1/src/ai/ai_gui.cpp openttd-1.2.2/src/ai/ai_gui.cpp
--- openttd-1.2.1/src/ai/ai_gui.cpp	2012-05-31 22:55:02.000000000 +0200
+++ openttd-1.2.2/src/ai/ai_gui.cpp	2012-08-16 20:41:36.000000000 +0200
@@ -431,15 +431,21 @@
 				const ScriptConfigItem config_item = **it;
 				if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;

+				if (this->clicked_row != num) {
+					DeleteChildWindows(WC_QUERY_STRING);
+					this->clicked_row = num;
+				}
+
 				bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0;

 				int x = pt.x - wid->pos_x;
 				if (_current_text_dir == TD_RTL) x = wid->current_x - x;
 				x -= 4;
+
 				/* One of the arrows is clicked (or green/red rect in case of bool value) */
+				int old_val = this->ai_config->GetSetting(config_item.name);
 				if (IsInsideMM(x, 0, 21)) {
-					int new_val = this->ai_config->GetSetting(config_item.name);
-					int old_val = new_val;
+					int new_val = old_val;
 					if (bool_item) {
 						new_val = !new_val;
 					} else if (x >= 10) {
@@ -463,8 +469,7 @@
 					}
 				} else if (!bool_item) {
 					/* Display a query box so users can enter a custom value. */
-					this->clicked_row = num;
-					SetDParam(0, this->ai_config->GetSetting(config_item.name));
+					SetDParam(0, old_val);
 					ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
 				}
 				this->SetDirty();
diff -Nru openttd-1.2.1/src/newgrf_gui.cpp openttd-1.2.2/src/newgrf_gui.cpp
--- openttd-1.2.1/src/newgrf_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -326,9 +326,9 @@
 				if (par_info == NULL) par_info = GetDummyParameterInfo(num);

 				/* One of the arrows is clicked */
+				uint32 old_val = par_info->GetValue(this->grf_config);
 				if (IsInsideMM(x, 0, 21)) {
-					uint32 val = par_info->GetValue(this->grf_config);
-					uint32 old_val = val;
+					uint32 val = old_val;
 					if (par_info->type == PTYPE_BOOL) {
 						val = !val;
 					} else {
@@ -350,7 +350,7 @@
 					}
 				} else if (par_info->type == PTYPE_UINT_ENUM && click_count >= 2) {
 					/* Display a query box so users can enter a custom value. */
-					SetDParam(0, this->grf_config->param[num]);
+					SetDParam(0, old_val);
 					ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
 				}
 				this->SetDirty();


###############################################################################
# Made depot handling consistent wrt to different vehicle types, # could cause a crash
###############################################################################


diff -Nru openttd-1.2.1/src/aircraft_cmd.cpp openttd-1.2.2/src/aircraft_cmd.cpp
--- openttd-1.2.1/src/aircraft_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/aircraft_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -365,7 +365,7 @@
 static void CheckIfAircraftNeedsService(Aircraft *v)
 {
 	if (Company::Get(v->owner)->settings.vehicle.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return;
-	if (v->IsInDepot()) {
+	if (v->IsChainInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
 	}
diff -Nru openttd-1.2.1/src/aircraft.h openttd-1.2.2/src/aircraft.h
--- openttd-1.2.1/src/aircraft.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/aircraft.h	2012-08-16 20:41:43.000000000 +0200
@@ -77,7 +77,13 @@
 	int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; }
 	int GetSpeedOldUnits() const   { return this->vcache.cached_max_speed * 10 / 128; }
 	Money GetRunningCost() const;
-	bool IsInDepot() const { return (this->vehstatus & VS_HIDDEN) != 0 && IsHangarTile(this->tile); }
+
+	bool IsInDepot() const
+	{
+		assert(this->IsPrimaryVehicle());
+		return (this->vehstatus & VS_HIDDEN) != 0 && IsHangarTile(this->tile);
+	}
+
 	bool Tick();
 	void OnNewDay();
 	uint Crash(bool flooded = false);
diff -Nru openttd-1.2.1/src/script/api/script_vehicle.cpp openttd-1.2.2/src/script/api/script_vehicle.cpp
--- openttd-1.2.1/src/script/api/script_vehicle.cpp	2012-05-31 22:55:07.000000000 +0200
+++ openttd-1.2.2/src/script/api/script_vehicle.cpp	2012-08-16 20:41:40.000000000 +0200
@@ -182,7 +182,7 @@
 /* static */ bool ScriptVehicle::IsInDepot(VehicleID vehicle_id)
 {
 	if (!IsValidVehicle(vehicle_id)) return false;
-	return ::Vehicle::Get(vehicle_id)->IsInDepot();
+	return ::Vehicle::Get(vehicle_id)->IsChainInDepot();
 }

 /* static */ bool ScriptVehicle::IsStoppedInDepot(VehicleID vehicle_id)
diff -Nru openttd-1.2.1/src/autoreplace_cmd.cpp openttd-1.2.2/src/autoreplace_cmd.cpp
--- openttd-1.2.1/src/autoreplace_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/autoreplace_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -662,7 +662,7 @@
 	CommandCost ret = CheckOwnership(v->owner);
 	if (ret.Failed()) return ret;

-	if (!v->IsInDepot()) return CMD_ERROR;
+	if (!v->IsChainInDepot()) return CMD_ERROR;
 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;

 	bool free_wagon = false;
@@ -699,7 +699,7 @@
 		if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, true));
 		if (cost.Failed()) return cost;

-		assert(v->IsStoppedInDepot());
+		assert(free_wagon || v->IsStoppedInDepot());

 		/* We have to construct the new vehicle chain to test whether it is valid.
 		 * Vehicle construction needs random bits, so we have to save the random seeds
diff -Nru openttd-1.2.1/src/ground_vehicle.cpp openttd-1.2.2/src/ground_vehicle.cpp
--- openttd-1.2.1/src/ground_vehicle.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/ground_vehicle.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -12,6 +12,7 @@
 #include "stdafx.h"
 #include "train.h"
 #include "roadveh.h"
+#include "depot_map.h"

 /**
  * Recalculates the cached total power of a vehicle. Should be called when the consist is changed.
@@ -164,6 +165,27 @@
 	}
 }

+/**
+ * Check whether the whole vehicle chain is in the depot.
+ * @return true if and only if the whole chain is in the depot.
+ */
+template <class T, VehicleType Type>
+bool GroundVehicle<T, Type>::IsChainInDepot() const
+{
+	const T *v = this->First();
+	/* Is the front engine stationary in the depot? */
+	assert_compile((int)TRANSPORT_RAIL == (int)VEH_TRAIN);
+	assert_compile((int)TRANSPORT_ROAD == (int)VEH_ROAD);
+	if (!IsDepotTypeTile(v->tile, (TransportType)Type) || v->cur_speed != 0) return false;
+
+	/* Check whether the rest is also already trying to enter the depot. */
+	for (; v != NULL; v = v->Next()) {
+		if (!v->T::IsInDepot() || v->tile != this->tile) return false;
+	}
+
+	return true;
+}
+
 /* Instantiation for Train */
 template struct GroundVehicle<Train, VEH_TRAIN>;
 /* Instantiation for RoadVehicle */
diff -Nru openttd-1.2.1/src/ground_vehicle.hpp openttd-1.2.2/src/ground_vehicle.hpp
--- openttd-1.2.1/src/ground_vehicle.hpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/ground_vehicle.hpp	2012-08-16 20:41:43.000000000 +0200
@@ -92,6 +92,7 @@
 	void PowerChanged();
 	void CargoChanged();
 	int GetAcceleration() const;
+	bool IsChainInDepot() const;

 	/**
 	 * Common code executed for crashed ground vehicles
diff -Nru openttd-1.2.1/src/ship_cmd.cpp openttd-1.2.2/src/ship_cmd.cpp
--- openttd-1.2.1/src/ship_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/ship_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -142,7 +142,7 @@
 static void CheckIfShipNeedsService(Vehicle *v)
 {
 	if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
-	if (v->IsInDepot()) {
+	if (v->IsChainInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
 	}
@@ -299,7 +299,7 @@

 static bool CheckShipLeaveDepot(Ship *v)
 {
-	if (!v->IsInDepot()) return false;
+	if (!v->IsChainInDepot()) return false;

 	/* We are leaving a depot, but have to go to the exact same one; re-enter */
 	if (v->current_order.IsType(OT_GOTO_DEPOT) &&
diff -Nru openttd-1.2.1/src/roadveh_cmd.cpp openttd-1.2.2/src/roadveh_cmd.cpp
--- openttd-1.2.1/src/roadveh_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/roadveh_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -306,19 +306,6 @@
 	return CommandCost();
 }

-bool RoadVehicle::IsStoppedInDepot() const
-{
-	TileIndex tile = this->tile;
-
-	if (!IsRoadDepotTile(tile)) return false;
-	if (this->IsFrontEngine() && !(this->vehstatus & VS_STOPPED)) return false;
-
-	for (const RoadVehicle *v = this; v != NULL; v = v->Next()) {
-		if (v->state != RVSB_IN_DEPOT || v->tile != tile) return false;
-	}
-	return true;
-}
-
 static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance)
 {
 	if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0);
@@ -356,6 +343,8 @@
 	RoadVehicle *v = RoadVehicle::GetIfValid(p1);
 	if (v == NULL) return CMD_ERROR;

+	if (!v->IsPrimaryVehicle()) return CMD_ERROR;
+
 	CommandCost ret = CheckOwnership(v->owner);
 	if (ret.Failed()) return ret;

@@ -1576,7 +1565,7 @@
 {
 	/* If we already got a slot at a stop, use that FIRST, and go to a depot later */
 	if (Company::Get(v->owner)->settings.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
-	if (v->IsInDepot()) {
+	if (v->IsChainInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
 	}
diff -Nru openttd-1.2.1/src/roadveh.h openttd-1.2.2/src/roadveh.h
--- openttd-1.2.1/src/roadveh.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/roadveh.h	2012-08-16 20:41:43.000000000 +0200
@@ -113,7 +113,6 @@
 	Money GetRunningCost() const;
 	int GetDisplayImageWidth(Point *offset = NULL) const;
 	bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; }
-	bool IsStoppedInDepot() const;
 	bool Tick();
 	void OnNewDay();
 	uint Crash(bool flooded = false);
diff -Nru openttd-1.2.1/src/train_cmd.cpp openttd-1.2.2/src/train_cmd.cpp
--- openttd-1.2.1/src/train_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/train_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -730,34 +730,6 @@
 	return CommandCost();
 }

-/**
- * Is the whole consist the in a depot?
- * @return \c true iff all vehicles of the train are in a depot.
- */
-bool Train::IsInDepot() const
-{
-	/* Is the front engine stationary in the depot? */
-	if (!IsRailDepotTile(this->tile) || this->cur_speed != 0) return false;
-
-	/* Check whether the rest is also already trying to enter the depot. */
-	for (const Train *v = this; v != NULL; v = v->Next()) {
-		if (v->track != TRACK_BIT_DEPOT || v->tile != this->tile) return false;
-	}
-
-	return true;
-}
-
-/**
- * Is the train stopped in a depot?
- * @return True if the train is stopped in a depot, else false.
- */
-bool Train::IsStoppedInDepot() const
-{
-	/* Are we stopped? Of course wagons don't really care... */
-	if (this->IsFrontEngine() && !(this->vehstatus & VS_STOPPED)) return false;
-	return this->IsInDepot();
-}
-
 static Train *FindGoodVehiclePos(const Train *src)
 {
 	EngineID eng = src->engine_type;
@@ -1932,6 +1904,8 @@
 	Train *t = Train::GetIfValid(p1);
 	if (t == NULL) return CMD_ERROR;

+	if (!t->IsPrimaryVehicle()) return CMD_ERROR;
+
 	CommandCost ret = CheckOwnership(t->owner);
 	if (ret.Failed()) return ret;

@@ -1942,7 +1916,7 @@
 		 * to proceed to the next signal. In the other cases we
 		 * would like to pass the signal at danger and run till the
 		 * next signal we encounter. */
-		t->force_proceed = t->force_proceed == TFP_SIGNAL ? TFP_NONE : HasBit(t->flags, VRF_TRAIN_STUCK) || t->IsInDepot() ? TFP_STUCK : TFP_SIGNAL;
+		t->force_proceed = t->force_proceed == TFP_SIGNAL ? TFP_NONE : HasBit(t->flags, VRF_TRAIN_STUCK) || t->IsChainInDepot() ? TFP_STUCK : TFP_SIGNAL;
 		SetWindowDirty(WC_VEHICLE_VIEW, t->index);
 	}

@@ -3900,7 +3874,7 @@
 static void CheckIfTrainNeedsService(Train *v)
 {
 	if (Company::Get(v->owner)->settings.vehicle.servint_trains == 0 || !v->NeedsAutomaticServicing()) return;
-	if (v->IsInDepot()) {
+	if (v->IsChainInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
 	}
diff -Nru openttd-1.2.1/src/train.h openttd-1.2.2/src/train.h
--- openttd-1.2.1/src/train.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/train.h	2012-08-16 20:41:43.000000000 +0200
@@ -101,8 +101,7 @@
 	int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; }
 	Money GetRunningCost() const;
 	int GetDisplayImageWidth(Point *offset = NULL) const;
-	bool IsInDepot() const;
-	bool IsStoppedInDepot() const;
+	bool IsInDepot() const { return this->track == TRACK_BIT_DEPOT; }
 	bool Tick();
 	void OnNewDay();
 	uint Crash(bool flooded = false);
diff -Nru openttd-1.2.1/src/vehicle_base.h openttd-1.2.2/src/vehicle_base.h
--- openttd-1.2.1/src/vehicle_base.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/vehicle_base.h	2012-08-16 20:41:43.000000000 +0200
@@ -411,10 +411,22 @@
 	virtual bool IsInDepot() const { return false; }

 	/**
+	 * Check whether the whole vehicle chain is in the depot.
+	 * @return true if and only if the whole chain is in the depot.
+	 */
+	virtual bool IsChainInDepot() const { return this->IsInDepot(); }
+
+	/**
 	 * Check whether the vehicle is in the depot *and* stopped.
 	 * @return true if and only if the vehicle is in the depot and stopped.
 	 */
-	virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
+	bool IsStoppedInDepot() const
+	{
+		assert(this == this->First());
+		/* Free wagons have no VS_STOPPED state */
+		if (this->IsPrimaryVehicle() && !(this->vehstatus & VS_STOPPED)) return false;
+		return this->IsChainInDepot();
+	}

 	/**
 	 * Calls the tick handler of the vehicle
diff -Nru openttd-1.2.1/src/vehicle_cmd.cpp openttd-1.2.2/src/vehicle_cmd.cpp
--- openttd-1.2.1/src/vehicle_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/vehicle_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -601,13 +601,7 @@

 		if (!!(v->vehstatus & VS_STOPPED) != do_start) continue;

-		if (!vehicle_list_window) {
-			if (vli.vtype == VEH_TRAIN) {
-				if (!Train::From(v)->IsInDepot()) continue;
-			} else {
-				if (!(v->vehstatus & VS_HIDDEN)) continue;
-			}
-		}
+		if (!vehicle_list_window && !v->IsChainInDepot()) continue;

 		/* Just try and don't care if some vehicle's can't be stopped. */
 		DoCommand(tile, v->index, 0, flags, CMD_START_STOP_VEHICLE);
@@ -679,7 +673,7 @@
 		const Vehicle *v = list[i];

 		/* Ensure that the vehicle completely in the depot */
-		if (!v->IsInDepot()) continue;
+		if (!v->IsChainInDepot()) continue;

 		CommandCost ret = DoCommand(0, v->index, 0, flags, CMD_AUTOREPLACE_VEHICLE);

@@ -991,6 +985,7 @@

 	Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20));
 	if (v == NULL) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle()) return CMD_ERROR;

 	return v->SendToDepot(flags, (DepotCommand)(p1 & DEPOT_COMMAND_MASK));
 }


###############################################################################
# When a base set was incorrectly configured in the .cfg, then the game would crash during start. This method falls back to another base set and shows an in-game warning
###############################################################################


diff -Nru openttd-1.2.1/src/openttd.cpp openttd-1.2.2/src/openttd.cpp
--- openttd-1.2.1/src/openttd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/openttd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -722,8 +722,14 @@

 	BaseGraphics::FindSets();
 	if (graphics_set == NULL && BaseGraphics::ini_set != NULL) graphics_set = strdup(BaseGraphics::ini_set);
-	if (!BaseGraphics::SetSet(graphics_set) && !StrEmpty(graphics_set)) {
-		usererror("Failed to select requested graphics set '%s'", graphics_set);
+	if (!BaseGraphics::SetSet(graphics_set)) {
+		if (!StrEmpty(graphics_set)) {
+			BaseGraphics::SetSet(NULL);
+
+			ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND);
+			msg.SetDParamStr(0, graphics_set);
+			ScheduleErrorMessage(msg);
+		}
 	}
 	free(graphics_set);

@@ -782,18 +788,26 @@
 	BaseSounds::FindSets();
 	if (sounds_set == NULL && BaseSounds::ini_set != NULL) sounds_set = strdup(BaseSounds::ini_set);
 	if (!BaseSounds::SetSet(sounds_set)) {
-		StrEmpty(sounds_set) ?
-			usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 4.1 of readme.txt.") :
-			usererror("Failed to select requested sounds set '%s'", sounds_set);
+		if (StrEmpty(sounds_set) || !BaseSounds::SetSet(NULL)) {
+			usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 4.1 of readme.txt.");
+		} else {
+			ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND);
+			msg.SetDParamStr(0, sounds_set);
+			ScheduleErrorMessage(msg);
+		}
 	}
 	free(sounds_set);

 	BaseMusic::FindSets();
 	if (music_set == NULL && BaseMusic::ini_set != NULL) music_set = strdup(BaseMusic::ini_set);
 	if (!BaseMusic::SetSet(music_set)) {
-		StrEmpty(music_set) ?
-			usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 4.1 of readme.txt.") :
-			usererror("Failed to select requested music set '%s'", music_set);
+		if (StrEmpty(music_set) || !BaseMusic::SetSet(NULL)) {
+			usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 4.1 of readme.txt.");
+		} else {
+			ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND);
+			msg.SetDParamStr(0, music_set);
+			ScheduleErrorMessage(msg);
+		}
 	}
 	free(music_set);

diff -Nru openttd-1.2.1/src/error_gui.cpp openttd-1.2.2/src/error_gui.cpp
--- openttd-1.2.1/src/error_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/error_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -417,3 +417,13 @@
 {
 	_error_list.splice(_error_list.end(), datas);
 }
+
+/**
+ * Schedule an error.
+ * Note: This does not try to display the error now. This is useful if the window system is not yet running.
+ * @param data Error message data; cleared afterwards
+ */
+void ScheduleErrorMessage(const ErrorMessageData &data)
+{
+	_error_list.push_back(data);
+}
diff -Nru openttd-1.2.1/src/error.h openttd-1.2.2/src/error.h
--- openttd-1.2.1/src/error.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/error.h	2012-08-16 20:41:43.000000000 +0200
@@ -48,6 +48,8 @@
 	void CopyOutDParams();
 };

+void ScheduleErrorMessage(const ErrorMessageData &data);
+
 void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x = 0, int y = 0, uint textref_stack_size = 0, const uint32 *textref_stack = NULL);
 void ClearErrorMessages();
 void ShowFirstError();


###############################################################################
# Due to NewGRFs (custom content) the order of vehicles would be wrong; mostly due to multiple sets competing + ship 0x80 variable was missing (first two hunks)
###############################################################################


diff -Nru openttd-1.2.1/src/newgrf_engine.cpp openttd-1.2.2/src/newgrf_engine.cpp
--- openttd-1.2.1/src/newgrf_engine.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_engine.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -23,6 +23,7 @@
 #include "station_base.h"
 #include "company_base.h"
 #include "newgrf_railtype.h"
+#include "ship.h"

 struct WagonOverride {
 	EngineID *train_id;
@@ -830,6 +831,14 @@
 			break;
 		}

+		case VEH_SHIP: {
+			Ship *s = Ship::From(v);
+			switch (variable - 0x80) {
+				case 0x62: return s->state;
+			}
+			break;
+		}
+
 		case VEH_AIRCRAFT: {
 			Aircraft *a = Aircraft::From(v);
 			switch (variable - 0x80) {
@@ -1175,30 +1184,22 @@
 	v->InvalidateNewGRFCacheOfChain();
 }

-/* Functions for changing the order of vehicle purchase lists
- * This is currently only implemented for rail vehicles. */
-
-/**
- * Get the list position of an engine.
- * Used when sorting a list of engines.
- * @param engine ID of the engine.
- * @return The list position of the engine.
- */
-uint ListPositionOfEngine(EngineID engine)
-{
-	const Engine *e = Engine::Get(engine);
-	/* Crude sorting to group by GRF ID */
-	return (e->GetGRFID() * 256) + e->list_position;
-}
+/* Functions for changing the order of vehicle purchase lists */

 struct ListOrderChange {
 	EngineID engine;
-	EngineID target;
+	uint target;      ///< local ID
 };

 static SmallVector<ListOrderChange, 16> _list_order_changes;

-void AlterVehicleListOrder(EngineID engine, EngineID target)
+/**
+ * Record a vehicle ListOrderChange.
+ * @param engine Engine to move
+ * @param target Local engine ID to move \a engine in front of
+ * @note All sorting is done later in CommitVehicleListOrderChanges
+ */
+void AlterVehicleListOrder(EngineID engine, uint target)
 {
 	/* Add the list order change to a queue */
 	ListOrderChange *loc = _list_order_changes.Append();
@@ -1206,49 +1207,74 @@
 	loc->target = target;
 }

-void CommitVehicleListOrderChanges()
+/**
+ * Comparator function to sort engines via scope-GRFID and local ID.
+ * @param a left side
+ * @param b right side
+ * @return comparison result
+ */
+static int CDECL EnginePreSort(const EngineID *a, const EngineID *b)
 {
-	/* List position to Engine map */
-	typedef SmallMap<uint16, Engine *, 16> ListPositionMap;
-	ListPositionMap lptr_map;
+	const EngineIDMapping *id_a = _engine_mngr.Get(*a);
+	const EngineIDMapping *id_b = _engine_mngr.Get(*b);

-	const ListOrderChange *end = _list_order_changes.End();
-	for (const ListOrderChange *it = _list_order_changes.Begin(); it != end; ++it) {
-		EngineID engine = it->engine;
-		EngineID target = it->target;
+	/* 1. Sort by engine type */
+	if (id_a->type != id_b->type) return (int)id_a->type - (int)id_b->type;

-		if (engine == target) continue;
+	/* 2. Sort by scope-GRFID */
+	if (id_a->grfid != id_b->grfid) return id_a->grfid < id_b->grfid ? -1 : 1;

-		Engine *source_e = Engine::Get(engine);
-		Engine *target_e = NULL;
+	/* 3. Sort by local ID */
+	return (int)id_a->internal_id - (int)id_b->internal_id;
+}

-		/* Populate map with current list positions */
-		Engine *e;
-		FOR_ALL_ENGINES_OF_TYPE(e, source_e->type) {
-			if (!_settings_game.vehicle.dynamic_engines || e->GetGRF() == source_e->GetGRF()) {
-				if (e->grf_prop.local_id == target) target_e = e;
-				lptr_map[e->list_position] = e;
-			}
-		}
+/**
+ * Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
+ */
+void CommitVehicleListOrderChanges()
+{
+	/* Pre-sort engines by scope-grfid and local index */
+	SmallVector<EngineID, 16> ordering;
+	Engine *e;
+	FOR_ALL_ENGINES(e) {
+		*ordering.Append() = e->index;
+	}
+	QSortT(ordering.Begin(), ordering.Length(), EnginePreSort);

-		/* std::map sorted by default, SmallMap does not */
-		lptr_map.SortByKey();
+	/* Apply Insertion-Sort opeations */
+	const ListOrderChange *end = _list_order_changes.End();
+	for (const ListOrderChange *it = _list_order_changes.Begin(); it != end; ++it) {
+		EngineID source = it->engine;
+		uint local_target = it->target;

-		/* Get the target position, if it exists */
-		if (target_e != NULL) {
-			uint16 target_position = target_e->list_position;
-
-			bool moving = false;
-			const ListPositionMap::Pair *end = lptr_map.End();
-			for (ListPositionMap::Pair *it = lptr_map.Begin(); it != end; ++it) {
-				if (it->first == target_position) moving = true;
-				if (moving) it->second->list_position++;
-			}
+		const EngineIDMapping *id_source = _engine_mngr.Get(source);
+		if (id_source->internal_id == local_target) continue;
+
+		EngineID target = _engine_mngr.GetID(id_source->type, local_target, id_source->grfid);
+		if (target == INVALID_ENGINE) continue;

-			source_e->list_position = target_position;
+		int source_index = ordering.FindIndex(source);
+		int target_index = ordering.FindIndex(target);
+
+		assert(source_index >= 0 && target_index >= 0);
+		assert(source_index != target_index);
+
+		EngineID *list = ordering.Begin();
+		if (source_index < target_index) {
+			--target_index;
+			for (int i = source_index; i < target_index; ++i) list[i] = list[i + 1];
+			list[target_index] = source;
+		} else {
+			for (int i = source_index; i > target_index; --i) list[i] = list[i - 1];
+			list[target_index] = source;
 		}
+	}

-		lptr_map.Clear();
+	/* Store final sort-order */
+	const EngineID *idend = ordering.End();
+	uint index = 0;
+	for (const EngineID *it = ordering.Begin(); it != idend; ++it, ++index) {
+		Engine::Get(*it)->list_position = index;
 	}

 	/* Clear out the queue */

diff -Nru openttd-1.2.1/src/autoreplace_gui.cpp openttd-1.2.2/src/autoreplace_gui.cpp
--- openttd-1.2.1/src/autoreplace_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/autoreplace_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -33,7 +33,7 @@

 static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
 {
-	int r = ListPositionOfEngine(*a) - ListPositionOfEngine(*b);
+	int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position;

 	return r;
 }
diff -Nru openttd-1.2.1/src/build_vehicle_gui.cpp openttd-1.2.2/src/build_vehicle_gui.cpp
--- openttd-1.2.1/src/build_vehicle_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/build_vehicle_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -98,7 +98,7 @@
  */
 static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
 {
-	int r = ListPositionOfEngine(*a) - ListPositionOfEngine(*b);
+	int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position;

 	return _internal_sort_order ? -r : r;
 }
@@ -1094,7 +1094,7 @@

 		this->sel_engine = sel_id;

-		/* make engines first, and then wagons, sorted by ListPositionOfEngine() */
+		/* make engines first, and then wagons, sorted by selected sort_criteria */
 		_internal_sort_order = false;
 		EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter);

diff -Nru openttd-1.2.1/src/newgrf_engine.h openttd-1.2.2/src/newgrf_engine.h
--- openttd-1.2.1/src/newgrf_engine.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_engine.h	2012-08-16 20:41:43.000000000 +0200
@@ -63,8 +63,7 @@

 void UnloadWagonOverrides(Engine *e);

-uint ListPositionOfEngine(EngineID engine);
-void AlterVehicleListOrder(EngineID engine, EngineID target);
+void AlterVehicleListOrder(EngineID engine, uint target);
 void CommitVehicleListOrderChanges();

 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id);

###############################################################################
# Incorrect initial sizing of UI elements that should have the same size; could lead to crash
###############################################################################

diff -Nru openttd-1.2.1/src/widget.cpp openttd-1.2.2/src/widget.cpp
--- openttd-1.2.1/src/widget.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/widget.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -1153,7 +1153,17 @@
 {
 	assert(given_width >= this->smallest_x && given_height >= this->smallest_y);

-	uint additional_length = given_width - this->smallest_x; // Additional width given to us.
+	/* Compute additional width given to us. */
+	uint additional_length = given_width;
+	if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
+		/* For EQUALSIZE containers this does not sum to smallest_x during initialisation */
+		for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
+			additional_length -= child_wid->smallest_x + child_wid->padding_right + child_wid->padding_left;
+		}
+	} else {
+		additional_length -= this->smallest_x;
+	}
+
 	this->StoreSizePosition(sizing, x, y, given_width, given_height);

 	/* In principle, the additional horizontal space is distributed evenly over the available resizable childs. Due to step sizes, this may not always be feasible.
@@ -1305,7 +1315,17 @@
 {
 	assert(given_width >= this->smallest_x && given_height >= this->smallest_y);

-	int additional_length = given_height - this->smallest_y; // Additional height given to us.
+	/* Compute additional height given to us. */
+	uint additional_length = given_height;
+	if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) {
+		/* For EQUALSIZE containers this does not sum to smallest_y during initialisation */
+		for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
+			additional_length -= child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom;
+		}
+	} else {
+		additional_length -= this->smallest_y;
+	}
+
 	this->StoreSizePosition(sizing, x, y, given_width, given_height);

 	/* Like the horizontal container, the vertical container also distributes additional height evenly, starting with the childs with the biggest resize steps.
@@ -1508,9 +1528,7 @@
 	/* When resizing, update the scrollbar's count. E.g. with a vertical
 	 * scrollbar becoming wider or narrower means the amount of rows in
 	 * the scrollbar becomes respectively smaller or higher. */
-	if (sizing == ST_RESIZE) {
-		this->SetCount(this->count);
-	}
+	this->SetCount(this->count);
 }

 void NWidgetMatrix::FillNestedArray(NWidgetBase **array, uint length)

###############################################################################
# Cargo translation (id within NewGRF and id within OpenTTD, needed due to multiple NewGRFs coexisting) was returning the wrong cargo ID in some corner cases + extended NewGRF format implementation did not work correctly
###############################################################################

diff -Nru openttd-1.2.1/src/newgrf_cargo.cpp openttd-1.2.2/src/newgrf_cargo.cpp
--- openttd-1.2.1/src/newgrf_cargo.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_cargo.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -126,18 +126,3 @@
 	}
 	return CT_INVALID;
 }
-
-uint8 GetReverseCargoTranslation(CargoID cargo, const GRFFile *grffile)
-{
-	/* Note: All grf versions use CargoBit here. Pre-version 7 do NOT use the 'climate dependent' ID. */
-	const CargoSpec *cs = CargoSpec::Get(cargo);
-
-	/* If the GRF contains a translation table (and the cargo is in the table)
-	 * then get the cargo ID for the label */
-	for (uint i = 0; i < grffile->cargo_max; i++) {
-		if (cs->label == grffile->cargo_list[i]) return i;
-	}
-
-	/* No matching label was found, so we return the 'climate independent' 'bitnum' */
-	return cs->bitnum;
-}
diff -Nru openttd-1.2.1/src/newgrf_cargo.h openttd-1.2.2/src/newgrf_cargo.h
--- openttd-1.2.1/src/newgrf_cargo.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_cargo.h	2012-08-16 20:41:43.000000000 +0200
@@ -27,6 +27,5 @@
 SpriteID GetCustomCargoSprite(const CargoSpec *cs);
 uint16 GetCargoCallback(CallbackID callback, uint32 param1, uint32 param2, const CargoSpec *cs);
 CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit = false);
-uint8 GetReverseCargoTranslation(CargoID cargo, const GRFFile *grffile);

 #endif /* NEWGRF_CARGO_H */
diff -Nru openttd-1.2.1/src/newgrf.cpp openttd-1.2.2/src/newgrf.cpp
--- openttd-1.2.1/src/newgrf.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -1041,7 +1041,7 @@
 				} else if (_cur.grffile->grf_version >= 8) {
 					/* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
 					ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
-				} else if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
+				} else if (ctype < NUM_CARGO) {
 					/* Use untranslated cargo. */
 					ei->cargo_type = ctype;
 				} else {
@@ -1276,7 +1276,7 @@
 				} else if (_cur.grffile->grf_version >= 8) {
 					/* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
 					ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
-				} else if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
+				} else if (ctype < NUM_CARGO) {
 					/* Use untranslated cargo. */
 					ei->cargo_type = ctype;
 				} else {
@@ -1454,7 +1454,7 @@
 				} else if (_cur.grffile->grf_version >= 8) {
 					/* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
 					ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
-				} else if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
+				} else if (ctype < NUM_CARGO) {
 					/* Use untranslated cargo. */
 					ei->cargo_type = ctype;
 				} else {
@@ -2442,11 +2442,22 @@
 				break;
 			}

-			case 0x09: // Cargo translation table
-				/* This is loaded during the reservation stage, so just skip it here. */
-				/* Each entry is 4 bytes. */
-				buf->Skip(4);
+			case 0x09: { // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
+				if (i == 0) {
+					if (gvid != 0) {
+						grfmsg(1, "GlobalVarChangeInfo: Cargo translation table must start at zero");
+						return CIR_INVALID_ID;
+					}
+
+					free(_cur.grffile->cargo_list);
+					_cur.grffile->cargo_max = numinfo;
+					_cur.grffile->cargo_list = MallocT<CargoLabel>(numinfo);
+				}
+
+				CargoLabel cl = buf->ReadDWord();
+				_cur.grffile->cargo_list[i] = BSWAP32(cl);
 				break;
+			}

 			case 0x0A: { // Currency display names
 				uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
@@ -2560,11 +2571,22 @@
 				buf->Skip(8);
 				break;

-			case 0x12: // Rail type translation table
-				/* This is loaded during the reservation stage, so just skip it here. */
-				/* Each entry is 4 bytes. */
-				buf->Skip(4);
+			case 0x12: { // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
+				if (i == 0) {
+					if (gvid != 0) {
+						grfmsg(1, "GlobalVarChangeInfo: Rail type translation table must start at zero");
+						return CIR_INVALID_ID;
+					}
+
+					free(_cur.grffile->railtype_list);
+					_cur.grffile->railtype_max = numinfo;
+					_cur.grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
+				}
+
+				RailTypeLabel rtl = buf->ReadDWord();
+				_cur.grffile->railtype_list[i] = BSWAP32(rtl);
 				break;
+			}

 			case 0x13:   // Gender translation table
 			case 0x14:   // Case translation table
@@ -4362,11 +4384,13 @@
 /* Action 0x01 */
 static void NewSpriteSet(ByteReader *buf)
 {
-	/* <01> <feature> <num-sets> <num-ent>
+	/* Basic format:    <01> <feature> <num-sets> <num-ent>
+	 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
 	 *
 	 * B feature       feature to define sprites for
 	 *                 0, 1, 2, 3: veh-type, 4: train stations
-	 * B num-sets      number of sprite sets
+	 * E first-set     first sprite set to define
+	 * B num-sets      number of sprite sets (extended byte in extended format)
 	 * E num-ent       how many entries per sprite set
 	 *                 For vehicles, this is the number of different
 	 *                         vehicle directions in each sprite set
@@ -4374,11 +4398,11 @@
 	 *                         In that case, use num-dirs=4.
 	 */

-	uint8 feature   = buf->ReadByte();
-	uint8 num_sets  = buf->ReadByte();
+	uint8  feature   = buf->ReadByte();
+	uint16 num_sets  = buf->ReadByte();
 	uint16 first_set = 0;

-	if (num_sets == 0 && buf->HasData(2)) {
+	if (num_sets == 0 && buf->HasData(3)) {
 		/* Extended Action1 format.
 		 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
 		first_set = buf->ReadExtendedByte();
@@ -4402,7 +4426,14 @@
 static void SkipAct1(ByteReader *buf)
 {
 	buf->ReadByte();
-	uint8 num_sets  = buf->ReadByte();
+	uint16 num_sets  = buf->ReadByte();
+
+	if (num_sets == 0 && buf->HasData(3)) {
+		/* Extended Action1 format.
+		 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
+		buf->ReadExtendedByte(); // first_set
+		num_sets = buf->ReadExtendedByte();
+	}
 	uint16 num_ents = buf->ReadExtendedByte();

 	_cur.skip_sprites = num_sets * num_ents;
@@ -8174,6 +8205,9 @@
 			only_defaultcargo = (ei->refit_mask == 0);
 		}

+		/* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
+		if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
+
 		/* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
 		 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
 		if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
diff -Nru openttd-1.2.1/src/newgrf_industries.cpp openttd-1.2.2/src/newgrf_industries.cpp
--- openttd-1.2.1/src/newgrf_industries.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_industries.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -657,7 +657,7 @@
 	const IndustrySpec *indspec = GetIndustrySpec(ind->type);
 	if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {
 		uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO,
-				0, GetReverseCargoTranslation(cargo_type, indspec->grf_prop.grffile),
+				0, indspec->grf_prop.grffile->cargo_map[cargo_type],
 				ind, ind->type, ind->location.tile);
 		if (res != CALLBACK_FAILED) return !ConvertBooleanCallback(indspec->grf_prop.grffile, CBID_INDUSTRY_REFUSE_CARGO, res);
 	}

###############################################################################
# Make oil rig vehicle list accessible by spectators (they could see all other vehicle lists)
###############################################################################

diff -Nru openttd-1.2.1/src/vehicle_gui.cpp openttd-1.2.2/src/vehicle_gui.cpp
--- openttd-1.2.1/src/vehicle_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/vehicle_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -1292,7 +1292,7 @@

 		if (show_orderlist) DrawSmallOrderList(v, orderlist_left, orderlist_right, y, v->cur_real_order_index);

-		if (v->IsInDepot()) {
+		if (v->IsChainInDepot()) {
 			str = STR_BLUE_COMMA;
 		} else {
 			str = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? STR_RED_COMMA : STR_BLACK_COMMA;
@@ -1358,7 +1358,7 @@
 		}

 		this->FinishInitNested(desc, window_number);
-		this->owner = this->vli.company;
+		if (this->vli.company != OWNER_NONE) this->owner = this->vli.company;

 		if (this->vli.vtype == VEH_TRAIN) ResizeWindow(this, 65, 0);
 	}
@@ -1544,7 +1544,7 @@

 				switch (index) {
 					case ADI_REPLACE: // Replace window
-						ShowReplaceGroupVehicleWindow(DEFAULT_GROUP, this->vli.vtype);
+						ShowReplaceGroupVehicleWindow(ALL_GROUP, this->vli.vtype);
 						break;
 					case ADI_SERVICE: // Send for servicing
 					case ADI_DEPOT: // Send to Depots
@@ -1609,7 +1609,7 @@

 static void ShowVehicleListWindowLocal(CompanyID company, VehicleListType vlt, VehicleType vehicle_type, uint16 unique_number)
 {
-	if (!Company::IsValidID(company)) return;
+	if (!Company::IsValidID(company) && company != OWNER_NONE) return;

 	_vehicle_list_desc.cls = GetWindowClassForVehicleType(vehicle_type);
 	AllocateWindowDescFront<VehicleListWindow>(&_vehicle_list_desc, VehicleListIdentifier(vlt, vehicle_type, company, unique_number).Pack());
@@ -1636,15 +1636,7 @@

 void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type, StationID station)
 {
-	if (!Company::IsValidID(company)) {
-		company = _local_company;
-		/* This can happen when opening the vehicle list as a spectator. */
-		if (!Company::IsValidID(company)) return;
-		_vehicle_list_desc.flags |= WDF_CONSTRUCTION;
-	} else {
-		_vehicle_list_desc.flags &= ~WDF_CONSTRUCTION;
-	}
-
+	_vehicle_list_desc.flags &= ~WDF_CONSTRUCTION;
 	ShowVehicleListWindowLocal(company, VL_STATION_LIST, vehicle_type, station);
 }

diff -Nru openttd-1.2.1/src/vehiclelist.cpp openttd-1.2.2/src/vehiclelist.cpp
--- openttd-1.2.1/src/vehiclelist.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/vehiclelist.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -19,12 +19,13 @@
  */
 uint32 VehicleListIdentifier::Pack()
 {
-	assert(this->company < (1 <<  4));
+	byte c = this->company == OWNER_NONE ? 0xF : (byte)this->company;
+	assert(c             < (1 <<  4));
 	assert(this->type    < (1 <<  3));
 	assert(this->vtype   < (1 <<  2));
 	assert(this->index   < (1 << 20));

-	return this->company << 28 | this->type << 23 | this->vtype << 26 | this->index;
+	return c << 28 | this->type << 23 | this->vtype << 26 | this->index;
 }

 /**
@@ -34,7 +35,8 @@
  */
 bool VehicleListIdentifier::Unpack(uint32 data)
 {
-	this->company = (CompanyID)GB(data, 28, 4);
+	byte c        = GB(data, 28, 4);
+	this->company = c == 0xF ? OWNER_NONE : (CompanyID)c;
 	this->type    = (VehicleListType)GB(data, 23, 3);
 	this->vtype   = (VehicleType)GB(data, 26, 2);
 	this->index   = GB(data, 0, 20);


###############################################################################
# Minor remaining bugfixes;
# - some bits of IsInDepot -> IsChainDepot and GetReverseCargoTranslation conversions
# - not enough space in depot view for articulated vehicle parts
# - catenary wires drawn under bridges when bridges are transparent
# - station properties 11/14 pylon/wire placement of catenary incorrectly implemented
# - center object previews in UI, otherwise graphics would be out of view in some cases
# - do not remove (tram) track from bridge when in dragging perpendicular to the bridge
# - do not interpret the tile of a station as its (station) ID
# - airport refusal would sometimes be shown for the wrong town
###############################################################################


diff -Nru openttd-1.2.1/src/depot_gui.cpp openttd-1.2.2/src/depot_gui.cpp
--- openttd-1.2.1/src/depot_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/depot_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -480,13 +480,14 @@
 					this->sel = INVALID_VEHICLE;
 					TrainDepotMoveVehicle(v, sel, gdvp.head);
 				} else if (v != NULL) {
-					int image = v->GetImage(_current_text_dir == TD_RTL ? DIR_E : DIR_W, EIT_IN_DEPOT);
+					bool rtl = _current_text_dir == TD_RTL;
+					int image = v->GetImage(rtl ? DIR_E : DIR_W, EIT_IN_DEPOT);
 					SetObjectToPlaceWnd(image, GetVehiclePalette(v), HT_DRAG, this);

 					this->sel = v->index;
 					this->SetDirty();

-					_cursor.short_vehicle_offset = v->IsGroundVehicle() ? 16 - v->GetGroundVehicleCache()->cached_veh_length * 2 : 0;
+					_cursor.short_vehicle_offset = v->IsGroundVehicle() ? (16 - v->GetGroundVehicleCache()->cached_veh_length * 2) * (rtl ? -1 : 1) : 0;
 					_cursor.vehchain = _ctrl_pressed;
 				}
 				break;
diff -Nru openttd-1.2.1/src/train_gui.cpp openttd-1.2.2/src/train_gui.cpp
--- openttd-1.2.1/src/train_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/train_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -61,8 +61,10 @@
 	bool rtl = _current_text_dir == TD_RTL;

 	assert(selection != INVALID_VEHICLE);
-	Point offset;
-	int dragged_width = Train::Get(selection)->GetDisplayImageWidth(&offset) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+	int dragged_width = WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+	for (Train *t = Train::Get(selection); t != NULL; t = t->HasArticulatedPart() ? t->GetNextArticulatedPart() : NULL) {
+		dragged_width += t->GetDisplayImageWidth(NULL);
+	}

 	int drag_hlight_left = rtl ? max(px -dragged_width, 0) : px;
 	int drag_hlight_right = rtl ? px : min(px + dragged_width, max_width);
diff -Nru openttd-1.2.1/src/elrail.cpp openttd-1.2.2/src/elrail.cpp
--- openttd-1.2.1/src/elrail.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/elrail.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -111,7 +111,6 @@
 		case MP_STATION:
 			if (!HasStationRail(t)) return TRACK_BIT_NONE;
 			if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
-			if (!IsStationTileElectrifiable(t)) return TRACK_BIT_NONE;
 			return TrackToTrackBits(GetRailStationTrack(t));

 		default:
@@ -409,7 +408,8 @@
 			}
 		}

-		if (PPPallowed[i] != 0 && HasBit(PCPstatus, i) && !HasBit(OverridePCP, i)) {
+		if (PPPallowed[i] != 0 && HasBit(PCPstatus, i) && !HasBit(OverridePCP, i) &&
+				(!IsRailStationTile(ti->tile) || CanStationTileHavePylons(ti->tile))) {
 			for (Direction k = DIR_BEGIN; k < DIR_END; k++) {
 				byte temp = PPPorder[i][GetTLG(ti->tile)][k];

@@ -437,12 +437,15 @@
 	if (IsTunnelTile(ti->tile)) return;

 	/* Don't draw a wire under a low bridge */
-	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_CATENARY)) {
+	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_BRIDGES)) {
 		int height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));

 		if (height <= GetTileMaxZ(ti->tile) + 1) return;
 	}

+	/* Don't draw a wire if the station tile does not want any */
+	if (IsRailStationTile(ti->tile) && !CanStationTileHaveWires(ti->tile)) return;
+
 	SpriteID wire_normal = GetWireBase(ti->tile);
 	SpriteID wire_halftile = (halftile_corner != CORNER_INVALID) ? GetWireBase(ti->tile, TCX_UPPER_HALFTILE) : wire_normal;
 	Track halftile_track;
diff -Nru openttd-1.2.1/src/newgrf_station.cpp openttd-1.2.2/src/newgrf_station.cpp
--- openttd-1.2.1/src/newgrf_station.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/newgrf_station.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -894,18 +894,29 @@
 }

 /**
- * Check if a rail station tile can be electrified.
+ * Check if a rail station tile shall have pylons when electrified.
  * @param tile %Tile to test.
- * @return Tile can be electrified.
+ * @return Tile shall have pylons.
  * @note This could be cached (during build) in the map array to save on all the dereferencing.
  */
-bool IsStationTileElectrifiable(TileIndex tile)
+bool CanStationTileHavePylons(TileIndex tile)
 {
 	const StationSpec *statspec = GetStationSpec(tile);
+	uint gfx = GetStationGfx(tile);
+	/* Default stations do not draw pylons under roofs (gfx >= 4) */
+	return statspec != NULL ? HasBit(statspec->pylons, gfx) : gfx < 4;
+}

-	return statspec == NULL ||
-			HasBit(statspec->pylons, GetStationGfx(tile)) ||
-			!HasBit(statspec->wires, GetStationGfx(tile));
+/**
+ * Check if a rail station tile shall have wires when electrified.
+ * @param tile %Tile to test.
+ * @return Tile shall have wires.
+ * @note This could be cached (during build) in the map array to save on all the dereferencing.
+ */
+bool CanStationTileHaveWires(TileIndex tile)
+{
+	const StationSpec *statspec = GetStationSpec(tile);
+	return statspec == NULL || !HasBit(statspec->wires, GetStationGfx(tile));
 }

 /** Wrapper for animation control, see #GetStationCallback. */
@@ -957,7 +968,7 @@
 				if (cargo_type == CT_INVALID) {
 					cargo = CT_INVALID;
 				} else {
-					cargo = GetReverseCargoTranslation(cargo_type, ss->grf_prop.grffile);
+					cargo = ss->grf_prop.grffile->cargo_map[cargo_type];
 				}
 				StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIM_START_STOP, ss, st, tile, (random_bits << 16) | Random(), (uint8)trigger | (cargo << 8));
 			}
diff -Nru openttd-1.2.1/src/object_gui.cpp openttd-1.2.2/src/object_gui.cpp
--- openttd-1.2.1/src/object_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/object_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -93,6 +93,12 @@
 				break;
 			}

+			case WID_BO_OBJECT_NAME:
+			case WID_BO_OBJECT_SIZE:
+				/* We do not want the window to resize when selecting objects; better clip texts */
+				size->width = 0;
+				break;
+
 			case WID_BO_OBJECT_MATRIX: {
 				/* Get the right amount of buttons based on the current spec. */
 				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
@@ -174,6 +180,13 @@
 				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 				if (spec == NULL) break;

+				/* Height of the selection matrix.
+				 * Depending on the number of views, the matrix has a 1x1, 1x2, 2x1 or 2x2 layout. To make the previews
+				 * look nice in all layouts, we use the 4x4 layout (smallest previews) as starting point. For the bigger
+				 * previews in the layouts with less views we add space homogenously on all sides, so the 4x4 preview-rectangle
+				 * is centered in the 2x1, 1x2 resp. 1x1 buttons. */
+				uint matrix_height = this->GetWidget<NWidgetMatrix>(WID_BO_OBJECT_MATRIX)->current_y;
+
 				DrawPixelInfo tmp_dpi;
 				/* Set up a clipping area for the preview. */
 				if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
@@ -182,9 +195,9 @@
 					if (spec->grf_prop.grffile == NULL) {
 						extern const DrawTileSprites _objects[];
 						const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id];
-						DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - TILE_PIXELS, dts, PAL_NONE);
+						DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - TILE_PIXELS, dts, PAL_NONE);
 					} else {
-						DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - TILE_PIXELS, spec, GB(widget, 16, 16));
+						DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - TILE_PIXELS, spec, GB(widget, 16, 16));
 					}
 					_cur_dpi = old_dpi;
 				}
diff -Nru openttd-1.2.1/src/road_cmd.cpp openttd-1.2.2/src/road_cmd.cpp
--- openttd-1.2.1/src/road_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/road_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -216,6 +216,9 @@

 		CommandCost cost(EXPENSES_CONSTRUCTION);
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+			/* Removing any roadbit in the bridge axis removes the roadtype (that's the behaviour remove-long-roads needs) */
+			if ((AxisToRoadBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) & pieces) == ROAD_NONE) return_cmd_error(rt == ROADTYPE_TRAM ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD);
+
 			TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
 			/* Pay for *every* tile of the bridge or tunnel */
 			uint len = GetTunnelBridgeLength(other_end, tile) + 2;
@@ -651,6 +654,7 @@

 		case MP_TUNNELBRIDGE: {
 			if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) goto do_clear;
+			/* Only allow building the outern roadbit, so building long roads stops at existing bridges */
 			if (MirrorRoadBits(DiagDirToRoadBits(GetTunnelBridgeDirection(tile))) != pieces) goto do_clear;
 			if (HasTileRoadType(tile, rt)) return_cmd_error(STR_ERROR_ALREADY_BUILT);
 			/* Don't allow adding roadtype to the bridge/tunnel when vehicles are already driving on it */
diff -Nru openttd-1.2.1/src/script/api/script_order.cpp openttd-1.2.2/src/script/api/script_order.cpp
--- openttd-1.2.1/src/script/api/script_order.cpp	2012-05-31 22:55:07.000000000 +0200
+++ openttd-1.2.2/src/script/api/script_order.cpp	2012-08-16 20:41:40.000000000 +0200
@@ -659,8 +659,8 @@
 /* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile)
 {
 	if (vehicle_type == ScriptVehicle::VT_AIR) {
-		if (ScriptTile::IsStationTile(origin_tile) && ::Station::Get(origin_tile)->airport.tile != INVALID_TILE) origin_tile = ::Station::Get(origin_tile)->airport.tile;
-		if (ScriptTile::IsStationTile(dest_tile) && ::Station::Get(dest_tile)->airport.tile != INVALID_TILE) dest_tile = ::Station::Get(dest_tile)->airport.tile;
+		if (ScriptTile::IsStationTile(origin_tile) && ::Station::GetByTile(origin_tile)->airport.tile != INVALID_TILE) origin_tile = ::Station::GetByTile(origin_tile)->airport.tile;
+		if (ScriptTile::IsStationTile(dest_tile) && ::Station::GetByTile(dest_tile)->airport.tile != INVALID_TILE) dest_tile = ::Station::GetByTile(dest_tile)->airport.tile;

 		return ScriptMap::DistanceSquare(origin_tile, dest_tile);
 	} else {
diff -Nru openttd-1.2.1/src/station_cmd.cpp openttd-1.2.2/src/station_cmd.cpp
--- openttd-1.2.1/src/station_cmd.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/station_cmd.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -2165,11 +2165,13 @@

 	/* Check if local auth would allow a new airport */
 	StringID authority_refuse_message = STR_NULL;
+	Town *authority_refuse_town = NULL;

 	if (_settings_game.economy.station_noise_level) {
 		/* do not allow to build a new airport if this raise the town noise over the maximum allowed by town */
 		if ((nearest->noise_reached + newnoise_level) > nearest->MaxTownNoise()) {
 			authority_refuse_message = STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE;
+			authority_refuse_town = nearest;
 		}
 	} else {
 		uint num = 0;
@@ -2179,11 +2181,12 @@
 		}
 		if (num >= 2) {
 			authority_refuse_message = STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT;
+			authority_refuse_town = t;
 		}
 	}

 	if (authority_refuse_message != STR_NULL) {
-		SetDParam(0, t->index);
+		SetDParam(0, authority_refuse_town->index);
 		return_cmd_error(authority_refuse_message);
 	}

@@ -2800,7 +2803,7 @@
 		}
 	}

-	if (HasStationRail(ti->tile) && HasCatenaryDrawn(GetRailType(ti->tile)) && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
+	if (HasStationRail(ti->tile) && HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);

 	if (HasBit(roadtypes, ROADTYPE_TRAM)) {
 		Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
diff -Nru openttd-1.2.1/src/station_func.h openttd-1.2.2/src/station_func.h
--- openttd-1.2.1/src/station_func.h	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/station_func.h	2012-08-16 20:41:43.000000000 +0200
@@ -39,8 +39,8 @@
 /* Check if a rail station tile is traversable. */
 bool IsStationTileBlocked(TileIndex tile);

-/* Check if a rail station tile is electrifiable. */
-bool IsStationTileElectrifiable(TileIndex tile);
+bool CanStationTileHavePylons(TileIndex tile);
+bool CanStationTileHaveWires(TileIndex tile);

 void UpdateAirportsNoise();

diff -Nru openttd-1.2.1/src/station_gui.cpp openttd-1.2.2/src/station_gui.cpp
--- openttd-1.2.1/src/station_gui.cpp	2012-05-31 22:55:13.000000000 +0200
+++ openttd-1.2.2/src/station_gui.cpp	2012-08-16 20:41:43.000000000 +0200
@@ -849,8 +849,6 @@
 	~StationViewWindow()
 	{
 		Owner owner = Station::Get(this->window_number)->owner;
-		if (!Company::IsValidID(owner)) owner = _local_company;
-		if (!Company::IsValidID(owner)) return; // Spectators
 		DeleteWindowById(WC_TRAINS_LIST,   VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN,    owner, this->window_number).Pack(), false);
 		DeleteWindowById(WC_ROADVEH_LIST,  VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD,     owner, this->window_number).Pack(), false);
 		DeleteWindowById(WC_SHIPS_LIST,    VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP,     owner, this->window_number).Pack(), false);
@@ -1136,9 +1134,11 @@
 			case WID_SV_TRAINS:   // Show list of scheduled trains to this station
 			case WID_SV_ROADVEHS: // Show list of scheduled road-vehicles to this station
 			case WID_SV_SHIPS:    // Show list of scheduled ships to this station
-			case WID_SV_PLANES:   // Show list of scheduled aircraft to this station
-				ShowVehicleListWindow(this->owner, (VehicleType)(widget - WID_SV_TRAINS), (StationID)this->window_number);
+			case WID_SV_PLANES: { // Show list of scheduled aircraft to this station
+				Owner owner = Station::Get(this->window_number)->owner;
+				ShowVehicleListWindow(owner, (VehicleType)(widget - WID_SV_TRAINS), (StationID)this->window_number);
 				break;
+			}
 		}
 	}

Attachment: signature.asc
Description: Digital signature


Reply to: