src/station_cmd.cpp
branchcpp_gui
changeset 6268 4b5241e5dd10
parent 6254 abc6ad7c035c
child 6285 187e3ef04cc9
--- a/src/station_cmd.cpp	Tue Feb 27 23:54:28 2007 +0000
+++ b/src/station_cmd.cpp	Wed Feb 28 00:33:40 2007 +0000
@@ -1,10 +1,12 @@
 /* $Id$ */
 
-/** @file station_cmd.c */
+/** @file station_cmd.cpp */
 
 #include "stdafx.h"
 #include "openttd.h"
+#include "aircraft.h"
 #include "bridge_map.h"
+#include "cmd_helper.h"
 #include "debug.h"
 #include "functions.h"
 #include "station_map.h"
@@ -36,24 +38,21 @@
 #include "helpers.hpp"
 #include "misc/autoptr.hpp"
 #include "road.h"
+#include "cargotype.h"
 
 /**
  * Called if a new block is added to the station-pool
  */
 static void StationPoolNewBlock(uint start_item)
 {
-	Station *st;
-
 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
 	 *  TODO - This is just a temporary stage, this will be removed. */
-	for (st = GetStation(start_item); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) st->index = start_item++;
+	for (Station *st = GetStation(start_item); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) st->index = start_item++;
 }
 
 static void StationPoolCleanBlock(uint start_item, uint end_item)
 {
-	uint i;
-
-	for (i = start_item; i <= end_item; i++) {
+	for (uint i = start_item; i <= end_item; i++) {
 		Station *st = GetStation(i);
 		if (st->IsValid()) st->~Station();
 	}
@@ -64,11 +63,9 @@
  */
 static void RoadStopPoolNewBlock(uint start_item)
 {
-	RoadStop *rs;
-
 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
 	 * TODO - This is just a temporary stage, this will be removed. */
-	for (rs = GetRoadStop(start_item); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
+	for (RoadStop *rs = GetRoadStop(start_item); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
 		rs->xy    = INVALID_TILE;
 		rs->index = start_item++;
 	}
@@ -78,29 +75,25 @@
 DEFINE_OLD_POOL(RoadStop, RoadStop, RoadStopPoolNewBlock, NULL)
 
 
-extern void UpdateAirplanesOnNewStation(Station *st);
-
-
 RoadStop* GetRoadStopByTile(TileIndex tile, RoadStop::Type type)
 {
 	const Station* st = GetStationByTile(tile);
-	RoadStop* rs;
-
-	for (rs = st->GetPrimaryRoadStop(type); rs->xy != tile; rs = rs->next) {
+
+	for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) {
+		if (rs->xy == tile) return rs;
 		assert(rs->next != NULL);
 	}
-
-	return rs;
 }
 
 
 static uint GetNumRoadStopsInStation(const Station* st, RoadStop::Type type)
 {
 	uint num = 0;
-	const RoadStop *rs;
 
 	assert(st != NULL);
-	for (rs = st->GetPrimaryRoadStop(type); rs != NULL; rs = rs->next) num++;
+	for (const RoadStop *rs = st->GetPrimaryRoadStop(type); rs != NULL; rs = rs->next) {
+		num++;
+	}
 
 	return num;
 }
@@ -129,12 +122,6 @@
 	BEGIN_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
 		if (IsTileType(tile_cur, MP_STATION)) {
 			StationID t = GetStationIndex(tile_cur);
-			{
-				Station *st = GetStation(t);
-				// you cannot take control of an oilrig!!
-				if (st->airport_type == AT_OILRIG && st->facilities == (FACIL_AIRPORT|FACIL_DOCK))
-					continue;
-			}
 
 			if (closest_station == INVALID_STATION) {
 				closest_station = t;
@@ -147,29 +134,6 @@
 	return (closest_station == INVALID_STATION) ? NULL : GetStation(closest_station);
 }
 
-static Station *AllocateStation(void)
-{
-	Station *st = NULL;
-
-	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
-	 * TODO - This is just a temporary stage, this will be removed. */
-	for (st = GetStation(0); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) {
-		if (!st->IsValid()) {
-			StationID index = st->index;
-
-			memset(st, 0, sizeof(Station));
-			st->index = index;
-			return st;
-		}
-	}
-
-	/* Check if we can add a block to the pool */
-	if (AddBlockToPool(&_Station_pool)) return AllocateStation();
-
-	_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
-	return NULL;
-}
-
 
 /**
  * Counts the numbers of tiles matching a specific type in the area around
@@ -181,13 +145,11 @@
  */
 static int CountMapSquareAround(TileIndex tile, TileType type, IndustryType industry)
 {
-	TileIndex cur_tile;
-	int dx, dy;
 	int num = 0;
 
-	for (dx = -3; dx <= 3; dx++) {
-		for (dy = -3; dy <= 3; dy++) {
-			cur_tile = TILE_MASK(tile + TileDiffXY(dx, dy));
+	for (int dx = -3; dx <= 3; dx++) {
+		for (int dy = -3; dy <= 3; dy++) {
+			TileIndex cur_tile = TILE_MASK(tile + TileDiffXY(dx, dy));
 
 			if (IsTileType(cur_tile, type)) {
 				switch (type) {
@@ -230,7 +192,6 @@
 	Town *t = st->town;
 	uint32 free_names = (uint32)-1;
 	int found;
-	uint z,z2;
 	unsigned long tmp;
 
 	{
@@ -295,14 +256,16 @@
 	}
 
 	/* check elevation compared to town */
-	z = GetTileZ(tile);
-	z2 = GetTileZ(t->xy);
-	if (z < z2) {
-		found = M(STR_SV_STNAME_VALLEY);
-		if (HASBIT(free_names, M(STR_SV_STNAME_VALLEY))) goto done;
-	} else if (z > z2) {
-		found = M(STR_SV_STNAME_HEIGHTS);
-		if (HASBIT(free_names, M(STR_SV_STNAME_HEIGHTS))) goto done;
+	{
+		uint z = GetTileZ(tile);
+		uint z2 = GetTileZ(t->xy);
+		if (z < z2) {
+			found = M(STR_SV_STNAME_VALLEY);
+			if (HASBIT(free_names, M(STR_SV_STNAME_VALLEY))) goto done;
+		} else if (z > z2) {
+			found = M(STR_SV_STNAME_HEIGHTS);
+			if (HASBIT(free_names, M(STR_SV_STNAME_HEIGHTS))) goto done;
+		}
 	}
 
 	/* check direction compared to town */
@@ -332,13 +295,14 @@
 }
 #undef M
 
-static Station* GetClosestStationFromTile(TileIndex tile, uint threshold, PlayerID owner)
+static Station* GetClosestStationFromTile(TileIndex tile)
 {
+	uint threshold = 8;
 	Station* best_station = NULL;
 	Station* st;
 
 	FOR_ALL_STATIONS(st) {
-		if ((owner == PLAYER_SPECTATOR || st->owner == owner)) {
+		if (st->facilities == 0 && st->owner == _current_player) {
 			uint cur_dist = DistanceManhattan(tile, st->xy);
 
 			if (cur_dist < threshold) {
@@ -387,9 +351,8 @@
 static uint GetAcceptanceMask(const Station *st)
 {
 	uint mask = 0;
-	uint i;
-
-	for (i = 0; i != NUM_CARGO; i++) {
+
+	for (uint i = 0; i != NUM_CARGO; i++) {
 		if (st->goods[i].waiting_acceptance & 0x8000) mask |= 1 << i;
 	}
 	return mask;
@@ -400,7 +363,7 @@
 static void ShowRejectOrAcceptNews(const Station *st, uint num_items, CargoID *cargo, StringID msg)
 {
 	for (uint i = 0; i < num_items; i++) {
-		SetDParam(i + 1, _cargoc.names_s[cargo[i]]);
+		SetDParam(i + 1, GetCargo(cargo[i])->name);
 	}
 
 	SetDParam(0, st->index);
@@ -411,35 +374,30 @@
 void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile,
 	int w, int h, int rad)
 {
-	int x,y;
-	int x1,y1,x2,y2;
-	int xc,yc;
-
 	memset(produced, 0, sizeof(AcceptedCargo));
 
-	x = TileX(tile);
-	y = TileY(tile);
+	int x = TileX(tile);
+	int y = TileY(tile);
 
 	// expand the region by rad tiles on each side
 	// while making sure that we remain inside the board.
-	x2 = min(x + w + rad, MapSizeX());
-	x1 = max(x - rad, 0);
-
-	y2 = min(y + h + rad, MapSizeY());
-	y1 = max(y - rad, 0);
+	int x2 = min(x + w + rad, MapSizeX());
+	int x1 = max(x - rad, 0);
+
+	int y2 = min(y + h + rad, MapSizeY());
+	int y1 = max(y - rad, 0);
 
 	assert(x1 < x2);
 	assert(y1 < y2);
 	assert(w > 0);
 	assert(h > 0);
 
-	for (yc = y1; yc != y2; yc++) {
-		for (xc = x1; xc != x2; xc++) {
+	for (int yc = y1; yc != y2; yc++) {
+		for (int xc = x1; xc != x2; xc++) {
 			if (!(IS_INSIDE_1D(xc, x, w) && IS_INSIDE_1D(yc, y, h))) {
-				GetProducedCargoProc *gpc;
 				TileIndex tile = TileXY(xc, yc);
 
-				gpc = _tile_type_procs[GetTileType(tile)]->get_produced_cargo_proc;
+				GetProducedCargoProc *gpc = _tile_type_procs[GetTileType(tile)]->get_produced_cargo_proc;
 				if (gpc != NULL) {
 					CargoID cargos[2] = { CT_INVALID, CT_INVALID };
 
@@ -460,37 +418,32 @@
 void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile,
 	int w, int h, int rad)
 {
-	int x,y;
-	int x1,y1,x2,y2;
-	int xc,yc;
-
 	memset(accepts, 0, sizeof(AcceptedCargo));
 
-	x = TileX(tile);
-	y = TileY(tile);
+	int x = TileX(tile);
+	int y = TileY(tile);
 
 	// expand the region by rad tiles on each side
 	// while making sure that we remain inside the board.
-	x2 = min(x + w + rad, MapSizeX());
-	y2 = min(y + h + rad, MapSizeY());
-	x1 = max(x - rad, 0);
-	y1 = max(y - rad, 0);
+	int x2 = min(x + w + rad, MapSizeX());
+	int y2 = min(y + h + rad, MapSizeY());
+	int x1 = max(x - rad, 0);
+	int y1 = max(y - rad, 0);
 
 	assert(x1 < x2);
 	assert(y1 < y2);
 	assert(w > 0);
 	assert(h > 0);
 
-	for (yc = y1; yc != y2; yc++) {
-		for (xc = x1; xc != x2; xc++) {
+	for (int yc = y1; yc != y2; yc++) {
+		for (int xc = x1; xc != x2; xc++) {
 			TileIndex tile = TileXY(xc, yc);
 
 			if (!IsTileType(tile, MP_STATION)) {
 				AcceptedCargo ac;
-				uint i;
 
 				GetAcceptedCargo(tile, ac);
-				for (i = 0; i < lengthof(ac); ++i) accepts[i] += ac[i];
+				for (uint i = 0; i < lengthof(ac); ++i) accepts[i] += ac[i];
 			}
 		}
 	}
@@ -518,21 +471,17 @@
 // show_msg controls whether to display a message that acceptance was changed.
 static void UpdateStationAcceptance(Station *st, bool show_msg)
 {
-	uint old_acc, new_acc;
-	const RoadStop *cur_rs;
-	int i;
+	// Don't update acceptance for a buoy
+	if (st->IsBuoy()) return;
+
 	ottd_Rectangle rect;
-	int rad;
-	AcceptedCargo accepts;
-
 	rect.min_x = MapSizeX();
 	rect.min_y = MapSizeY();
-	rect.max_x = rect.max_y = 0;
-	// Don't update acceptance for a buoy
-	if (st->IsBuoy()) return;
+	rect.max_x = 0;
+	rect.max_y = 0;
 
 	/* old accepted goods types */
-	old_acc = GetAcceptanceMask(st);
+	uint old_acc = GetAcceptanceMask(st);
 
 	// Put all the tiles that span an area in the table.
 	if (st->train_tile != 0) {
@@ -553,31 +502,30 @@
 
 	if (st->dock_tile != 0) MergePoint(&rect, st->dock_tile);
 
-	for (cur_rs = st->bus_stops; cur_rs != NULL; cur_rs = cur_rs->next) {
-		MergePoint(&rect, cur_rs->xy);
+	for (const RoadStop *rs = st->bus_stops; rs != NULL; rs = rs->next) {
+		MergePoint(&rect, rs->xy);
 	}
 
-	for (cur_rs = st->truck_stops; cur_rs != NULL; cur_rs = cur_rs->next) {
-		MergePoint(&rect, cur_rs->xy);
+	for (const RoadStop *rs = st->truck_stops; rs != NULL; rs = rs->next) {
+		MergePoint(&rect, rs->xy);
 	}
 
-	rad = (_patches.modified_catchment) ? FindCatchmentRadius(st) : 4;
-
 	// And retrieve the acceptance.
+	AcceptedCargo accepts;
 	if (rect.max_x >= rect.min_x) {
 		GetAcceptanceAroundTiles(
 			accepts,
 			TileXY(rect.min_x, rect.min_y),
 			rect.max_x - rect.min_x + 1,
 			rect.max_y - rect.min_y + 1,
-			rad
+			_patches.modified_catchment ? FindCatchmentRadius(st) : 4
 		);
 	} else {
 		memset(accepts, 0, sizeof(accepts));
 	}
 
 	// Adjust in case our station only accepts fewer kinds of goods
-	for (i = 0; i != NUM_CARGO; i++) {
+	for (uint i = 0; i != NUM_CARGO; i++) {
 		uint amt = min(accepts[i], 15);
 
 		// Make sure the station can accept the goods type.
@@ -589,7 +537,7 @@
 	}
 
 	// Only show a message in case the acceptance was actually changed.
-	new_acc = GetAcceptanceMask(st);
+	uint new_acc = GetAcceptanceMask(st);
 	if (old_acc == new_acc)
 		return;
 
@@ -638,7 +586,7 @@
 
 static void UpdateStationSignCoord(Station *st)
 {
-	StationRect *r = &st->rect;
+	const StationRect *r = &st->rect;
 
 	if (r->IsEmpty()) return; // no tiles belong to this station
 
@@ -667,21 +615,18 @@
 // Or an error code if it failed.
 int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station)
 {
-	int32 cost = 0, ret;
-
-	Slope tileh;
-	uint z;
+	int32 cost = 0;
 	int allowed_z = -1;
-	int flat_z;
-
-	BEGIN_TILE_LOOP(tile_cur, w, h, tile)
+
+	BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
 		if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) {
 			return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 		}
 
 		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
 
-		tileh = GetTileSlope(tile_cur, &z);
+		uint z;
+		Slope tileh = GetTileSlope(tile_cur, &z);
 
 		/* Prohibit building if
 		 *   1) The tile is "steep" (i.e. stretches two height levels)
@@ -696,7 +641,7 @@
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 		}
 
-		flat_z = z;
+		int flat_z = z;
 		if (tileh != SLOPE_FLAT) {
 			// need to check so the entrance to the station is not pointing at a slope.
 			if ((invalid_dirs&1 && !(tileh & SLOPE_NE) && (uint)w_cur == w) ||
@@ -732,18 +677,19 @@
 				}
 			}
 		} else {
-			ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+			int32 ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) return ret;
 			cost += ret;
 		}
-	END_TILE_LOOP(tile_cur, w, h, tile)
+	} END_TILE_LOOP(tile_cur, w, h, tile)
 
 	return cost;
 }
 
-static bool CanExpandRailroadStation(Station* st, uint* fin, Axis axis)
+static bool CanExpandRailroadStation(const Station* st, uint* fin, Axis axis)
 {
-	uint curw = st->trainst_w, curh = st->trainst_h;
+	uint curw = st->trainst_w;
+	uint curh = st->trainst_h;
 	TileIndex tile = fin[0];
 	uint w = fin[1];
 	uint h = fin[2];
@@ -842,7 +788,7 @@
 /** Build railroad station
  * @param tile_org starting position of station dragging/placement
  * @param p1 various bitstuffed elements
- * - p1 = (bit  0)    - orientation (p1 & 1)
+ * - p1 = (bit  0)    - orientation (Axis)
  * - p1 = (bit  8-15) - number of tracks
  * - p1 = (bit 16-23) - platform length
  * @param p2 various bitstuffed elements
@@ -852,15 +798,8 @@
  */
 int32 CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, uint32 p2)
 {
-	Station *st;
 	int w_org, h_org;
-	int32 cost, ret;
-	StationID est;
-	int plat_len, numtracks;
-	Axis axis;
-	uint finalvalues[3];
-	const StationSpec *statspec;
-	int specindex;
+	int32 ret;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -869,10 +808,9 @@
 	if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
 
 	/* unpack parameters */
-	axis = (Axis)(p1 & 1);
-	numtracks = GB(p1,  8, 8);
-	plat_len  = GB(p1, 16, 8);
-	/* w = length, h = num_tracks */
+	Axis axis = Extract<Axis, 0>(p1);
+	uint numtracks = GB(p1,  8, 8);
+	uint plat_len  = GB(p1, 16, 8);
 	if (axis == AXIS_X) {
 		w_org = plat_len;
 		h_org = numtracks;
@@ -884,27 +822,25 @@
 	if (h_org > _patches.station_spread || w_org > _patches.station_spread) return CMD_ERROR;
 
 	// these values are those that will be stored in train_tile and station_platforms
+	uint finalvalues[3];
 	finalvalues[0] = tile_org;
 	finalvalues[1] = w_org;
 	finalvalues[2] = h_org;
 
 	// Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station)
-	est = INVALID_STATION;
+	StationID est = INVALID_STATION;
 	// If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
 	//  for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
 	ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
 	if (CmdFailed(ret)) return ret;
-	cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
+	int32 cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
 
 	// Make sure there are no similar stations around us.
-	st = GetStationAround(tile_org, w_org, h_org, est);
+	Station *st = GetStationAround(tile_org, w_org, h_org, est);
 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
 	// See if there is a deleted station close to us.
-	if (st == NULL) {
-		st = GetClosestStationFromTile(tile_org, 8, _current_player);
-		if (st != NULL && st->facilities) st = NULL;
-	}
+	if (st == NULL) st = GetClosestStationFromTile(tile_org);
 
 	/* In case of new station if DC_EXEC is NOT set we still need to create the station
 	 * to test if everything is OK. In this case we need to delete it before return. */
@@ -912,7 +848,7 @@
 
 	if (st != NULL) {
 		// Reuse an existing station.
-		if (st->owner != OWNER_NONE && st->owner != _current_player)
+		if (st->owner != _current_player)
 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 
 		if (st->train_tile != 0) {
@@ -945,8 +881,8 @@
 	if (GB(p2, 8, 8) >= STAT_CLASS_MAX) return CMD_ERROR;
 
 	/* Check if we can allocate a custom stationspec to this station */
-	statspec = GetCustomStationSpec((StationClassID)GB(p2, 8, 8), GB(p2, 16, 8));
-	specindex = AllocateSpecToStation(statspec, st, flags & DC_EXEC);
+	const StationSpec *statspec = GetCustomStationSpec((StationClassID)GB(p2, 8, 8), GB(p2, 16, 8));
+	int specindex = AllocateSpecToStation(statspec, st, flags & DC_EXEC);
 	if (specindex == -1) return CMD_ERROR;
 
 	if (statspec != NULL) {
@@ -1031,14 +967,13 @@
 	uint w = st->trainst_w;
 	uint h = st->trainst_h;
 	TileIndex tile = st->train_tile;
-	uint i;
 
 restart:
 
 	// too small?
 	if (w != 0 && h != 0) {
 		// check the left side, x = constant, y changes
-		for (i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(0, i));) {
+		for (uint i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(0, i));) {
 			// the left side is unused?
 			if (++i == h) {
 				tile += TileDiffXY(1, 0);
@@ -1048,7 +983,7 @@
 		}
 
 		// check the right side, x = constant, y changes
-		for (i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(w - 1, i));) {
+		for (uint i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(w - 1, i));) {
 			// the right side is unused?
 			if (++i == h) {
 				w--;
@@ -1057,7 +992,7 @@
 		}
 
 		// check the upper side, y = constant, x changes
-		for (i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(i, 0));) {
+		for (uint i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(i, 0));) {
 			// the left side is unused?
 			if (++i == w) {
 				tile += TileDiffXY(0, 1);
@@ -1067,7 +1002,7 @@
 		}
 
 		// check the lower side, y = constant, x changes
-		for (i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(i, h - 1));) {
+		for (uint i = 0; !st->TileBelongsToRailStation(tile + TileDiffXY(i, h - 1));) {
 			// the left side is unused?
 			if (++i == w) {
 				h--;
@@ -1091,13 +1026,11 @@
  */
 int32 CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	Station *st;
-
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
 	// make sure the specified tile belongs to the current player, and that it is a railroad station.
 	if (!IsTileType(tile, MP_STATION) || !IsRailwayStation(tile) || !_patches.nonuniform_stations) return CMD_ERROR;
-	st = GetStationByTile(tile);
+	Station *st = GetStationByTile(tile);
 	if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile))) return CMD_ERROR;
 
 	// if we reached here, it means we can actually delete it. do that.
@@ -1130,9 +1063,6 @@
 
 static int32 RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
 {
-	int w,h;
-	int32 cost = 0;
-
 	/* if there is flooding and non-uniform stations are enabled, remove platforms tile by tile */
 	if (_current_player == OWNER_WATER && _patches.nonuniform_stations)
 		return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAILROAD_STATION);
@@ -1143,11 +1073,12 @@
 
 	/* determine width and height of platforms */
 	tile = st->train_tile;
-	w = st->trainst_w;
-	h = st->trainst_h;
+	int w = st->trainst_w;
+	int h = st->trainst_h;
 
 	assert(w != 0 && h != 0);
 
+	int32 cost = 0;
 	/* clear all areas of the station */
 	do {
 		int w_bak = w;
@@ -1239,13 +1170,10 @@
  */
 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	Station *st;
-	RoadStop *road_stop;
-	int32 cost;
-	int32 ret;
 	bool type = HASBIT(p2, 0);
 	bool is_drive_through = HASBIT(p2, 1);
 	bool build_over_road  = is_drive_through && IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL;
+	bool town_owned_road  = build_over_road && IsTileOwner(tile, OWNER_TOWN);
 	Owner cur_owner = _current_player;
 
 	/* Saveguard the parameters */
@@ -1264,23 +1192,20 @@
 
 	if (build_over_road) flags ^= DC_AUTO;
 
-	if (build_over_road && IsTileOwner(tile, OWNER_TOWN)) _current_player = OWNER_TOWN;
-	ret = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL);
+	if (town_owned_road) _current_player = OWNER_TOWN;
+	int32 ret = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL);
 	_current_player = cur_owner;
 	if (CmdFailed(ret)) return ret;
-	cost = build_over_road ? 0 : ret; // Don't add cost of clearing road when overbuilding
-
-	st = GetStationAround(tile, 1, 1, INVALID_STATION);
+	int32 cost = build_over_road ? 0 : ret; // Don't add cost of clearing road when overbuilding
+
+	Station *st = GetStationAround(tile, 1, 1, INVALID_STATION);
 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
 	/* Find a station close to us */
-	if (st == NULL) {
-		st = GetClosestStationFromTile(tile, 8, _current_player);
-		if (st != NULL && st->facilities != 0) st = NULL;
-	}
+	if (st == NULL) st = GetClosestStationFromTile(tile);
 
 	//give us a road stop in the list, and check if something went wrong
-	road_stop = new RoadStop(tile);
+	RoadStop *road_stop = new RoadStop(tile);
 	if (road_stop == NULL) {
 		return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
 	}
@@ -1298,7 +1223,7 @@
 	AutoPtrT<Station> st_auto_delete;
 
 	if (st != NULL) {
-		if (st->owner != OWNER_NONE && st->owner != _current_player) {
+		if (st->owner != _current_player) {
 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 		}
 
@@ -1334,8 +1259,12 @@
 
 		st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
 
-		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, is_drive_through, (DiagDirection)p1);
-		if (is_drive_through & HASBIT(p2, 3)) SetStopBuiltOnTownRoad(tile);
+		RoadStop::Type rs_type = type ? RoadStop::TRUCK : RoadStop::BUS;
+		if (is_drive_through) {
+			MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, (Axis)p1, town_owned_road);
+		} else {
+			MakeRoadStop(tile, st->owner, st->index, rs_type, (DiagDirection)p1);
+		}
 
 		UpdateStationVirtCoordDirty(st);
 		UpdateStationAcceptance(st, false);
@@ -1351,14 +1280,14 @@
 // Remove a bus station
 static int32 RemoveRoadStop(Station *st, uint32 flags, TileIndex tile)
 {
-	RoadStop **primary_stop;
-	RoadStop *cur_stop;
-	bool is_truck = IsTruckStop(tile);
-
 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner)) {
 		return CMD_ERROR;
 	}
 
+	bool is_truck = IsTruckStop(tile);
+
+	RoadStop **primary_stop;
+	RoadStop *cur_stop;
 	if (is_truck) { // truck stop
 		primary_stop = &st->truck_stops;
 		cur_stop = GetRoadStopByTile(tile, RoadStop::TRUCK);
@@ -1404,21 +1333,15 @@
  */
 int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	Station* st;
-	bool is_drive_through;
-	bool is_towns_road = false;
-	RoadBits road_bits;
-	int32 ret;
-
 	/* Make sure the specified tile is a road stop of the correct type */
 	if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR;
-	st = GetStationByTile(tile);
+	Station *st = GetStationByTile(tile);
 	/* Save the stop info before it is removed */
-	is_drive_through = IsDriveThroughStopTile(tile);
-	road_bits = GetAnyRoadBits(tile);
-	if (is_drive_through) is_towns_road = GetStopBuiltOnTownRoad(tile);
-
-	ret = RemoveRoadStop(st, flags, tile);
+	bool is_drive_through = IsDriveThroughStopTile(tile);
+	RoadBits road_bits = GetAnyRoadBits(tile);
+	bool is_towns_road = is_drive_through && GetStopBuiltOnTownRoad(tile);
+
+	int32 ret = RemoveRoadStop(st, flags, tile);
 
 	/* If the stop was a drive-through stop replace the road */
 	if ((flags & DC_EXEC) && !CmdFailed(ret) && is_drive_through) {
@@ -1426,7 +1349,7 @@
 		Owner cur_owner = _current_player;
 
 		if (is_towns_road) {
-			index = ClosestTownFromTile(tile, _patches.dist_local_authority)->index;
+			index = ClosestTownFromTile(tile, (uint)-1)->index;
 			_current_player = OWNER_TOWN;
 		}
 		DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
@@ -1535,13 +1458,7 @@
  */
 int32 CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	Town *t;
-	Station *st;
-	int32 cost;
-	int32 ret;
-	int w, h;
 	bool airport_upgrade = true;
-	const AirportFTAClass* afc;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -1551,11 +1468,12 @@
 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
 		return CMD_ERROR;
 
-	t = ClosestTownFromTile(tile, (uint)-1);
+	Town *t = ClosestTownFromTile(tile, (uint)-1);
 
 	/* Check if local auth refuses a new airport */
 	{
 		uint num = 0;
+		const Station *st;
 		FOR_ALL_STATIONS(st) {
 			if (st->town == t && st->facilities&FACIL_AIRPORT && st->airport_type != AT_OILRIG)
 				num++;
@@ -1566,22 +1484,19 @@
 		}
 	}
 
-	afc = GetAirport(p1);
-	w = afc->size_x;
-	h = afc->size_y;
-
-	ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
+	const AirportFTAClass *afc = GetAirport(p1);
+	int w = afc->size_x;
+	int h = afc->size_y;
+
+	int32 ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
 	if (CmdFailed(ret)) return ret;
-	cost = ret;
-
-	st = GetStationAround(tile, w, h, INVALID_STATION);
+	int32 cost = ret;
+
+	Station *st = GetStationAround(tile, w, h, INVALID_STATION);
 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
 	/* Find a station close to us */
-	if (st == NULL) {
-		st = GetClosestStationFromTile(tile, 8, _current_player);
-		if (st != NULL && st->facilities) st = NULL;
-	}
+	if (st == NULL) st = GetClosestStationFromTile(tile);
 
 	if (w > _patches.station_spread || h > _patches.station_spread) {
 		_error_message = STR_306C_STATION_TOO_SPREAD_OUT;
@@ -1593,7 +1508,7 @@
 	AutoPtrT<Station> st_auto_delete;
 
 	if (st != NULL) {
-		if (st->owner != OWNER_NONE && st->owner != _current_player)
+		if (st->owner != _current_player)
 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 
 		if (!st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TEST)) return CMD_ERROR;
@@ -1618,10 +1533,11 @@
 
 		st->sign.width_1 = 0;
 
-		// if airport type equals Heliport then generate
-		// type 5 name, which is heliport, otherwise airport names (1)
-		if (!GenerateStationName(st, tile, (p1 == AT_HELIPORT)||(p1 == AT_HELIDEPOT)||(p1 == AT_HELISTATION) ? 5 : 1))
+		/* If only helicopters may use the airport generate a helicopter related (5)
+		 * station name, otherwise generate a normal airport name (1) */
+		if (!GenerateStationName(st, tile, !(afc->flags & AirportFTAClass::AIRPLANES) ? 5 : 1)) {
 			return CMD_ERROR;
+		}
 	}
 
 	cost += _price.build_airport * w * h;
@@ -1664,20 +1580,16 @@
 
 static int32 RemoveAirport(Station *st, uint32 flags)
 {
-	TileIndex tile;
-	int w,h;
-	int32 cost;
-
 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
 		return CMD_ERROR;
 
-	tile = st->airport_tile;
+	TileIndex tile = st->airport_tile;
 
 	const AirportFTAClass *afc = st->Airport();
-	w = afc->size_x;
-	h = afc->size_y;
-
-	cost = w * h * _price.remove_airport;
+	int w = afc->size_x;
+	int h = afc->size_y;
+
+	int32 cost = w * h * _price.remove_airport;
 
 	BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
 		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
@@ -1689,9 +1601,7 @@
 	} END_TILE_LOOP(tile_cur, w,h,tile)
 
 	if (flags & DC_EXEC) {
-		uint i;
-
-		for (i = 0; i < afc->nof_depots; ++i) {
+		for (uint i = 0; i < afc->nof_depots; ++i) {
 			DeleteWindowById(
 				WC_VEHICLE_DEPOT, tile + ToTileIndexDiff(afc->airport_depots[i])
 			);
@@ -1716,14 +1626,12 @@
  */
 int32 CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	Station *st;
-
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
 	if (!IsClearWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE);
 
 	/* allocate and initialize new station */
-	st = new Station(tile);
+	Station *st = new Station(tile);
 	if (st == NULL) return CMD_ERROR;
 
 	/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
@@ -1776,12 +1684,10 @@
 
 static int32 RemoveBuoy(Station *st, uint32 flags)
 {
-	TileIndex tile;
-
 	/* XXX: strange stuff */
 	if (!IsValidPlayer(_current_player))  return_cmd_error(INVALID_STRING_ID);
 
-	tile = st->dock_tile;
+	TileIndex tile = st->dock_tile;
 
 	if (CheckShipsOnBuoy(st))   return_cmd_error(STR_BUOY_IS_IN_USE);
 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
@@ -1827,13 +1733,11 @@
  */
 int32 CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	TileIndex tile_cur;
-	DiagDirection direction;
 	int32 cost;
-	Station *st;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
+	DiagDirection direction;
 	switch (GetTileSlope(tile, NULL)) {
 		case SLOPE_SW: direction = DIAGDIR_NE; break;
 		case SLOPE_SE: direction = DIAGDIR_NW; break;
@@ -1844,14 +1748,10 @@
 
 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
 
-	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
-
 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 	if (CmdFailed(cost)) return CMD_ERROR;
 
-	tile_cur = tile + TileOffsByDiagDir(direction);
-
-	if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
+	TileIndex tile_cur = tile + TileOffsByDiagDir(direction);
 
 	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
@@ -1866,23 +1766,20 @@
 	}
 
 	/* middle */
-	st = GetStationAround(
+	Station *st = GetStationAround(
 		tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
 		_dock_w_chk[direction], _dock_h_chk[direction], INVALID_STATION);
 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
 	/* Find a station close to us */
-	if (st == NULL) {
-		st = GetClosestStationFromTile(tile, 8, _current_player);
-		if (st!=NULL && st->facilities) st = NULL;
-	}
+	if (st == NULL) st = GetClosestStationFromTile(tile);
 
 	/* In case of new station if DC_EXEC is NOT set we still need to create the station
 	* to test if everything is OK. In this case we need to delete it before return. */
 	AutoPtrT<Station> st_auto_delete;
 
 	if (st != NULL) {
-		if (st->owner != OWNER_NONE && st->owner != _current_player)
+		if (st->owner != _current_player)
 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 
 		if (!st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TEST)) return CMD_ERROR;
@@ -1927,13 +1824,10 @@
 
 static int32 RemoveDock(Station *st, uint32 flags)
 {
-	TileIndex tile1;
-	TileIndex tile2;
-
 	if (!CheckOwnership(st->owner)) return CMD_ERROR;
 
-	tile1 = st->dock_tile;
-	tile2 = tile1 + TileOffsByDiagDir(GetDockDirection(tile1));
+	TileIndex tile1 = st->dock_tile;
+	TileIndex tile2 = tile1 + TileOffsByDiagDir(GetDockDirection(tile1));
 
 	if (!EnsureNoVehicle(tile1)) return CMD_ERROR;
 	if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
@@ -1969,7 +1863,6 @@
 
 static void DrawTile_Station(TileInfo *ti)
 {
-	const DrawTileSeqStruct *dtss;
 	const DrawTileSprites *t = NULL;
 	RailType railtype = GetRailType(ti->tile);
 	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
@@ -1977,9 +1870,8 @@
 	const Station *st = NULL;
 	const StationSpec *statspec = NULL;
 	PlayerID owner = GetTileOwner(ti->tile);
-	SpriteID image;
+
 	SpriteID palette;
-
 	if (IsValidPlayer(owner)) {
 		palette = PLAYER_SPRITE_COLOR(owner);
 	} else {
@@ -2017,7 +1909,7 @@
 
 	if (t == NULL || t->seq == NULL) t = &_station_display_datas[GetStationGfx(ti->tile)];
 
-	image = t->ground_sprite;
+	SpriteID image = t->ground_sprite;
 	if (HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
 		image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 		image += rti->custom_ground_offset;
@@ -2033,9 +1925,8 @@
 
 	if (IsBuoyTile(ti->tile) && (ti->z != 0 || !IsTileOwner(ti->tile, OWNER_WATER))) DrawCanalWater(ti->tile);
 
+	const DrawTileSeqStruct *dtss;
 	foreach_draw_tile_seq(dtss, t->seq) {
-		SpriteID pal;
-
 		image = dtss->image;
 		if (relocation == 0 || HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
 			image += rti->total_offset;
@@ -2043,6 +1934,7 @@
 			image += relocation;
 		}
 
+		SpriteID pal;
 		if (_display_opt & DO_TRANS_BUILDINGS) {
 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
 			pal = PALETTE_TO_TRANSPARENT;
@@ -2067,18 +1959,14 @@
 
 void StationPickerDrawSprite(int x, int y, RailType railtype, int image)
 {
-	SpriteID pal, img;
-	const DrawTileSeqStruct *dtss;
-	const DrawTileSprites *t;
 	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
-
-	pal = PLAYER_SPRITE_COLOR(_local_player);
-
-	t = &_station_display_datas[image];
-
-	img = t->ground_sprite;
+	SpriteID pal = PLAYER_SPRITE_COLOR(_local_player);
+	const DrawTileSprites *t = &_station_display_datas[image];
+
+	SpriteID img = t->ground_sprite;
 	DrawSprite(img + rti->total_offset, HASBIT(img, PALETTE_MODIFIER_COLOR) ? pal : PAL_NONE, x, y);
 
+	const DrawTileSeqStruct *dtss;
 	foreach_draw_tile_seq(dtss, t->seq) {
 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
 		DrawSprite(dtss->image + rti->total_offset, pal, x + pt.x, y + pt.y);
@@ -2102,11 +1990,10 @@
 
 static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
 {
-	StringID str;
-
 	td->owner = GetTileOwner(tile);
 	td->build_date = GetStationByTile(tile)->build_date;
 
+	StringID str;
 	switch (GetStationType(tile)) {
 		default: NOT_REACHED();
 		case STATION_RAIL:    str = STR_305E_RAILROAD_STATION; break;
@@ -2200,9 +2087,8 @@
 	};
 
 	StationGfx gfx = GetStationGfx(tile);
-	const AnimData* i;
-
-	for (i = data; i != endof(data); i++) {
+
+	for (const AnimData *i = data; i != endof(data); i++) {
 		if (i->from <= gfx && gfx <= i->to) {
 			if ((_tick_counter & i->delay) == 0) {
 				SetStationGfx(tile, gfx < i->to ? gfx + 1 : i->from);
@@ -2244,7 +2130,7 @@
 					x &= 0xF;
 					y &= 0xF;
 
-					if (DiagDirToAxis(dir) != AXIS_X) intswap(x, y);
+					if (DiagDirToAxis(dir) != AXIS_X) Swap(x, y);
 					if (y == TILE_SIZE / 2) {
 						if (dir != DIAGDIR_SE && dir != DIAGDIR_SW) x = TILE_SIZE - 1 - x;
 						if (x == 12) return VETSB_ENTERED_STATION | (station_id << VETS_STATION_ID_OFFSET); /* enter station */
@@ -2260,7 +2146,7 @@
 			}
 		}
 	} else if (v->type == VEH_Road) {
-		if (v->u.road.state < RVSB_IN_ROAD_STOP && v->u.road.frame == 0) {
+		if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) {
 			if (IsRoadStop(tile)) {
 				/* Attempt to allocate a parking bay in a road stop */
 				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
@@ -2317,22 +2203,18 @@
 
 static void UpdateStationRating(Station *st)
 {
-	GoodsEntry *ge;
-	int rating;
-	StationID index;
-	int waiting;
 	bool waiting_changed = false;
 
 	byte_inc_sat(&st->time_since_load);
 	byte_inc_sat(&st->time_since_unload);
 
-	ge = st->goods;
+	GoodsEntry *ge = st->goods;
 	do {
 		if (ge->enroute_from != INVALID_STATION) {
 			byte_inc_sat(&ge->enroute_time);
 			byte_inc_sat(&ge->days_since_pickup);
 
-			rating = 0;
+			int rating = 0;
 
 			{
 				int b = ge->last_speed;
@@ -2361,15 +2243,13 @@
 				(rating += 35, true);
 			}
 
-			{
-				waiting = GB(ge->waiting_acceptance, 0, 12);
-				(rating -= 90, waiting > 1500) ||
-				(rating += 55, waiting > 1000) ||
-				(rating += 35, waiting > 600) ||
-				(rating += 10, waiting > 300) ||
-				(rating += 20, waiting > 100) ||
-				(rating += 10, true);
-			}
+			int waiting = GB(ge->waiting_acceptance, 0, 12);
+			(rating -= 90, waiting > 1500) ||
+			(rating += 55, waiting > 1000) ||
+			(rating += 35, waiting > 600) ||
+			(rating += 10, waiting > 300) ||
+			(rating += 20, waiting > 100) ||
+			(rating += 10, true);
 
 			{
 				int or_ = ge->rating; // old rating
@@ -2399,8 +2279,7 @@
 		}
 	} while (++ge != endof(st->goods));
 
-	index = st->index;
-
+	StationID index = st->index;
 	if (waiting_changed) {
 		InvalidateWindow(WC_STATION_VIEW, index);
 	} else {
@@ -2411,11 +2290,9 @@
 /* called for every station each tick */
 static void StationHandleSmallTick(Station *st)
 {
-	byte b;
-
 	if (st->facilities == 0) return;
 
-	b = st->delete_ctr + 1;
+	byte b = st->delete_ctr + 1;
 	if (b >= 185) b = 0;
 	st->delete_ctr = b;
 
@@ -2424,19 +2301,15 @@
 
 void OnTick_Station(void)
 {
-	uint i;
-	Station *st;
-
 	if (_game_mode == GM_EDITOR) return;
 
-	i = _station_tick_ctr;
+	uint i = _station_tick_ctr;
 	if (++_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
 
 	if (IsValidStationID(i)) StationHandleBigTick(GetStation(i));
 
-	FOR_ALL_STATIONS(st) {
-		StationHandleSmallTick(st);
-	}
+	Station *st;
+	FOR_ALL_STATIONS(st) StationHandleSmallTick(st);
 }
 
 void StationMonthlyLoop(void)
@@ -2451,9 +2324,7 @@
 	FOR_ALL_STATIONS(st) {
 		if (st->owner == owner &&
 				DistanceManhattan(tile, st->xy) <= radius) {
-			uint i;
-
-			for (i = 0; i != NUM_CARGO; i++) {
+			for (uint i = 0; i != NUM_CARGO; i++) {
 				GoodsEntry* ge = &st->goods[i];
 
 				if (ge->enroute_from != INVALID_STATION) {
@@ -2484,15 +2355,12 @@
  */
 int32 CmdRenameStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	StringID str;
-	Station *st;
-
 	if (!IsValidStationID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
-	st = GetStation(p1);
+	Station *st = GetStation(p1);
 
 	if (!CheckOwnership(st->owner)) return CMD_ERROR;
 
-	str = AllocateNameUnique(_cmd_text, 6);
+	StringID str = AllocateNameUnique(_cmd_text, 6);
 	if (str == 0) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
@@ -2514,18 +2382,12 @@
 uint MoveGoodsToStation(TileIndex tile, int w, int h, int type, uint amount)
 {
 	Station* around[8];
-	uint i;
-	uint moved;
-	uint best_rating, best_rating2;
-	Station *st1, *st2;
-	uint t;
-	int rad = 0;
+
+	for (uint i = 0; i < lengthof(around); i++) around[i] = NULL;
+
 	int w_prod; //width and height of the "producer" of the cargo
 	int h_prod;
 	int max_rad;
-
-	for (i = 0; i < lengthof(around); i++) around[i] = NULL;
-
 	if (_patches.modified_catchment) {
 		w_prod = w;
 		h_prod = h;
@@ -2541,14 +2403,12 @@
 	}
 
 	BEGIN_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad))
-		Station* st;
-
 		cur_tile = TILE_MASK(cur_tile);
 		if (!IsTileType(cur_tile, MP_STATION)) continue;
 
-		st = GetStationByTile(cur_tile);
-
-		for (i = 0; i != lengthof(around); i++) {
+		Station *st = GetStationByTile(cur_tile);
+
+		for (uint i = 0; i != lengthof(around); i++) {
 			if (around[i] == NULL) {
 				if (!st->IsBuoy() &&
 						(st->town->exclusive_counter == 0 || st->town->exclusivity == st->owner) && // check exclusive transport rights
@@ -2556,9 +2416,6 @@
 						(!_patches.selectgoods || st->goods[type].last_speed > 0) && // if last_speed is 0, no vehicle has been there.
 						((st->facilities & ~FACIL_BUS_STOP)   != 0 || type == CT_PASSENGERS) && // if we have other fac. than a bus stop, or the cargo is passengers
 						((st->facilities & ~FACIL_TRUCK_STOP) != 0 || type != CT_PASSENGERS)) { // if we have other fac. than a cargo bay or the cargo is not passengers
-					int x_dist;
-					int y_dist;
-
 					if (_patches.modified_catchment) {
 						// min and max coordinates of the producer relative
 						const int x_min_prod = 9;
@@ -2566,27 +2423,26 @@
 						const int y_min_prod = 9;
 						const int y_max_prod = 8 + h_prod;
 
-						rad = FindCatchmentRadius(st);
-
-						x_dist = min(w_cur - x_min_prod, x_max_prod - w_cur);
+						int rad = FindCatchmentRadius(st);
+
+						int x_dist = min(w_cur - x_min_prod, x_max_prod - w_cur);
 						if (w_cur < x_min_prod) {
 							x_dist = x_min_prod - w_cur;
 						} else if (w_cur > x_max_prod) {
 							x_dist = w_cur - x_max_prod;
 						}
 
-						y_dist = min(h_cur - y_min_prod, y_max_prod - h_cur);
+						int y_dist = min(h_cur - y_min_prod, y_max_prod - h_cur);
 						if (h_cur < y_min_prod) {
 							y_dist = y_min_prod - h_cur;
 						} else if (h_cur > y_max_prod) {
 							y_dist = h_cur - y_max_prod;
 						}
-					} else {
-						x_dist = 0;
-						y_dist = 0;
+
+						if (x_dist > rad || y_dist > rad) break;
 					}
 
-					if (x_dist <= rad && y_dist <= rad) around[i] = st;
+					around[i] = st;
 				}
 				break;
 			} else if (around[i] == st) {
@@ -2600,16 +2456,18 @@
 
 	if (around[1] == NULL) {
 		/* only one station around */
-		moved = (amount * around[0]->goods[type].rating >> 8) + 1;
+		uint moved = (amount * around[0]->goods[type].rating >> 8) + 1;
 		UpdateStationWaiting(around[0], type, moved);
 		return moved;
 	}
 
 	/* several stations around, find the two with the highest rating */
-	st2 = st1 = NULL;
-	best_rating = best_rating2 = 0;
-
-	for (i = 0; i != lengthof(around) && around[i] != NULL; i++) {
+	Station *st1 = NULL;
+	Station *st2 = NULL;
+	uint best_rating  = 0;
+	uint best_rating2 = 0;
+
+	for (uint i = 0; i != lengthof(around) && around[i] != NULL; i++) {
 		if (around[i]->goods[type].rating >= best_rating) {
 			best_rating2 = best_rating;
 			st2 = st1;
@@ -2630,9 +2488,9 @@
 	best_rating2 >>= 1;
 
 	/* amount given to station 1 */
-	t = (best_rating * (amount + 1)) / (best_rating + best_rating2);
-
-	moved = 0;
+	uint t = (best_rating * (amount + 1)) / (best_rating + best_rating2);
+
+	uint moved = 0;
 	if (t != 0) {
 		moved = t * best_rating / 256 + 1;
 		amount -= t;
@@ -2650,7 +2508,6 @@
 
 void BuildOilRig(TileIndex tile)
 {
-	uint j;
 	Station *st = new Station();
 
 	if (st == NULL) {
@@ -2684,7 +2541,7 @@
 	st->facilities = FACIL_AIRPORT | FACIL_DOCK;
 	st->build_date = _date;
 
-	for (j = 0; j != NUM_CARGO; j++) {
+	for (uint j = 0; j != NUM_CARGO; j++) {
 		st->goods[j].waiting_acceptance = 0;
 		st->goods[j].days_since_pickup = 0;
 		st->goods[j].enroute_from = INVALID_STATION;
@@ -2724,14 +2581,33 @@
 		RebuildStationLists();
 		InvalidateWindowClasses(WC_STATION_LIST);
 	} else {
-		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+		if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile)) {
+			/* For a drive-through stop on a town-owned road remove the stop and replace the road */
+			DoCommand(tile, 0, (GetStationType(tile) == STATION_TRUCK) ? RoadStop::TRUCK : RoadStop::BUS, DC_EXEC, CMD_REMOVE_ROAD_STOP);
+		} else {
+			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+		}
 	}
 }
 
+/**
+ * Check if a drive-through road stop tile can be cleared.
+ * Road stops built on town-owned roads check the conditions
+ * that would allow clearing of the original road.
+ * @param tile road stop tile to check
+ * @return true if the road can be cleared
+ */
+static bool CanRemoveRoadWithStop(TileIndex tile)
+{
+	/* The road can always be cleared if it was not a town-owned road */
+	if (!GetStopBuiltOnTownRoad(tile)) return true;
+
+	bool edge_road;
+	return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile), OWNER_TOWN, &edge_road);
+}
+
 static int32 ClearTile_Station(TileIndex tile, byte flags)
 {
-	Station *st;
-
 	if (flags & DC_AUTO) {
 		switch (GetStationType(tile)) {
 			case STATION_RAIL:    return_cmd_error(STR_300B_MUST_DEMOLISH_RAILROAD);
@@ -2746,17 +2622,17 @@
 		}
 	}
 
-	st = GetStationByTile(tile);
+	Station *st = GetStationByTile(tile);
 
 	switch (GetStationType(tile)) {
 		case STATION_RAIL:    return RemoveRailroadStation(st, tile, flags);
 		case STATION_AIRPORT: return RemoveAirport(st, flags);
 		case STATION_TRUCK:
-			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
+			if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile))
 				return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION);
 			return RemoveRoadStop(st, flags, tile);
 		case STATION_BUS:
-			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
+			if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile))
 				return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION);
 			return RemoveRoadStop(st, flags, tile);
 		case STATION_BUOY:    return RemoveBuoy(st, flags);
@@ -2784,24 +2660,15 @@
 
 void AfterLoadStations(void)
 {
+	/* Update the speclists of all stations to point to the currently loaded custom stations. */
 	Station *st;
-	uint i;
-	TileIndex tile;
-
-	/* Update the speclists of all stations to point to the currently loaded custom stations. */
 	FOR_ALL_STATIONS(st) {
-		for (i = 0; i < st->num_specs; i++) {
+		for (uint i = 0; i < st->num_specs; i++) {
 			if (st->speclist[i].grfid == 0) continue;
 
 			st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
 		}
 	}
-
-	for (tile = 0; tile < MapSize(); tile++) {
-		if (GetTileType(tile) != MP_STATION) continue;
-		st = GetStationByTile(tile);
-		st->rect.BeforeAddTile(tile, StationRect::ADD_FORCE);
-	}
 }
 
 
@@ -2920,10 +2787,8 @@
 
 static void SaveLoad_STNS(Station *st)
 {
-	uint i;
-
 	SlObject(st, _station_desc);
-	for (i = 0; i != NUM_CARGO; i++) {
+	for (uint i = 0; i != NUM_CARGO; i++) {
 		SlObject(&st->goods[i], _goods_desc);
 
 		/* In older versions, enroute_from had 0xFF as INVALID_STATION, is now 0xFFFF */
@@ -2942,7 +2807,9 @@
 	if (st->num_specs != 0) {
 		/* Allocate speclist memory when loading a game */
 		if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
-		for (i = 0; i < st->num_specs; i++) SlObject(&st->speclist[i], _station_speclist_desc);
+		for (uint i = 0; i < st->num_specs; i++) {
+			SlObject(&st->speclist[i], _station_speclist_desc);
+		}
 	}
 }
 
@@ -2969,7 +2836,7 @@
 			uint w = GB(st->trainst_w, 4, 4);
 			uint h = GB(st->trainst_w, 0, 4);
 
-			if (GetRailStationAxis(st->train_tile) == AXIS_Y) uintswap(w, h);
+			if (GetRailStationAxis(st->train_tile) != AXIS_X) Swap(w, h);
 			st->trainst_w = w;
 			st->trainst_h = h;
 		}
@@ -3004,5 +2871,3 @@
 	{ 'STNS', Save_STNS,      Load_STNS,      CH_ARRAY },
 	{ 'ROAD', Save_ROADSTOP,  Load_ROADSTOP,  CH_ARRAY | CH_LAST},
 };
-
-