Changeset - r9341:c8e34c3b896e
[Not reviewed]
master
0 6 0
frosch - 16 years ago 2008-05-24 19:36:20
frosch@openttd.org
(svn r13233) -Fix: Replace some (incorrect) evaluations of TileOwner by RoadOwner.
-Fix: Before evaluating RoadOwner, check if the roadtype is present.
-Fix: Some places assumed that MP_ROAD means normal street.
6 files changed with 34 insertions and 28 deletions:
0 comments (0 inline, 0 general)
src/ai/default/default.cpp
Show inline comments
 
@@ -3742,53 +3742,53 @@ pos_2:
 
					return;
 
				}
 
			}
 

	
 
			if (rails & TRACK_BIT_3WAY_NW) {
 
pos_3:
 
				if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(0, 1))) & TRACK_BIT_3WAY_SE) == 0) {
 
					_players_ai[p->index].cur_dir_a = DIAGDIR_NW;
 
					_players_ai[p->index].cur_tile_a = tile;
 
					_players_ai[p->index].state = AIS_REMOVE_SINGLE_RAIL_TILE;
 
					return;
 
				}
 
			}
 
		} else {
 
			static const byte _depot_bits[] = {0x19, 0x16, 0x25, 0x2A};
 

	
 
			DiagDirection dir = GetRailDepotDirection(tile);
 

	
 
			if (GetRailTrackStatus(tile + TileOffsByDiagDir(dir)) & _depot_bits[dir])
 
				return;
 

	
 
			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
		}
 
	} else if (IsTileType(tile, MP_ROAD)) {
 
		if (!IsTileOwner(tile, _current_player)) return;
 

	
 
		if (IsLevelCrossing(tile)) goto is_rail_crossing;
 

	
 
		if (IsRoadDepot(tile)) {
 
			if (!IsTileOwner(tile, _current_player)) return;
 

	
 
			DiagDirection dir;
 
			TileIndex t;
 

	
 
			// Check if there are any stations around.
 
			t = tile + TileDiffXY(-1, 0);
 
			if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
 

	
 
			t = tile + TileDiffXY(1, 0);
 
			if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
 

	
 
			t = tile + TileDiffXY(0, -1);
 
			if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
 

	
 
			t = tile + TileDiffXY(0, 1);
 
			if (IsTileType(t, MP_STATION) && IsTileOwner(t, _current_player)) return;
 

	
 
			dir = GetRoadDepotDirection(tile);
 

	
 
			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
			DoCommand(
 
				TILE_MASK(tile + TileOffsByDiagDir(dir)),
 
				DiagDirToRoadBits(ReverseDiagDir(dir)),
 
				0,
 
				DC_EXEC,
src/road_cmd.cpp
Show inline comments
 
@@ -152,96 +152,91 @@ bool CheckAllowRemoveRoad(TileIndex tile
 
	RoadBits n = ROAD_NONE;
 
	RoadBits present = GetAnyRoadBits(tile, rt);
 
	if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1,  0), rt) & ROAD_SW) n |= ROAD_NE;
 
	if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile,  0,  1), rt) & ROAD_NW) n |= ROAD_SE;
 
	if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile,  1,  0), rt) & ROAD_NE) n |= ROAD_SW;
 
	if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile,  0, -1), rt) & ROAD_SE) n |= ROAD_NW;
 

	
 
	/* If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
 
	 * then allow it */
 
	if (KillFirstBit(n) != ROAD_NONE && (n & remove) != ROAD_NONE) {
 
		*edge_road = false;
 
		/* you can remove all kind of roads with extra dynamite */
 
		if (_patches.extra_dynamite) return true;
 

	
 
		const Town *t = ClosestTownFromTile(tile, (uint)-1);
 

	
 
		SetDParam(0, t->index);
 
		_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road, RoadType rt)
 
{
 
	return CheckAllowRemoveRoad(tile, remove, GetRoadOwner(tile, rt), edge_road, rt);
 
}
 

	
 

	
 
/** Delete a piece of road.
 
 * @param tile tile where to remove road from
 
 * @param flags operation to perform
 
 * @param pieces roadbits to remove
 
 * @param rt roadtype to remove
 
 * @param crossing_check should we check if there is a tram track when we are removing road from crossing?
 
 */
 
static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true)
 
{
 
	/* cost for removing inner/edge -roads */
 
	static const uint16 road_remove_cost[2] = {50, 18};
 

	
 
	/* true if the roadpiece was always removeable,
 
	 * false if it was a center piece. Affects town ratings drop */
 
	bool edge_road;
 

	
 
	RoadTypes rts = GetRoadTypes(tile);
 
	/* The tile doesn't have the given road type */
 
	if (!HasBit(rts, rt)) return CMD_ERROR;
 

	
 
	Town *t = NULL;
 
	switch (GetTileType(tile)) {
 
		case MP_ROAD:
 
			if (_game_mode != GM_EDITOR && GetRoadOwner(tile, rt) == OWNER_TOWN) t = GetTownByTile(tile);
 
			if (_game_mode != GM_EDITOR && IsRoadOwner(tile, rt, OWNER_TOWN)) t = GetTownByTile(tile);
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 
			break;
 

	
 
		case MP_STATION:
 
			if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
			if (GetVehicleTunnelBridge(tile, GetOtherTunnelBridgeEnd(tile)) != NULL) return CMD_ERROR;
 
			break;
 

	
 
		default:
 
			return CMD_ERROR;
 
	}
 

	
 
	RoadTypes rts = GetRoadTypes(tile);
 
	/* The tile doesn't have the given road type */
 
	if (!HasBit(rts, rt)) return CMD_ERROR;
 

	
 
	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road, rt)) return CMD_ERROR;
 
	if (!CheckAllowRemoveRoad(tile, pieces, GetRoadOwner(tile, rt), &edge_road, rt)) return CMD_ERROR;
 

	
 
	/* check if you're allowed to remove the street owned by a town
 
	 * removal allowance depends on difficulty setting */
 
	if (town_check && !CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_ROAD)) {
 
		/* If it's the last roadtype, just clear the whole tile */
 
		if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 

	
 
		CommandCost cost(EXPENSES_CONSTRUCTION);
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
 
			/* Pay for *every* tile of the bridge or tunnel */
 
			cost.AddCost((GetTunnelBridgeLength(other_end, tile) + 2) * _price.remove_road);
 
			if (flags & DC_EXEC) {
 
				SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
 
				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
 

	
 
				/* Mark tiles diry that have been repaved */
 
				MarkTileDirtyByTile(tile);
 
				MarkTileDirtyByTile(other_end);
 
				if (IsBridge(tile)) {
 
					TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
 

	
 
@@ -480,49 +475,49 @@ CommandCost CmdBuildRoad(TileIndex tile,
 
	RoadType rt = (RoadType)GB(p1, 4, 2);
 
	if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
 

	
 
	DisallowedRoadDirections toggle_drd = (DisallowedRoadDirections)GB(p1, 6, 2);
 

	
 
	Slope tileh = GetTileSlope(tile, NULL);
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_ROAD:
 
			switch (GetRoadTileType(tile)) {
 
				case ROAD_TILE_NORMAL: {
 
					if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
 

	
 
					other_bits = GetOtherRoadBits(tile, rt);
 
					if (!HasTileRoadType(tile, rt)) break;
 

	
 
					existing = GetRoadBits(tile, rt);
 
					bool crossing = !IsStraightRoad(existing | pieces);
 
					if (rt != ROADTYPE_TRAM && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) {
 
						/* Junctions cannot be one-way */
 
						return_cmd_error(STR_ERR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
 
					}
 
					if ((existing & pieces) == pieces) {
 
						/* We only want to set the (dis)allowed road directions */
 
						if (toggle_drd != DRD_NONE && rt != ROADTYPE_TRAM && GetRoadOwner(tile, ROADTYPE_ROAD) == _current_player) {
 
						if (toggle_drd != DRD_NONE && rt != ROADTYPE_TRAM && IsRoadOwner(tile, ROADTYPE_ROAD, _current_player)) {
 
							if (crossing) return_cmd_error(STR_ERR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
 

	
 
							if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 

	
 
							/* Ignore half built tiles */
 
							if (flags & DC_EXEC && rt != ROADTYPE_TRAM && IsStraightRoad(existing)) {
 
								SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd);
 
								MarkTileDirtyByTile(tile);
 
							}
 
							return CommandCost();
 
						}
 
						return_cmd_error(STR_1007_ALREADY_BUILT);
 
					}
 
				} break;
 

	
 
				case ROAD_TILE_CROSSING:
 
					if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
 
					other_bits = GetCrossingRoadBits(tile);
 
					if (pieces & ComplementRoadBits(other_bits)) goto do_clear;
 
					break;
 

	
 
				default:
 
				case ROAD_TILE_DEPOT:
 
					goto do_clear;
 
@@ -873,49 +868,49 @@ CommandCost CmdBuildRoadDepot(TileIndex 
 

	
 
static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags)
 
{
 
	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DoClearSquare(tile);
 
		delete GetDepotByTile(tile);
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_road_depot);
 
}
 

	
 
static CommandCost ClearTile_Road(TileIndex tile, byte flags)
 
{
 
	switch (GetRoadTileType(tile)) {
 
		case ROAD_TILE_NORMAL: {
 
			RoadBits b = GetAllRoadBits(tile);
 

	
 
			/* Clear the road if only one piece is on the tile OR the AI tries
 
			 * to clear town road OR we are not using the DC_AUTO flag */
 
			if ((CountBits(b) == 1 && GetRoadBits(tile, ROADTYPE_TRAM) == ROAD_NONE) ||
 
			    ((flags & DC_AI_BUILDING) && IsTileOwner(tile, OWNER_TOWN)) ||
 
			    ((flags & DC_AI_BUILDING) && GetOtherRoadBits(tile, ROADTYPE_ROAD) == ROAD_NONE && IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) ||
 
			    !(flags & DC_AUTO)
 
				) {
 
				RoadTypes rts = GetRoadTypes(tile);
 
				CommandCost ret(EXPENSES_CONSTRUCTION);
 
				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 
					if (HasBit(rts, rt)) {
 
						CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rt), rt, true);
 
						if (CmdFailed(tmp_ret)) return tmp_ret;
 
						ret.AddCost(tmp_ret);
 
					}
 
				}
 
				return ret;
 
			}
 
			return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
 
		}
 

	
 
		case ROAD_TILE_CROSSING: {
 
			RoadTypes rts = GetRoadTypes(tile);
 
			CommandCost ret(EXPENSES_CONSTRUCTION);
 

	
 
			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
 

	
 
			/* Must iterate over the roadtypes in a reverse manner because
 
			 * tram tracks must be removed before the road bits. */
 
@@ -1528,51 +1523,49 @@ static VehicleEnterTileStatus VehicleEnt
 
				return VETSB_ENTERED_WORMHOLE;
 
			}
 
			break;
 

	
 
		default: break;
 
	}
 
	return VETSB_CONTINUE;
 
}
 

	
 

	
 
static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
 
{
 
	if (IsRoadDepot(tile)) {
 
		if (GetTileOwner(tile) == old_player) {
 
			if (new_player == PLAYER_SPECTATOR) {
 
				DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
 
			} else {
 
				SetTileOwner(tile, new_player);
 
			}
 
		}
 
		return;
 
	}
 

	
 
	for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 
		/* ROADTYPE_ROAD denotes the tile owner, so update it too */
 
		if (rt != ROADTYPE_ROAD && !HasTileRoadType(tile, rt)) continue;
 

	
 
		/* Update all roadtypes, no matter if they are present */
 
		if (GetRoadOwner(tile, rt) == old_player) {
 
			SetRoadOwner(tile, rt, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
 
		}
 
	}
 

	
 
	if (IsLevelCrossing(tile)) {
 
		if (GetTileOwner(tile) == old_player) {
 
			if (new_player == PLAYER_SPECTATOR) {
 
				DoCommand(tile, 0, GetCrossingRailTrack(tile), DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL);
 
			} else {
 
				SetTileOwner(tile, new_player);
 
			}
 
		}
 
	}
 
}
 

	
 
static CommandCost TerraformTile_Road(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 
{
 
	if (_patches.build_on_slopes && AutoslopeEnabled()) {
 
		switch (GetRoadTileType(tile)) {
 
			case ROAD_TILE_CROSSING:
 
				if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 
				break;
 

	
src/road_map.h
Show inline comments
 
@@ -166,48 +166,54 @@ static inline void SetRoadOwner(TileInde
 
	switch (GetRoadTileType(t)) {
 
		default: NOT_REACHED();
 
		case ROAD_TILE_NORMAL:
 
			switch (rt) {
 
				default: NOT_REACHED();
 
				case ROADTYPE_ROAD: SB( _m[t].m1, 0, 5, o); break;
 
				case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
 
				case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
 
			}
 
			break;
 
		case ROAD_TILE_CROSSING:
 
			switch (rt) {
 
				default: NOT_REACHED();
 
				case ROADTYPE_ROAD: SB( _m[t].m4, 0, 5, o); break;
 
				/* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
 
				 * to OWNER_TOWN makes it use one bit less */
 
				case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
 
				case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
 
			}
 
			break;
 
		case ROAD_TILE_DEPOT: return SetTileOwner(t, o);
 
	}
 
}
 

	
 
static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o)
 
{
 
	assert(HasTileRoadType(t, rt));
 
	return (GetRoadOwner(t, rt) == o);
 
}
 

	
 
/** Which directions are disallowed ? */
 
enum DisallowedRoadDirections {
 
	DRD_NONE,       ///< None of the directions are disallowed
 
	DRD_SOUTHBOUND, ///< All southbound traffic is disallowed
 
	DRD_NORTHBOUND, ///< All northbound traffic is disallowed
 
	DRD_BOTH,       ///< All directions are disallowed
 
	DRD_END
 
};
 
DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections);
 

	
 
/**
 
 * Gets the disallowed directions
 
 * @param t the tile to get the directions from
 
 * @return the disallowed directions
 
 */
 
static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
 
{
 
	assert(IsNormalRoad(t));
 
	return (DisallowedRoadDirections)GB(_m[t].m5, 4, 2);
 
}
 

	
 
/**
 
 * Sets the disallowed directions
 
 * @param t   the tile to set the directions for
src/smallmap_gui.cpp
Show inline comments
 
@@ -469,48 +469,52 @@ static inline uint32 GetSmallMapVegetati
 
			bits = ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
 
			break;
 
	}
 

	
 
	return bits;
 
}
 

	
 

	
 
static uint32 _owner_colors[OWNER_END + 1];
 

	
 
/**
 
 * Return the color a tile would be displayed with in the small map in mode "Owner".
 
 *
 
 * @param tile The tile of which we would like to get the color.
 
 * @return The color of tile in the small map in mode "Owner"
 
 */
 
static inline uint32 GetSmallMapOwnerPixels(TileIndex tile)
 
{
 
	Owner o;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_INDUSTRY: o = OWNER_END;          break;
 
		case MP_HOUSE:    o = OWNER_TOWN;         break;
 
		default:          o = GetTileOwner(tile); break;
 
		/* FIXME: For MP_ROAD there are multiple owners.
 
		 * GetTileOwner returns the rail owner (level crossing) resp. the owner of ROADTYPE_ROAD (normal road),
 
		 * even if there are no ROADTYPE_ROAD bits on the tile.
 
		 */
 
	}
 

	
 
	return _owner_colors[o];
 
}
 

	
 

	
 
static const uint32 _smallmap_mask_left[3] = {
 
	MKCOLOR(0xFF000000),
 
	MKCOLOR(0xFFFF0000),
 
	MKCOLOR(0xFFFFFF00),
 
};
 

	
 
static const uint32 _smallmap_mask_right[] = {
 
	MKCOLOR(0x000000FF),
 
	MKCOLOR(0x0000FFFF),
 
	MKCOLOR(0x00FFFFFF),
 
};
 

	
 
/* each tile has 4 x pixels and 1 y pixel */
 

	
 
static GetSmallMapPixels *_smallmap_draw_procs[] = {
 
	GetSmallMapContoursPixels,
 
	GetSmallMapVehiclesPixels,
 
	GetSmallMapIndustriesPixels,
src/station_cmd.cpp
Show inline comments
 
@@ -1279,75 +1279,78 @@ static RoadStop **FindRoadStopSpot(bool 
 
		/* we have no roadstop of the type yet, so write a "primary stop" */
 
		return primary_stop;
 
	} else {
 
		/* there are stops already, so append to the end of the list */
 
		RoadStop *stop = *primary_stop;
 
		while (stop->next != NULL) stop = stop->next;
 
		return &stop->next;
 
	}
 
}
 

	
 
/** Build a bus or truck stop
 
 * @param tile tile to build the stop at
 
 * @param flags operation to perform
 
 * @param p1 entrance direction (DiagDirection)
 
 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
 
 *           bit 1: 0 for normal, 1 for drive-through
 
 *           bit 2..4: the roadtypes
 
 *           bit 5: allow stations directly adjacent to other stations.
 
 */
 
CommandCost CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	bool type = HasBit(p2, 0);
 
	bool is_drive_through = HasBit(p2, 1);
 
	bool build_over_road  = is_drive_through && IsNormalRoadTile(tile);
 
	bool town_owned_road  = build_over_road && IsTileOwner(tile, OWNER_TOWN);
 
	bool town_owned_road  = false;
 
	RoadTypes rts = (RoadTypes)GB(p2, 2, 3);
 

	
 
	if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR;
 

	
 
	/* Trams only have drive through stops */
 
	if (!is_drive_through && HasBit(rts, ROADTYPE_TRAM)) return CMD_ERROR;
 

	
 
	/* Saveguard the parameters */
 
	if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
 
	/* If it is a drive-through stop check for valid axis */
 
	if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR;
 
	/* Road bits in the wrong direction */
 
	if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
 

	
 
	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
 

	
 
	/* Not allowed to build over this road */
 
	if (build_over_road) {
 
		if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
 

	
 
		RoadTypes cur_rts = GetRoadTypes(tile);
 

	
 
		/* there is a road, check if we can build road+tram stop over it */
 
		if (HasBit(cur_rts, ROADTYPE_ROAD)) {
 
			Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
 
			if (road_owner != OWNER_TOWN && road_owner != OWNER_NONE && !CheckOwnership(road_owner)) return CMD_ERROR;
 
			if (road_owner == OWNER_TOWN) {
 
				town_owned_road = true;
 
				if (!_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
 
			} else {
 
				if (road_owner != OWNER_NONE && !CheckOwnership(road_owner)) return CMD_ERROR;
 
			}
 
		}
 

	
 
		/* there is a tram, check if we can build road+tram stop over it */
 
		if (HasBit(cur_rts, ROADTYPE_TRAM)) {
 
			Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM);
 
			if (tram_owner != OWNER_NONE && !CheckOwnership(tram_owner)) return CMD_ERROR;
 
		}
 

	
 
		/* Don't allow building the roadstop when vehicles are already driving on it */
 
		if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 

	
 
		/* Do not remove roadtypes! */
 
		rts |= cur_rts;
 
	}
 

	
 
	CommandCost cost = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL, !build_over_road);
 
	if (CmdFailed(cost)) return cost;
 

	
 
	Station *st = NULL;
 

	
 
	if (!_patches.adjacent_stations || !HasBit(p2, 5)) {
 
		st = GetStationAround(tile, 1, 1, INVALID_STATION);
 
		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
	}
src/town_cmd.cpp
Show inline comments
 
@@ -1191,56 +1191,56 @@ static int GrowTownAtRoad(Town *t, TileI
 
			break;
 

	
 
		default:
 
			_grow_town_result = 10 + t->num_houses * 4 / 9;
 
			break;
 
	}
 

	
 
	do {
 
		RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
 

	
 
		/* Try to grow the town from this point */
 
		GrowTownInTile(&tile, cur_rb, target_dir, t);
 

	
 
		/* Exclude the source position from the bitmask
 
		 * and return if no more road blocks available */
 
		cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
 
		if (cur_rb == ROAD_NONE)
 
			return _grow_town_result;
 

	
 
		/* Select a random bit from the blockmask, walk a step
 
		 * and continue the search from there. */
 
		do target_dir = RandomDiagDir(); while (!(cur_rb & DiagDirToRoadBits(target_dir)));
 
		tile = TileAddByDiagDir(tile, target_dir);
 

	
 
		if (IsTileType(tile, MP_ROAD)) {
 
		if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, ROADTYPE_ROAD)) {
 
			/* Don't allow building over roads of other cities */
 
			if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) {
 
			if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN) && GetTownByTile(tile) != t) {
 
				_grow_town_result = GROWTH_SUCCEED;
 
			} else if (IsTileOwner(tile, OWNER_NONE) && _game_mode == GM_EDITOR) {
 
			} else if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
 
				/* If we are in the SE, and this road-piece has no town owner yet, it just found an
 
				 * owner :) (happy happy happy road now) */
 
				SetTileOwner(tile, OWNER_TOWN);
 
				SetRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN);
 
				SetTownIndex(tile, t->index);
 
			}
 
		}
 

	
 
		/* Max number of times is checked. */
 
	} while (--_grow_town_result >= 0);
 

	
 
	return (_grow_town_result == -2);
 
}
 

	
 
/**
 
 * Generate a random road block.
 
 * The probability of a straight road
 
 * is somewhat higher than a curved.
 
 *
 
 * @return A RoadBits value with 2 bits set
 
 */
 
static RoadBits GenRandomRoadBits()
 
{
 
	uint32 r = Random();
 
	uint a = GB(r, 0, 2);
 
	uint b = GB(r, 8, 2);
 
	if (a == b) b ^= 2;
 
	return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
 
@@ -2417,50 +2417,50 @@ bool CheckIfAuthorityAllows(TileIndex ti
 
}
 

	
 

	
 
Town *CalcClosestTownFromTile(TileIndex tile, uint threshold)
 
{
 
	Town *t;
 
	uint best = threshold;
 
	Town *best_town = NULL;
 

	
 
	FOR_ALL_TOWNS(t) {
 
		uint dist = DistanceManhattan(tile, t->xy);
 
		if (dist < best) {
 
			best = dist;
 
			best_town = t;
 
		}
 
	}
 

	
 
	return best_town;
 
}
 

	
 

	
 
Town *ClosestTownFromTile(TileIndex tile, uint threshold)
 
{
 
	if (IsTileType(tile, MP_HOUSE) || (
 
				IsTileType(tile, MP_ROAD) &&
 
				GetRoadOwner(tile, ROADTYPE_ROAD) == OWNER_TOWN
 
				IsTileType(tile, MP_ROAD) && HasTileRoadType(tile, ROADTYPE_ROAD) &&
 
				IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)
 
			)) {
 
		return GetTownByTile(tile);
 
	} else {
 
		return CalcClosestTownFromTile(tile, threshold);
 
	}
 
}
 

	
 
static bool _town_rating_test = false;
 
std::map<const Town *, int> _town_test_ratings;
 

	
 
void SetTownRatingTestMode(bool mode)
 
{
 
	static int ref_count = 0;
 
	if (mode) {
 
		if (ref_count == 0) {
 
			_town_test_ratings.clear();
 
		}
 
		ref_count++;
 
	} else {
 
		assert(ref_count > 0);
 
		ref_count--;
 
	}
 
	_town_rating_test = !(ref_count == 0);
 
}
0 comments (0 inline, 0 general)