Changeset - r23617:216c443321e5
[Not reviewed]
master
0 7 0
PeterN - 5 years ago 2019-04-13 13:12:34
peter@fuzzle.org
Codechange: Replace duplicated code with TileArea::Expand() (#7467)
7 files changed with 37 insertions and 54 deletions:
0 comments (0 inline, 0 general)
src/industry_cmd.cpp
Show inline comments
 
@@ -153,14 +153,13 @@ Industry::~Industry()
 
		} else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
 
			DeleteOilRig(tile_cur);
 
		}
 
	}
 

	
 
	if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) {
 
		TileArea ta(this->location.tile - TileDiffXY(min(TileX(this->location.tile), 21), min(TileY(this->location.tile), 21)), 42, 42);
 
		ta.ClampToMap();
 
		TileArea ta = TileArea(this->location.tile, 0, 0).Expand(21);
 

	
 
		/* Remove the farmland and convert it to regular tiles over time. */
 
		TILE_AREA_LOOP(tile_cur, ta) {
 
			if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
 
					GetIndustryIndexOfField(tile_cur) == this->index) {
 
				SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
 
@@ -1530,12 +1529,14 @@ static bool CheckIfCanLevelIndustryPlatf
 
	uint h = TileHeight(tile);
 

	
 
	if (TileX(tile) <= _settings_game.construction.industry_platform + 1U || TileY(tile) <= _settings_game.construction.industry_platform + 1U) return false;
 
	/* Check that all tiles in area and surrounding are clear
 
	 * this determines that there are no obstructing items */
 

	
 
	/* TileArea::Expand is not used here as we need to abort
 
	 * instead of clamping if the bounds cannot expanded. */
 
	TileArea ta(tile + TileDiffXY(-_settings_game.construction.industry_platform, -_settings_game.construction.industry_platform),
 
			max_x + 2 + 2 * _settings_game.construction.industry_platform, max_y + 2 + 2 * _settings_game.construction.industry_platform);
 

	
 
	if (TileX(ta.tile) + ta.w >= MapMaxX() || TileY(ta.tile) + ta.h >= MapMaxY()) return false;
 

	
 
	/* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
 
@@ -1590,15 +1591,13 @@ static CommandCost CheckIfFarEnoughFromC
 
	const IndustrySpec *indspec = GetIndustrySpec(type);
 
	const Industry *i = nullptr;
 

	
 
	/* On a large map with many industries, it may be faster to check an area. */
 
	static const int dmax = 14;
 
	if (Industry::GetNumItems() > (size_t) (dmax * dmax * 2)) {
 
		const int tx = TileX(tile);
 
		const int ty = TileY(tile);
 
		TileArea tile_area = TileArea(TileXY(max(0, tx - dmax), max(0, ty - dmax)), TileXY(min(MapMaxX(), tx + dmax), min(MapMaxY(), ty + dmax)));
 
		TileArea tile_area = TileArea(tile, 1, 1).Expand(dmax);
 
		TILE_AREA_LOOP(atile, tile_area) {
 
			if (GetTileType(atile) == MP_INDUSTRY) {
 
				const Industry *i2 = Industry::GetByTile(atile);
 
				if (i == i2) continue;
 
				i = i2;
 
				if (DistanceMax(tile, i->location.tile) > (uint)dmax) continue;
src/script/api/script_tilelist.cpp
Show inline comments
 
@@ -63,13 +63,13 @@ ScriptTileList_IndustryAccepting::Script
 
		}
 
		if (!cargo_accepts) return;
 
	}
 

	
 
	if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
 

	
 
	TileArea ta(i->location.tile - ::TileDiffXY(radius, radius), i->location.w + radius * 2, i->location.h + radius * 2);
 
	TileArea ta = TileArea(i->location).Expand(radius);
 
	TILE_AREA_LOOP(cur_tile, ta) {
 
		if (!::IsValidTile(cur_tile)) continue;
 
		/* Exclude all tiles that belong to this industry */
 
		if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue;
 

	
 
		/* Only add the tile if it accepts the cargo (sometimes just 1 tile of an
 
@@ -99,13 +99,13 @@ ScriptTileList_IndustryProducing::Script
 
		if (i->produced_cargo[j] != CT_INVALID) cargo_produces = true;
 
	}
 
	if (!cargo_produces) return;
 

	
 
	if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
 

	
 
	TileArea ta(i->location.tile - ::TileDiffXY(radius, radius), i->location.w + radius * 2, i->location.h + radius * 2);
 
	TileArea ta = TileArea(i->location).Expand(radius);
 
	TILE_AREA_LOOP(cur_tile, ta) {
 
		if (!::IsValidTile(cur_tile)) continue;
 
		/* Exclude all tiles that belong to this industry */
 
		if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue;
 

	
 
		this->AddTile(cur_tile);
src/station.cpp
Show inline comments
 
@@ -446,13 +446,13 @@ void Station::RecomputeCatchment()
 
		if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != this->index) continue;
 

	
 
		uint r = GetTileCatchmentRadius(tile, this);
 
		if (r == CA_NONE) continue;
 

	
 
		/* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */
 
		TileArea ta2(TileXY(max<int>(TileX(tile) - r, 0), max<int>(TileY(tile) - r, 0)), TileXY(min<int>(TileX(tile) + r, MapMaxX()), min<int>(TileY(tile) + r, MapMaxY())));
 
		TileArea ta2 = TileArea(tile, 1, 1).Expand(r);
 
		TILE_AREA_LOOP(tile2, ta2) this->catchment_tiles.SetTile(tile2);
 
	}
 

	
 
	/* Search catchment tiles for towns and industries */
 
	BitmapTileIterator it(this->catchment_tiles);
 
	for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
src/station_cmd.cpp
Show inline comments
 
@@ -98,15 +98,13 @@ bool IsHangar(TileIndex t)
 
 * @param st to 'return' the found station
 
 * @return Succeeded command (if zero or one station found) or failed command (for two or more stations found).
 
 */
 
template <class T>
 
CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st)
 
{
 
	ta.tile -= TileDiffXY(1, 1);
 
	ta.w    += 2;
 
	ta.h    += 2;
 
	ta.Expand(1);
 

	
 
	/* check around to see if there are any stations there owned by the company */
 
	TILE_AREA_LOOP(tile_cur, ta) {
 
		if (IsTileType(tile_cur, MP_STATION)) {
 
			StationID t = GetStationIndex(tile_cur);
 
			if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue;
 
@@ -492,31 +490,14 @@ static void ShowRejectOrAcceptNews(const
 
 * @param h Y extent of the area
 
 * @param rad Search radius in addition to the given area
 
 */
 
CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad)
 
{
 
	CargoArray produced;
 

	
 
	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. */
 
	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);
 

	
 
	std::set<IndustryID> industries;
 
	TileArea ta(TileXY(x1, y1), TileXY(x2 - 1, y2 - 1));
 
	TileArea ta = TileArea(tile, w, h).Expand(rad);
 

	
 
	/* Loop over all tiles to get the produced cargo of
 
	 * everything except industries */
 
	TILE_AREA_LOOP(tile, ta) {
 
		if (IsTileType(tile, MP_INDUSTRY)) industries.insert(GetIndustryIndex(tile));
 
		AddProducedCargo(tile, produced);
 
@@ -550,37 +531,20 @@ CargoArray GetProductionAroundTiles(Tile
 
 */
 
CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted)
 
{
 
	CargoArray acceptance;
 
	if (always_accepted != nullptr) *always_accepted = 0;
 

	
 
	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. */
 
	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 (int yc = y1; yc != y2; yc++) {
 
		for (int xc = x1; xc != x2; xc++) {
 
			TileIndex tile = TileXY(xc, yc);
 

	
 
	TileArea ta = TileArea(tile, w, h).Expand(rad);
 

	
 
	TILE_AREA_LOOP(tile, ta) {
 
			/* Ignore industry if it has a neutral station. */
 
			if (!_settings_game.station.serve_neutral_industries && IsTileType(tile, MP_INDUSTRY) && Industry::GetByTile(tile)->neutral_station != nullptr) continue;
 

	
 
			AddAcceptedCargo(tile, acceptance, always_accepted);
 
		}
 
	}
 

	
 
	return acceptance;
 
}
 

	
 
/**
 
 * Get the acceptance of cargoes around the station in.
 
@@ -3855,21 +3819,18 @@ void FindStationsAroundTiles(const TileA
 
			AddNearbyStationsByCatchment(location.tile, stations, Town::GetByTile(location.tile)->stations_near);
 
			return;
 
		}
 
	}
 

	
 
	/* Not using, or don't have a nearby stations list, so we need to scan. */
 
	uint x = TileX(location.tile);
 
	uint y = TileY(location.tile);
 

	
 
	std::set<StationID> seen_stations;
 

	
 
	/* Scan an area around the building covering the maximum possible station
 
	 * to find the possible nearby stations. */
 
	uint max_c = _settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED;
 
	TileArea ta(TileXY(max<int>(0, x - max_c), max<int>(0, y - max_c)), TileXY(min<int>(MapMaxX(), x + location.w + max_c), min<int>(MapMaxY(), y + location.h + max_c)));
 
	TileArea ta = TileArea(location).Expand(max_c);
 
	TILE_AREA_LOOP(tile, ta) {
 
		if (IsTileType(tile, MP_STATION)) seen_stations.insert(GetStationIndex(tile));
 
	}
 

	
 
	for (StationID stationid : seen_stations) {
 
		Station *st = Station::GetIfValid(stationid);
src/tilearea.cpp
Show inline comments
 
@@ -115,12 +115,33 @@ bool OrthogonalTileArea::Contains(TileIn
 
	uint tile_y = TileY(tile);
 

	
 
	return IsInsideBS(tile_x, left, this->w) && IsInsideBS(tile_y, top, this->h);
 
}
 

	
 
/**
 
 * Expand a tile area by rad tiles in each direction, keeping within map bounds.
 
 * @param rad Number of tiles to expand
 
 * @return The OrthogonalTileArea.
 
 */
 
OrthogonalTileArea &OrthogonalTileArea::Expand(int rad)
 
{
 
	int x = TileX(this->tile);
 
	int y = TileY(this->tile);
 

	
 
	int sx = max(x - rad, 0);
 
	int sy = max(y - rad, 0);
 
	int ex = min(x + this->w + rad, MapSizeX());
 
	int ey = min(y + this->h + rad, MapSizeY());
 

	
 
	this->tile = TileXY(sx, sy);
 
	this->w    = ex - sx;
 
	this->h    = ey - sy;
 
	return *this;
 
}
 

	
 
/**
 
 * Clamp the tile area to map borders.
 
 */
 
void OrthogonalTileArea::ClampToMap()
 
{
 
	assert(this->tile < MapSize());
 
	this->w = min(this->w, MapSizeX() - TileX(this->tile));
src/tilearea_type.h
Show inline comments
 
@@ -45,12 +45,14 @@ struct OrthogonalTileArea {
 
	}
 

	
 
	bool Intersects(const OrthogonalTileArea &ta) const;
 

	
 
	bool Contains(TileIndex tile) const;
 

	
 
	OrthogonalTileArea &Expand(int rad);
 

	
 
	void ClampToMap();
 

	
 
	/**
 
	 * Get the center tile.
 
	 * @return The tile at the center, or just north of it.
 
	 */
src/waypoint_cmd.cpp
Show inline comments
 
@@ -197,13 +197,13 @@ CommandCost CmdBuildRailWaypoint(TileInd
 
		TileIndex tile = start_tile + i * offset;
 
		CommandCost ret = IsValidTileForWaypoint(tile, axis, &est);
 
		if (ret.Failed()) return ret;
 
	}
 

	
 
	Waypoint *wp = nullptr;
 
	TileArea new_location(TileArea(start_tile, width, height));
 
	TileArea new_location(start_tile, width, height);
 
	CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, new_location, &wp);
 
	if (ret.Failed()) return ret;
 

	
 
	/* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
 
	TileIndex center_tile = start_tile + (count / 2) * offset;
 
	if (wp == nullptr && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company);
0 comments (0 inline, 0 general)