File diff r25450:7e9533370994 → r25451:917146b539af
src/station_gui.cpp
Show inline comments
 
@@ -58,97 +58,97 @@ int DrawStationCoverageAreaText(int left
 
	if (_thd.drawstyle == HT_RECT && tile < MapSize()) {
 
		CargoArray cargoes;
 
		if (supplies) {
 
			cargoes = GetProductionAroundTiles(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE, rad);
 
		} else {
 
			cargoes = GetAcceptanceAroundTiles(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE, rad);
 
		}
 

	
 
		/* Convert cargo counts to a set of cargo bits, and draw the result. */
 
		for (CargoID i = 0; i < NUM_CARGO; i++) {
 
			switch (sct) {
 
				case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CC_PASSENGERS)) continue; break;
 
				case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CC_PASSENGERS)) continue; break;
 
				case SCT_ALL: break;
 
				default: NOT_REACHED();
 
			}
 
			if (cargoes[i] >= (supplies ? 1U : 8U)) SetBit(cargo_mask, i);
 
		}
 
	}
 
	SetDParam(0, cargo_mask);
 
	return DrawStringMultiLine(left, right, top, INT32_MAX, supplies ? STR_STATION_BUILD_SUPPLIES_CARGO : STR_STATION_BUILD_ACCEPTS_CARGO);
 
}
 

	
 
/**
 
 * Find stations adjacent to the current tile highlight area, so that existing coverage
 
 * area can be drawn.
 
 */
 
static void FindStationsAroundSelection()
 
{
 
	/* With distant join we don't know which station will be selected, so don't show any */
 
	if (_ctrl_pressed) {
 
		SetViewportCatchmentStation(nullptr, true);
 
		return;
 
	}
 

	
 
	/* Tile area for TileHighlightData */
 
	TileArea location(TileVirtXY(_thd.pos.x, _thd.pos.y), _thd.size.x / TILE_SIZE - 1, _thd.size.y / TILE_SIZE - 1);
 

	
 
	/* Extended area by one tile */
 
	uint x = TileX(location.tile);
 
	uint y = TileY(location.tile);
 

	
 
	int max_c = 1;
 
	TileArea ta(TileXY(std::max<int>(0, x - max_c), std::max<int>(0, y - max_c)), TileXY(std::min<int>(MapMaxX(), x + location.w + max_c), std::min<int>(MapMaxY(), y + location.h + max_c)));
 

	
 
	Station *adjacent = nullptr;
 

	
 
	/* Direct loop instead of ForAllStationsAroundTiles as we are not interested in catchment area */
 
	TILE_AREA_LOOP(tile, ta) {
 
	for (TileIndex tile : ta) {
 
		if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) {
 
			Station *st = Station::GetByTile(tile);
 
			if (st == nullptr) continue;
 
			if (adjacent != nullptr && st != adjacent) {
 
				/* Multiple nearby, distant join is required. */
 
				adjacent = nullptr;
 
				break;
 
			}
 
			adjacent = st;
 
		}
 
	}
 
	SetViewportCatchmentStation(adjacent, true);
 
}
 

	
 
/**
 
 * Check whether we need to redraw the station coverage text.
 
 * If it is needed actually make the window for redrawing.
 
 * @param w the window to check.
 
 */
 
void CheckRedrawStationCoverage(const Window *w)
 
{
 
	/* Test if ctrl state changed */
 
	static bool _last_ctrl_pressed;
 
	if (_ctrl_pressed != _last_ctrl_pressed) {
 
		_thd.dirty = 0xff;
 
		_last_ctrl_pressed = _ctrl_pressed;
 
	}
 

	
 
	if (_thd.dirty & 1) {
 
		_thd.dirty &= ~1;
 
		w->SetDirty();
 

	
 
		if (_settings_client.gui.station_show_coverage && _thd.drawstyle == HT_RECT) {
 
			FindStationsAroundSelection();
 
		}
 
	}
 
}
 

	
 
/**
 
 * Draw small boxes of cargo amount and ratings data at the given
 
 * coordinates. If amount exceeds 576 units, it is shown 'full', same
 
 * goes for the rating: at above 90% orso (224) it is also 'full'
 
 *
 
 * @param left   left most coordinate to draw the box at
 
 * @param right  right most coordinate to draw the box at
 
 * @param y      coordinate to draw the box at
 
 * @param type   Cargo type
 
 * @param amount Cargo amount
 
@@ -2169,97 +2169,97 @@ static bool AddNearbyStation(TileIndex t
 
	TileArea *ctx = (TileArea *)user_data;
 

	
 
	/* First check if there were deleted stations here */
 
	for (uint i = 0; i < _deleted_stations_nearby.size(); i++) {
 
		auto ts = _deleted_stations_nearby.begin() + i;
 
		if (ts->tile == tile) {
 
			_stations_nearby_list.push_back(_deleted_stations_nearby[i].station);
 
			_deleted_stations_nearby.erase(ts);
 
			i--;
 
		}
 
	}
 

	
 
	/* Check if own station and if we stay within station spread */
 
	if (!IsTileType(tile, MP_STATION)) return false;
 

	
 
	StationID sid = GetStationIndex(tile);
 

	
 
	/* This station is (likely) a waypoint */
 
	if (!T::IsValidID(sid)) return false;
 

	
 
	T *st = T::Get(sid);
 
	if (st->owner != _local_company || std::find(_stations_nearby_list.begin(), _stations_nearby_list.end(), sid) != _stations_nearby_list.end()) return false;
 

	
 
	if (st->rect.BeforeAddRect(ctx->tile, ctx->w, ctx->h, StationRect::ADD_TEST).Succeeded()) {
 
		_stations_nearby_list.push_back(sid);
 
	}
 

	
 
	return false; // We want to include *all* nearby stations
 
}
 

	
 
/**
 
 * Circulate around the to-be-built station to find stations we could join.
 
 * Make sure that only stations are returned where joining wouldn't exceed
 
 * station spread and are our own station.
 
 * @param ta Base tile area of the to-be-built station
 
 * @param distant_join Search for adjacent stations (false) or stations fully
 
 *                     within station spread
 
 * @tparam T the type of station to look for
 
 */
 
template <class T>
 
static const T *FindStationsNearby(TileArea ta, bool distant_join)
 
{
 
	TileArea ctx = ta;
 

	
 
	_stations_nearby_list.clear();
 
	_deleted_stations_nearby.clear();
 

	
 
	/* Check the inside, to return, if we sit on another station */
 
	TILE_AREA_LOOP(t, ta) {
 
	for (TileIndex t : ta) {
 
		if (t < MapSize() && IsTileType(t, MP_STATION) && T::IsValidID(GetStationIndex(t))) return T::GetByTile(t);
 
	}
 

	
 
	/* Look for deleted stations */
 
	for (const BaseStation *st : BaseStation::Iterate()) {
 
		if (T::IsExpected(st) && !st->IsInUse() && st->owner == _local_company) {
 
			/* Include only within station spread (yes, it is strictly less than) */
 
			if (std::max(DistanceMax(ta.tile, st->xy), DistanceMax(TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1), st->xy)) < _settings_game.station.station_spread) {
 
				_deleted_stations_nearby.push_back({st->xy, st->index});
 

	
 
				/* Add the station when it's within where we're going to build */
 
				if (IsInsideBS(TileX(st->xy), TileX(ctx.tile), ctx.w) &&
 
						IsInsideBS(TileY(st->xy), TileY(ctx.tile), ctx.h)) {
 
					AddNearbyStation<T>(st->xy, &ctx);
 
				}
 
			}
 
		}
 
	}
 

	
 
	/* Only search tiles where we have a chance to stay within the station spread.
 
	 * The complete check needs to be done in the callback as we don't know the
 
	 * extent of the found station, yet. */
 
	if (distant_join && std::min(ta.w, ta.h) >= _settings_game.station.station_spread) return nullptr;
 
	uint max_dist = distant_join ? _settings_game.station.station_spread - std::min(ta.w, ta.h) : 1;
 

	
 
	TileIndex tile = TileAddByDir(ctx.tile, DIR_N);
 
	CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyStation<T>, &ctx);
 

	
 
	return nullptr;
 
}
 

	
 
static const NWidgetPart _nested_select_station_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
 
		NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_JS_CAPTION), SetDataTip(STR_JOIN_STATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
 
	EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_JS_PANEL), SetResize(1, 0), SetScrollbar(WID_JS_SCROLLBAR), EndContainer(),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_JS_SCROLLBAR),
 
			NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
/**
 
 * Window for selecting stations/waypoints to (distant) join to.