src/road_cmd.cpp
changeset 5835 e0ff603ae0b7
parent 5726 8f399788f6c9
child 5650 aefc131bf5ce
equal deleted inserted replaced
5834:7bf92d5a5a0f 5835:e0ff603ae0b7
       
     1 /* $Id$ */
       
     2 
       
     3 #include "stdafx.h"
       
     4 #include "openttd.h"
       
     5 #include "bridge_map.h"
       
     6 #include "rail_map.h"
       
     7 #include "road_map.h"
       
     8 #include "sprite.h"
       
     9 #include "table/sprites.h"
       
    10 #include "table/strings.h"
       
    11 #include "functions.h"
       
    12 #include "map.h"
       
    13 #include "tile.h"
       
    14 #include "town_map.h"
       
    15 #include "vehicle.h"
       
    16 #include "viewport.h"
       
    17 #include "command.h"
       
    18 #include "player.h"
       
    19 #include "town.h"
       
    20 #include "gfx.h"
       
    21 #include "sound.h"
       
    22 #include "yapf/yapf.h"
       
    23 #include "depot.h"
       
    24 
       
    25 
       
    26 static uint CountRoadBits(RoadBits r)
       
    27 {
       
    28 	uint count = 0;
       
    29 
       
    30 	if (r & ROAD_NW) ++count;
       
    31 	if (r & ROAD_SW) ++count;
       
    32 	if (r & ROAD_SE) ++count;
       
    33 	if (r & ROAD_NE) ++count;
       
    34 	return count;
       
    35 }
       
    36 
       
    37 
       
    38 static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool* edge_road)
       
    39 {
       
    40 	RoadBits present;
       
    41 	RoadBits n;
       
    42 	Owner owner;
       
    43 	*edge_road = true;
       
    44 
       
    45 	if (_game_mode == GM_EDITOR) return true;
       
    46 
       
    47 	// Only do the special processing for actual players.
       
    48 	if (!IsValidPlayer(_current_player)) return true;
       
    49 
       
    50 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
       
    51 
       
    52 	// Only do the special processing if the road is owned
       
    53 	// by a town
       
    54 	if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner);
       
    55 
       
    56 	if (_cheats.magic_bulldozer.value) return true;
       
    57 
       
    58 	// Get a bitmask of which neighbouring roads has a tile
       
    59 	n = 0;
       
    60 	present = GetAnyRoadBits(tile);
       
    61 	if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile,-1, 0)) & ROAD_SW) n |= ROAD_NE;
       
    62 	if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE;
       
    63 	if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW;
       
    64 	if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0,-1)) & ROAD_SE) n |= ROAD_NW;
       
    65 
       
    66 	// If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
       
    67 	// then allow it
       
    68 	if ((n & (n - 1)) != 0 && (n & remove) != 0) {
       
    69 		Town *t;
       
    70 		*edge_road = false;
       
    71 		// you can remove all kind of roads with extra dynamite
       
    72 		if (_patches.extra_dynamite) return true;
       
    73 
       
    74 		t = ClosestTownFromTile(tile, _patches.dist_local_authority);
       
    75 
       
    76 		SetDParam(0, t->index);
       
    77 		_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
       
    78 		return false;
       
    79 	}
       
    80 
       
    81 	return true;
       
    82 }
       
    83 
       
    84 
       
    85 /** Delete a piece of road.
       
    86  * @param tile tile where to remove road from
       
    87  * @param p1 road piece flags
       
    88  * @param p2 unused
       
    89  */
       
    90 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
    91 {
       
    92 	// cost for removing inner/edge -roads
       
    93 	static const uint16 road_remove_cost[2] = {50, 18};
       
    94 
       
    95 	Owner owner;
       
    96 	Town *t;
       
    97 	/* true if the roadpiece was always removeable,
       
    98 	 * false if it was a center piece. Affects town ratings drop */
       
    99 	bool edge_road;
       
   100 	RoadBits pieces;
       
   101 
       
   102 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   103 
       
   104 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
       
   105 	if (p1 >> 4) return CMD_ERROR;
       
   106 	pieces = p1;
       
   107 
       
   108 	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
       
   109 
       
   110 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
       
   111 
       
   112 	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
       
   113 		t = GetTownByTile(tile);
       
   114 	} else {
       
   115 		t = NULL;
       
   116 	}
       
   117 
       
   118 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
       
   119 
       
   120 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
       
   121 
       
   122 	// check if you're allowed to remove the street owned by a town
       
   123 	// removal allowance depends on difficulty setting
       
   124 	if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
       
   125 
       
   126 	switch (GetRoadTileType(tile)) {
       
   127 		case ROAD_TILE_NORMAL: {
       
   128 			RoadBits present = GetRoadBits(tile);
       
   129 			RoadBits c = pieces;
       
   130 
       
   131 			if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
       
   132 
       
   133 			if (GetTileSlope(tile, NULL) != SLOPE_FLAT  &&
       
   134 					(present == ROAD_Y || present == ROAD_X)) {
       
   135 				c |= (c & 0xC) >> 2;
       
   136 				c |= (c & 0x3) << 2;
       
   137 			}
       
   138 
       
   139 			// limit the bits to delete to the existing bits.
       
   140 			c &= present;
       
   141 			if (c == 0) return CMD_ERROR;
       
   142 
       
   143 			if (flags & DC_EXEC) {
       
   144 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
       
   145 
       
   146 				present ^= c;
       
   147 				if (present == 0) {
       
   148 					DoClearSquare(tile);
       
   149 				} else {
       
   150 					SetRoadBits(tile, present);
       
   151 					MarkTileDirtyByTile(tile);
       
   152 				}
       
   153 			}
       
   154 			return CountRoadBits(c) * _price.remove_road;
       
   155 		}
       
   156 
       
   157 		case ROAD_TILE_CROSSING: {
       
   158 			if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
       
   159 				return CMD_ERROR;
       
   160 			}
       
   161 
       
   162 			if (flags & DC_EXEC) {
       
   163 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
       
   164 
       
   165 				MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile));
       
   166 				MarkTileDirtyByTile(tile);
       
   167 				YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(GetTrackBits(tile)));
       
   168 			}
       
   169 			return _price.remove_road * 2;
       
   170 		}
       
   171 
       
   172 		default:
       
   173 		case ROAD_TILE_DEPOT:
       
   174 			return CMD_ERROR;
       
   175 	}
       
   176 }
       
   177 
       
   178 
       
   179 static const RoadBits _valid_tileh_slopes_road[][15] = {
       
   180 	// set of normal ones
       
   181 	{
       
   182 		ROAD_ALL, 0, 0,
       
   183 		ROAD_X,   0, 0,  // 3, 4, 5
       
   184 		ROAD_Y,   0, 0,
       
   185 		ROAD_Y,   0, 0,  // 9, 10, 11
       
   186 		ROAD_X,   0, 0
       
   187 	},
       
   188 	// allowed road for an evenly raised platform
       
   189 	{
       
   190 		0,
       
   191 		ROAD_SW | ROAD_NW,
       
   192 		ROAD_SW | ROAD_SE,
       
   193 		ROAD_Y  | ROAD_SW,
       
   194 
       
   195 		ROAD_SE | ROAD_NE, // 4
       
   196 		ROAD_ALL,
       
   197 		ROAD_X  | ROAD_SE,
       
   198 		ROAD_ALL,
       
   199 
       
   200 		ROAD_NW | ROAD_NE, // 8
       
   201 		ROAD_X  | ROAD_NW,
       
   202 		ROAD_ALL,
       
   203 		ROAD_ALL,
       
   204 
       
   205 		ROAD_Y  | ROAD_NE, // 12
       
   206 		ROAD_ALL,
       
   207 		ROAD_ALL
       
   208 	},
       
   209 };
       
   210 
       
   211 
       
   212 static uint32 CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
       
   213 {
       
   214 	RoadBits road_bits;
       
   215 
       
   216 	if (IsSteepSlope(tileh)) {
       
   217 		if (existing == 0) {
       
   218 			// force full pieces.
       
   219 			*pieces |= (*pieces & 0xC) >> 2;
       
   220 			*pieces |= (*pieces & 0x3) << 2;
       
   221 			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
       
   222 		}
       
   223 		return CMD_ERROR;
       
   224 	}
       
   225 	road_bits = *pieces | existing;
       
   226 
       
   227 	// no special foundation
       
   228 	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
       
   229 		// force that all bits are set when we have slopes
       
   230 		if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
       
   231 		return 0; // no extra cost
       
   232 	}
       
   233 
       
   234 	// foundation is used. Whole tile is leveled up
       
   235 	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
       
   236 		return existing != 0 ? 0 : _price.terraform;
       
   237 	}
       
   238 
       
   239 	// partly leveled up tile, only if there's no road on that tile
       
   240 	if (existing == 0 && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
       
   241 		// force full pieces.
       
   242 		*pieces |= (*pieces & 0xC) >> 2;
       
   243 		*pieces |= (*pieces & 0x3) << 2;
       
   244 		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
       
   245 	}
       
   246 	return CMD_ERROR;
       
   247 }
       
   248 
       
   249 /** Build a piece of road.
       
   250  * @param tile tile where to build road
       
   251  * @param p1 road piece flags
       
   252  * @param p2 the town that is building the road (0 if not applicable)
       
   253  */
       
   254 int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
   255 {
       
   256 	int32 cost = 0;
       
   257 	int32 ret;
       
   258 	RoadBits existing = 0;
       
   259 	RoadBits pieces;
       
   260 	Slope tileh;
       
   261 
       
   262 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   263 
       
   264 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
       
   265 	 * if a non-player is building the road */
       
   266 	if ((p1 >> 4) || (IsValidPlayer(_current_player) && p2 != 0) || !IsValidTownID(p2)) return CMD_ERROR;
       
   267 	pieces = p1;
       
   268 
       
   269 	tileh = GetTileSlope(tile, NULL);
       
   270 
       
   271 	switch (GetTileType(tile)) {
       
   272 		case MP_STREET:
       
   273 			switch (GetRoadTileType(tile)) {
       
   274 				case ROAD_TILE_NORMAL:
       
   275 					if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
       
   276 
       
   277 					existing = GetRoadBits(tile);
       
   278 					if ((existing & pieces) == pieces) {
       
   279 						return_cmd_error(STR_1007_ALREADY_BUILT);
       
   280 					}
       
   281 					if (!EnsureNoVehicle(tile)) return CMD_ERROR;
       
   282 					break;
       
   283 
       
   284 				case ROAD_TILE_CROSSING:
       
   285 					if (pieces != GetCrossingRoadBits(tile)) { // XXX is this correct?
       
   286 						return_cmd_error(STR_1007_ALREADY_BUILT);
       
   287 					}
       
   288 					goto do_clear;
       
   289 
       
   290 				default:
       
   291 				case ROAD_TILE_DEPOT:
       
   292 					goto do_clear;
       
   293 			}
       
   294 			break;
       
   295 
       
   296 		case MP_RAILWAY: {
       
   297 			Axis roaddir;
       
   298 
       
   299 			if (IsSteepSlope(tileh)) {
       
   300 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   301 			}
       
   302 
       
   303 #define M(x) (1 << (x))
       
   304 			/* Level crossings may only be built on these slopes */
       
   305 			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
       
   306 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   307 			}
       
   308 #undef M
       
   309 
       
   310 			if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear;
       
   311 			switch (GetTrackBits(tile)) {
       
   312 				case TRACK_BIT_X:
       
   313 					if (pieces & ROAD_X) goto do_clear;
       
   314 					roaddir = AXIS_Y;
       
   315 					break;
       
   316 
       
   317 				case TRACK_BIT_Y:
       
   318 					if (pieces & ROAD_Y) goto do_clear;
       
   319 					roaddir = AXIS_X;
       
   320 					break;
       
   321 
       
   322 				default: goto do_clear;
       
   323 			}
       
   324 
       
   325 			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
       
   326 
       
   327 			if (flags & DC_EXEC) {
       
   328 				YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(GetTrackBits(tile)));
       
   329 				MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2);
       
   330 				MarkTileDirtyByTile(tile);
       
   331 			}
       
   332 			return _price.build_road * 2;
       
   333 		}
       
   334 
       
   335 		default:
       
   336 do_clear:;
       
   337 			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
       
   338 			if (CmdFailed(ret)) return ret;
       
   339 			cost += ret;
       
   340 	}
       
   341 
       
   342 	ret = CheckRoadSlope(tileh, &pieces, existing);
       
   343 	/* Return an error if we need to build a foundation (ret != 0) but the
       
   344 	 * current patch-setting is turned off (or stupid AI@work) */
       
   345 	if (CmdFailed(ret) || (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player)))
       
   346 		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   347 
       
   348 	cost += ret;
       
   349 
       
   350 	if (IsTileType(tile, MP_STREET)) {
       
   351 		// Don't put the pieces that already exist
       
   352 		pieces &= ComplementRoadBits(existing);
       
   353 	}
       
   354 
       
   355 	cost += CountRoadBits(pieces) * _price.build_road;
       
   356 
       
   357 	if (flags & DC_EXEC) {
       
   358 		if (IsTileType(tile, MP_STREET)) {
       
   359 			SetRoadBits(tile, existing | pieces);
       
   360 		} else {
       
   361 			MakeRoadNormal(tile, _current_player, pieces, p2);
       
   362 		}
       
   363 
       
   364 		MarkTileDirtyByTile(tile);
       
   365 	}
       
   366 	return cost;
       
   367 }
       
   368 
       
   369 int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
       
   370 {
       
   371 	// not a railroad crossing?
       
   372 	if (!IsLevelCrossing(tile)) return CMD_ERROR;
       
   373 
       
   374 	// not owned by me?
       
   375 	if (!CheckTileOwnership(tile) || !EnsureNoVehicle(tile)) return CMD_ERROR;
       
   376 
       
   377 	if (GetRailTypeCrossing(tile) == totype) return CMD_ERROR;
       
   378 
       
   379 	// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
       
   380 	if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailTypeCrossing(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
       
   381 
       
   382 	if (exec) {
       
   383 		SetRailTypeCrossing(tile, totype);
       
   384 		MarkTileDirtyByTile(tile);
       
   385 		YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(GetCrossingRailBits(tile)));
       
   386 	}
       
   387 
       
   388 	return _price.build_rail >> 1;
       
   389 }
       
   390 
       
   391 
       
   392 /** Build a long piece of road.
       
   393  * @param end_tile end tile of drag
       
   394  * @param p1 start tile of drag
       
   395  * @param p2 various bitstuffed elements
       
   396  * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
       
   397  * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
       
   398  * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
       
   399  */
       
   400 int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
       
   401 {
       
   402 	TileIndex start_tile, tile;
       
   403 	int32 cost, ret;
       
   404 
       
   405 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   406 
       
   407 	if (p1 >= MapSize()) return CMD_ERROR;
       
   408 
       
   409 	start_tile = p1;
       
   410 
       
   411 	/* Only drag in X or Y direction dictated by the direction variable */
       
   412 	if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
       
   413 	if (HASBIT(p2, 2)  && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
       
   414 
       
   415 	/* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
       
   416 	if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
       
   417 		TileIndex t = start_tile;
       
   418 		start_tile = end_tile;
       
   419 		end_tile = t;
       
   420 		p2 ^= IS_INT_INSIDE(p2&3, 1, 3) ? 3 : 0;
       
   421 	}
       
   422 
       
   423 	cost = 0;
       
   424 	tile = start_tile;
       
   425 	// Start tile is the small number.
       
   426 	for (;;) {
       
   427 		RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X;
       
   428 
       
   429 		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
       
   430 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
       
   431 
       
   432 		ret = DoCommand(tile, bits, 0, flags, CMD_BUILD_ROAD);
       
   433 		if (CmdFailed(ret)) {
       
   434 			if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
       
   435 			_error_message = INVALID_STRING_ID;
       
   436 		} else {
       
   437 			cost += ret;
       
   438 		}
       
   439 
       
   440 		if (tile == end_tile) break;
       
   441 
       
   442 		tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
       
   443 	}
       
   444 
       
   445 	return (cost == 0) ? CMD_ERROR : cost;
       
   446 }
       
   447 
       
   448 /** Remove a long piece of road.
       
   449  * @param end_tile end tile of drag
       
   450  * @param p1 start tile of drag
       
   451  * @param p2 various bitstuffed elements
       
   452  * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
       
   453  * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
       
   454  * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
       
   455  */
       
   456 int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
       
   457 {
       
   458 	TileIndex start_tile, tile;
       
   459 	int32 cost, ret;
       
   460 
       
   461 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   462 
       
   463 	if (p1 >= MapSize()) return CMD_ERROR;
       
   464 
       
   465 	start_tile = p1;
       
   466 
       
   467 	/* Only drag in X or Y direction dictated by the direction variable */
       
   468 	if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
       
   469 	if (HASBIT(p2, 2)  && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
       
   470 
       
   471 	/* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
       
   472 	if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
       
   473 		TileIndex t = start_tile;
       
   474 		start_tile = end_tile;
       
   475 		end_tile = t;
       
   476 		p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
       
   477 	}
       
   478 
       
   479 	cost = 0;
       
   480 	tile = start_tile;
       
   481 	// Start tile is the small number.
       
   482 	for (;;) {
       
   483 		RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X;
       
   484 
       
   485 		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
       
   486 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
       
   487 
       
   488 		// try to remove the halves.
       
   489 		if (bits != 0) {
       
   490 			ret = DoCommand(tile, bits, 0, flags, CMD_REMOVE_ROAD);
       
   491 			if (!CmdFailed(ret)) cost += ret;
       
   492 		}
       
   493 
       
   494 		if (tile == end_tile) break;
       
   495 
       
   496 		tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
       
   497 	}
       
   498 
       
   499 	return (cost == 0) ? CMD_ERROR : cost;
       
   500 }
       
   501 
       
   502 /** Build a road depot.
       
   503  * @param tile tile where to build the depot
       
   504  * @param p1 entrance direction (DiagDirection)
       
   505  * @param p2 unused
       
   506  *
       
   507  * @todo When checking for the tile slope,
       
   508  * distingush between "Flat land required" and "land sloped in wrong direction"
       
   509  */
       
   510 int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
   511 {
       
   512 	int32 cost;
       
   513 	Depot *dep;
       
   514 	Slope tileh;
       
   515 
       
   516 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   517 
       
   518 	if (p1 > 3) return CMD_ERROR; // check direction
       
   519 
       
   520 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
       
   521 
       
   522 	tileh = GetTileSlope(tile, NULL);
       
   523 	if (tileh != SLOPE_FLAT && (
       
   524 				!_patches.build_on_slopes ||
       
   525 				IsSteepSlope(tileh) ||
       
   526 				!CanBuildDepotByTileh(p1, tileh)
       
   527 			)) {
       
   528 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
       
   529 	}
       
   530 
       
   531 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
       
   532 	if (CmdFailed(cost)) return CMD_ERROR;
       
   533 
       
   534 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
       
   535 
       
   536 	dep = AllocateDepot();
       
   537 	if (dep == NULL) return CMD_ERROR;
       
   538 
       
   539 	if (flags & DC_EXEC) {
       
   540 		dep->xy = tile;
       
   541 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
       
   542 
       
   543 		MakeRoadDepot(tile, _current_player, p1);
       
   544 		MarkTileDirtyByTile(tile);
       
   545 	}
       
   546 	return cost + _price.build_road_depot;
       
   547 }
       
   548 
       
   549 static int32 RemoveRoadDepot(TileIndex tile, uint32 flags)
       
   550 {
       
   551 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
       
   552 		return CMD_ERROR;
       
   553 
       
   554 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
       
   555 
       
   556 	if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
       
   557 
       
   558 	return _price.remove_road_depot;
       
   559 }
       
   560 
       
   561 #define M(x) (1<<(x))
       
   562 
       
   563 static int32 ClearTile_Road(TileIndex tile, byte flags)
       
   564 {
       
   565 	switch (GetRoadTileType(tile)) {
       
   566 		case ROAD_TILE_NORMAL: {
       
   567 			RoadBits b = GetRoadBits(tile);
       
   568 
       
   569 			if (!((1 << b) & (M(1)|M(2)|M(4)|M(8))) &&
       
   570 					(!(flags & DC_AI_BUILDING) || !IsTileOwner(tile, OWNER_TOWN)) &&
       
   571 					flags & DC_AUTO) {
       
   572 				return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
       
   573 			}
       
   574 			return DoCommand(tile, b, 0, flags, CMD_REMOVE_ROAD);
       
   575 		}
       
   576 
       
   577 		case ROAD_TILE_CROSSING: {
       
   578 			int32 ret;
       
   579 
       
   580 			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
       
   581 
       
   582 			ret = DoCommand(tile, GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
       
   583 			if (CmdFailed(ret)) return CMD_ERROR;
       
   584 
       
   585 			if (flags & DC_EXEC) {
       
   586 				DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
       
   587 			}
       
   588 			return ret;
       
   589 		}
       
   590 
       
   591 		default:
       
   592 		case ROAD_TILE_DEPOT:
       
   593 			if (flags & DC_AUTO) {
       
   594 				return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
       
   595 			}
       
   596 			return RemoveRoadDepot(tile, flags);
       
   597 	}
       
   598 }
       
   599 
       
   600 
       
   601 typedef struct DrawRoadTileStruct {
       
   602 	uint16 image;
       
   603 	byte subcoord_x;
       
   604 	byte subcoord_y;
       
   605 } DrawRoadTileStruct;
       
   606 
       
   607 #include "table/road_land.h"
       
   608 
       
   609 
       
   610 uint GetRoadFoundation(Slope tileh, RoadBits bits)
       
   611 {
       
   612 	uint i;
       
   613 
       
   614 	// normal level sloped building
       
   615 	if (!IsSteepSlope(tileh) &&
       
   616 			(~_valid_tileh_slopes_road[1][tileh] & bits) == 0) {
       
   617 		return tileh;
       
   618 	}
       
   619 
       
   620 	// inclined sloped building
       
   621 	switch (bits) {
       
   622 		case ROAD_X: i = 0; break;
       
   623 		case ROAD_Y: i = 1; break;
       
   624 		default:     return 0;
       
   625 	}
       
   626 	switch (tileh) {
       
   627 		case SLOPE_W:
       
   628 		case SLOPE_STEEP_W: i += 0; break;
       
   629 		case SLOPE_S:
       
   630 		case SLOPE_STEEP_S: i += 2; break;
       
   631 		case SLOPE_E:
       
   632 		case SLOPE_STEEP_E: i += 4; break;
       
   633 		case SLOPE_N:
       
   634 		case SLOPE_STEEP_N: i += 6; break;
       
   635 		default: return 0;
       
   636 	}
       
   637 	return i + 15;
       
   638 }
       
   639 
       
   640 const byte _road_sloped_sprites[14] = {
       
   641 	0,  0,  2,  0,
       
   642 	0,  1,  0,  0,
       
   643 	3,  0,  0,  0,
       
   644 	0,  0
       
   645 };
       
   646 
       
   647 /**
       
   648  * Draw ground sprite and road pieces
       
   649  * @param ti TileInfo
       
   650  * @param road RoadBits to draw
       
   651  */
       
   652 static void DrawRoadBits(TileInfo* ti)
       
   653 {
       
   654 	RoadBits road = GetRoadBits(ti->tile);
       
   655 	const DrawRoadTileStruct *drts;
       
   656 	PalSpriteID image = 0;
       
   657 	Roadside roadside;
       
   658 
       
   659 	if (ti->tileh != SLOPE_FLAT) {
       
   660 		int foundation = GetRoadFoundation(ti->tileh, road);
       
   661 
       
   662 		if (foundation != 0) DrawFoundation(ti, foundation);
       
   663 
       
   664 		// DrawFoundation() modifies ti.
       
   665 		// Default sloped sprites..
       
   666 		if (ti->tileh != SLOPE_FLAT) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
       
   667 	}
       
   668 
       
   669 	if (image == 0) image = _road_tile_sprites_1[road];
       
   670 
       
   671 	roadside = GetRoadside(ti->tile);
       
   672 
       
   673 	if (IsOnSnow(ti->tile)) {
       
   674 		image += 19;
       
   675 	} else {
       
   676 		switch (roadside) {
       
   677 			case ROADSIDE_BARREN:           image |= PALETTE_TO_BARE_LAND; break;
       
   678 			case ROADSIDE_GRASS:            break;
       
   679 			case ROADSIDE_GRASS_ROAD_WORKS: break;
       
   680 			default:                        image -= 19; break; // Paved
       
   681 		}
       
   682 	}
       
   683 
       
   684 	DrawGroundSprite(image);
       
   685 
       
   686 	if (HasRoadWorks(ti->tile)) {
       
   687 		// Road works
       
   688 		DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y);
       
   689 		return;
       
   690 	}
       
   691 
       
   692 	// Return if full detail is disabled, or we are zoomed fully out.
       
   693 	if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return;
       
   694 
       
   695 	// Draw extra details.
       
   696 	for (drts = _road_display_table[roadside][road]; drts->image != 0; drts++) {
       
   697 		int x = ti->x | drts->subcoord_x;
       
   698 		int y = ti->y | drts->subcoord_y;
       
   699 		byte z = ti->z;
       
   700 		if (ti->tileh != SLOPE_FLAT) z = GetSlopeZ(x, y);
       
   701 		AddSortableSpriteToDraw(drts->image, x, y, 2, 2, 0x10, z);
       
   702 	}
       
   703 }
       
   704 
       
   705 static void DrawTile_Road(TileInfo *ti)
       
   706 {
       
   707 	switch (GetRoadTileType(ti->tile)) {
       
   708 		case ROAD_TILE_NORMAL:
       
   709 			DrawRoadBits(ti);
       
   710 			break;
       
   711 
       
   712 		case ROAD_TILE_CROSSING: {
       
   713 			PalSpriteID image;
       
   714 
       
   715 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
       
   716 
       
   717 			image = GetRailTypeInfo(GetRailTypeCrossing(ti->tile))->base_sprites.crossing;
       
   718 
       
   719 			if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++;
       
   720 			if (IsCrossingBarred(ti->tile)) image += 2;
       
   721 
       
   722 			if (IsOnSnow(ti->tile)) {
       
   723 				image += 8;
       
   724 			} else {
       
   725 				switch (GetRoadside(ti->tile)) {
       
   726 					case ROADSIDE_BARREN: image |= PALETTE_TO_BARE_LAND; break;
       
   727 					case ROADSIDE_GRASS:  break;
       
   728 					default:              image += 4; break; // Paved
       
   729 				}
       
   730 			}
       
   731 
       
   732 			DrawGroundSprite(image);
       
   733 			if (GetRailTypeCrossing(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
       
   734 			break;
       
   735 		}
       
   736 
       
   737 		default:
       
   738 		case ROAD_TILE_DEPOT: {
       
   739 			const DrawTileSprites* dts;
       
   740 			const DrawTileSeqStruct* dtss;
       
   741 			uint32 palette;
       
   742 
       
   743 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
       
   744 
       
   745 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
       
   746 
       
   747 			dts =  &_road_depot[GetRoadDepotDirection(ti->tile)];
       
   748 			DrawGroundSprite(dts->ground_sprite);
       
   749 
       
   750 			for (dtss = dts->seq; dtss->image != 0; dtss++) {
       
   751 				uint32 image = dtss->image;
       
   752 
       
   753 				if (_display_opt & DO_TRANS_BUILDINGS) {
       
   754 					MAKE_TRANSPARENT(image);
       
   755 				} else if (image & PALETTE_MODIFIER_COLOR) {
       
   756 					image |= palette;
       
   757 				}
       
   758 
       
   759 				AddSortableSpriteToDraw(
       
   760 					image,
       
   761 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
       
   762 					dtss->size_x, dtss->size_y,
       
   763 					dtss->size_z, ti->z
       
   764 				);
       
   765 			}
       
   766 			break;
       
   767 		}
       
   768 	}
       
   769 	DrawBridgeMiddle(ti);
       
   770 }
       
   771 
       
   772 void DrawRoadDepotSprite(int x, int y, DiagDirection dir)
       
   773 {
       
   774 	uint32 palette = PLAYER_SPRITE_COLOR(_local_player);
       
   775 	const DrawTileSprites* dts =  &_road_depot[dir];
       
   776 	const DrawTileSeqStruct* dtss;
       
   777 
       
   778 	x += 33;
       
   779 	y += 17;
       
   780 
       
   781 	DrawSprite(dts->ground_sprite, x, y);
       
   782 
       
   783 	for (dtss = dts->seq; dtss->image != 0; dtss++) {
       
   784 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
       
   785 		uint32 image = dtss->image;
       
   786 
       
   787 		if (image & PALETTE_MODIFIER_COLOR) image |= palette;
       
   788 
       
   789 		DrawSprite(image, x + pt.x, y + pt.y);
       
   790 	}
       
   791 }
       
   792 
       
   793 static uint GetSlopeZ_Road(TileIndex tile, uint x, uint y)
       
   794 {
       
   795 	uint z;
       
   796 	Slope tileh = GetTileSlope(tile, &z);
       
   797 
       
   798 	if (tileh == SLOPE_FLAT) return z;
       
   799 	if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
       
   800 		uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
       
   801 
       
   802 		if (f != 0) {
       
   803 			if (IsSteepSlope(tileh)) {
       
   804 				z += TILE_HEIGHT;
       
   805 			} else if (f < 15) {
       
   806 				return z + TILE_HEIGHT; // leveled foundation
       
   807 			}
       
   808 			tileh = _inclined_tileh[f - 15]; // inclined foundation
       
   809 		}
       
   810 		return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
       
   811 	} else {
       
   812 		return z + TILE_HEIGHT;
       
   813 	}
       
   814 }
       
   815 
       
   816 static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh)
       
   817 {
       
   818 	if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
       
   819 	if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
       
   820 		uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
       
   821 
       
   822 		if (f == 0) return tileh;
       
   823 		if (f < 15) return SLOPE_FLAT; // leveled foundation
       
   824 		return _inclined_tileh[f - 15]; // inclined foundation
       
   825 	} else {
       
   826 		return SLOPE_FLAT;
       
   827 	}
       
   828 }
       
   829 
       
   830 static void GetAcceptedCargo_Road(TileIndex tile, AcceptedCargo ac)
       
   831 {
       
   832 	/* not used */
       
   833 }
       
   834 
       
   835 static void AnimateTile_Road(TileIndex tile)
       
   836 {
       
   837 	if (IsLevelCrossing(tile)) MarkTileDirtyByTile(tile);
       
   838 }
       
   839 
       
   840 
       
   841 static const Roadside _town_road_types[][2] = {
       
   842 	{ ROADSIDE_GRASS,         ROADSIDE_GRASS },
       
   843 	{ ROADSIDE_PAVED,         ROADSIDE_PAVED },
       
   844 	{ ROADSIDE_PAVED,         ROADSIDE_PAVED },
       
   845 	{ ROADSIDE_TREES,         ROADSIDE_TREES },
       
   846 	{ ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED }
       
   847 };
       
   848 
       
   849 static const Roadside _town_road_types_2[][2] = {
       
   850 	{ ROADSIDE_GRASS,         ROADSIDE_GRASS },
       
   851 	{ ROADSIDE_PAVED,         ROADSIDE_PAVED },
       
   852 	{ ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED },
       
   853 	{ ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED },
       
   854 	{ ROADSIDE_STREET_LIGHTS, ROADSIDE_PAVED }
       
   855 };
       
   856 
       
   857 
       
   858 static void TileLoop_Road(TileIndex tile)
       
   859 {
       
   860 	switch (_opt.landscape) {
       
   861 		case LT_HILLY:
       
   862 			if (IsOnSnow(tile) != (GetTileZ(tile) > _opt.snow_line)) {
       
   863 				ToggleSnow(tile);
       
   864 				MarkTileDirtyByTile(tile);
       
   865 			}
       
   866 			break;
       
   867 
       
   868 		case LT_DESERT:
       
   869 			if (GetTropicZone(tile) == TROPICZONE_DESERT && !IsOnDesert(tile)) {
       
   870 				ToggleDesert(tile);
       
   871 				MarkTileDirtyByTile(tile);
       
   872 			}
       
   873 			break;
       
   874 	}
       
   875 
       
   876 	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) return;
       
   877 
       
   878 	if (!HasRoadWorks(tile)) {
       
   879 		const Town* t = ClosestTownFromTile(tile, (uint)-1);
       
   880 		int grp = 0;
       
   881 
       
   882 		if (t != NULL) {
       
   883 			grp = GetTownRadiusGroup(t, tile);
       
   884 
       
   885 			// Show an animation to indicate road work
       
   886 			if (t->road_build_months != 0 &&
       
   887 					(DistanceManhattan(t->xy, tile) < 8 || grp != 0) &&
       
   888 					GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) {
       
   889 				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicle(tile) && CHANCE16(1, 20)) {
       
   890 					StartRoadWorks(tile);
       
   891 
       
   892 					SndPlayTileFx(SND_21_JACKHAMMER, tile);
       
   893 					CreateEffectVehicleAbove(
       
   894 						TileX(tile) * TILE_SIZE + 7,
       
   895 						TileY(tile) * TILE_SIZE + 7,
       
   896 						0,
       
   897 						EV_BULLDOZER);
       
   898 					MarkTileDirtyByTile(tile);
       
   899 					return;
       
   900 				}
       
   901 			}
       
   902 		}
       
   903 
       
   904 		{
       
   905 			/* Adjust road ground type depending on 'grp' (grp is the distance to the center) */
       
   906 			const Roadside* new_rs = (_opt.landscape == LT_CANDY) ? _town_road_types_2[grp] : _town_road_types[grp];
       
   907 			Roadside cur_rs = GetRoadside(tile);
       
   908 
       
   909 			/* We have our desired type, do nothing */
       
   910 			if (cur_rs == new_rs[0]) return;
       
   911 
       
   912 			/* We have the pre-type of the desired type, switch to the desired type */
       
   913 			if (cur_rs == new_rs[1]) {
       
   914 				cur_rs = new_rs[0];
       
   915 			/* We have barren land, install the pre-type */
       
   916 			} else if (cur_rs == ROADSIDE_BARREN) {
       
   917 				cur_rs = new_rs[1];
       
   918 			/* We're totally off limits, remove any installation and make barren land */
       
   919 			} else {
       
   920 				cur_rs = ROADSIDE_BARREN;
       
   921 			}
       
   922 			SetRoadside(tile, cur_rs);
       
   923 			MarkTileDirtyByTile(tile);
       
   924 		}
       
   925 	} else if (IncreaseRoadWorksCounter(tile)) {
       
   926 		TerminateRoadWorks(tile);
       
   927 		MarkTileDirtyByTile(tile);
       
   928 	}
       
   929 }
       
   930 
       
   931 static void ClickTile_Road(TileIndex tile)
       
   932 {
       
   933 	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) ShowDepotWindow(tile, VEH_Road);
       
   934 }
       
   935 
       
   936 static const byte _road_trackbits[16] = {
       
   937 	0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F,
       
   938 };
       
   939 
       
   940 static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode)
       
   941 {
       
   942 	switch (mode) {
       
   943 		case TRANSPORT_RAIL:
       
   944 			if (!IsLevelCrossing(tile)) return 0;
       
   945 			return GetCrossingRailBits(tile) * 0x101;
       
   946 
       
   947 		case TRANSPORT_ROAD:
       
   948 			switch (GetRoadTileType(tile)) {
       
   949 				case ROAD_TILE_NORMAL:
       
   950 					return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile)] * 0x101;
       
   951 
       
   952 				case ROAD_TILE_CROSSING: {
       
   953 					uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101;
       
   954 
       
   955 					if (IsCrossingBarred(tile)) r *= 0x10001;
       
   956 					return r;
       
   957 				}
       
   958 
       
   959 				default:
       
   960 				case ROAD_TILE_DEPOT:
       
   961 					return AxisToTrackBits(DiagDirToAxis(GetRoadDepotDirection(tile))) * 0x101;
       
   962 			}
       
   963 			break;
       
   964 
       
   965 		default: break;
       
   966 	}
       
   967 	return 0;
       
   968 }
       
   969 
       
   970 static const StringID _road_tile_strings[] = {
       
   971 	STR_1814_ROAD,
       
   972 	STR_1814_ROAD,
       
   973 	STR_1814_ROAD,
       
   974 	STR_1815_ROAD_WITH_STREETLIGHTS,
       
   975 	STR_1814_ROAD,
       
   976 	STR_1816_TREE_LINED_ROAD,
       
   977 	STR_1814_ROAD,
       
   978 	STR_1814_ROAD,
       
   979 };
       
   980 
       
   981 static void GetTileDesc_Road(TileIndex tile, TileDesc *td)
       
   982 {
       
   983 	td->owner = GetTileOwner(tile);
       
   984 	switch (GetRoadTileType(tile)) {
       
   985 		case ROAD_TILE_CROSSING: td->str = STR_1818_ROAD_RAIL_LEVEL_CROSSING; break;
       
   986 		case ROAD_TILE_DEPOT: td->str = STR_1817_ROAD_VEHICLE_DEPOT; break;
       
   987 		default: td->str = _road_tile_strings[GetRoadside(tile)]; break;
       
   988 	}
       
   989 }
       
   990 
       
   991 static const byte _roadveh_enter_depot_unk0[4] = {
       
   992 	8, 9, 0, 1
       
   993 };
       
   994 
       
   995 static uint32 VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
       
   996 {
       
   997 	switch (GetRoadTileType(tile)) {
       
   998 		case ROAD_TILE_CROSSING:
       
   999 			if (v->type == VEH_Train && !IsCrossingBarred(tile)) {
       
  1000 				/* train crossing a road */
       
  1001 				SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
       
  1002 				BarCrossing(tile);
       
  1003 				MarkTileDirtyByTile(tile);
       
  1004 			}
       
  1005 			break;
       
  1006 
       
  1007 		case ROAD_TILE_DEPOT:
       
  1008 			if (v->type == VEH_Road &&
       
  1009 					v->u.road.frame == 11 &&
       
  1010 					_roadveh_enter_depot_unk0[GetRoadDepotDirection(tile)] == v->u.road.state) {
       
  1011 				VehicleEnterDepot(v);
       
  1012 				return 4;
       
  1013 			}
       
  1014 			break;
       
  1015 
       
  1016 		default: break;
       
  1017 	}
       
  1018 	return 0;
       
  1019 }
       
  1020 
       
  1021 
       
  1022 static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
       
  1023 {
       
  1024 	if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) == old_player) {
       
  1025 		SetCrossingRoadOwner(tile, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
       
  1026 	}
       
  1027 
       
  1028 	if (!IsTileOwner(tile, old_player)) return;
       
  1029 
       
  1030 	if (new_player != PLAYER_SPECTATOR) {
       
  1031 		SetTileOwner(tile, new_player);
       
  1032 	} else {
       
  1033 		switch (GetRoadTileType(tile)) {
       
  1034 			case ROAD_TILE_NORMAL:
       
  1035 				SetTileOwner(tile, OWNER_NONE);
       
  1036 				break;
       
  1037 
       
  1038 			case ROAD_TILE_CROSSING:
       
  1039 				MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
       
  1040 				break;
       
  1041 
       
  1042 			default:
       
  1043 			case ROAD_TILE_DEPOT:
       
  1044 				DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
       
  1045 				break;
       
  1046 		}
       
  1047 	}
       
  1048 }
       
  1049 
       
  1050 
       
  1051 const TileTypeProcs _tile_type_road_procs = {
       
  1052 	DrawTile_Road,           /* draw_tile_proc */
       
  1053 	GetSlopeZ_Road,          /* get_slope_z_proc */
       
  1054 	ClearTile_Road,          /* clear_tile_proc */
       
  1055 	GetAcceptedCargo_Road,   /* get_accepted_cargo_proc */
       
  1056 	GetTileDesc_Road,        /* get_tile_desc_proc */
       
  1057 	GetTileTrackStatus_Road, /* get_tile_track_status_proc */
       
  1058 	ClickTile_Road,          /* click_tile_proc */
       
  1059 	AnimateTile_Road,        /* animate_tile_proc */
       
  1060 	TileLoop_Road,           /* tile_loop_clear */
       
  1061 	ChangeTileOwner_Road,    /* change_tile_owner_clear */
       
  1062 	NULL,                    /* get_produced_cargo_proc */
       
  1063 	VehicleEnter_Road,       /* vehicle_enter_tile_proc */
       
  1064 	GetSlopeTileh_Road,      /* get_slope_tileh_proc */
       
  1065 };