Changeset - r19263:8bc163eb7eb2
[Not reviewed]
master
0 9 0
frosch - 12 years ago 2012-04-22 16:28:14
frosch@openttd.org
(svn r24166) -Codechange: Turn NewGRFClass::Get(Tid, uint) and GetCount(Tid) into non-static members GetSpec(uint) and GetSpecCount().
9 files changed with 72 insertions and 80 deletions:
0 comments (0 inline, 0 general)
src/airport_gui.cpp
Show inline comments
 
@@ -48,25 +48,25 @@ void CcBuildAirport(const CommandCost &r
 
}
 

	
 
/**
 
 * Place an airport.
 
 * @param tile Position to put the new airport.
 
 */
 
static void PlaceAirport(TileIndex tile)
 
{
 
	if (_selected_airport_index == -1) return;
 
	uint32 p2 = _ctrl_pressed;
 
	SB(p2, 16, 16, INVALID_STATION); // no station to join
 

	
 
	uint32 p1 = AirportClass::Get(_selected_airport_class, _selected_airport_index)->GetIndex();
 
	uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
 
	p1 |= _selected_airport_layout << 8;
 
	CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT | CMD_MSG(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE), CcBuildAirport, "" };
 
	ShowSelectStationIfNeeded(cmdcont, TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE));
 
}
 

	
 
/** Airport build toolbar window handler. */
 
struct BuildAirToolbarWindow : Window {
 
	int last_user_action; // Last started user action.
 

	
 
	BuildAirToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
 
	{
 
		this->InitNested(desc, window_number);
 
@@ -220,44 +220,44 @@ public:
 
		this->CreateNestedTree(desc);
 

	
 
		this->vscroll = this->GetScrollbar(WID_AP_SCROLLBAR);
 
		this->vscroll->SetCapacity(5);
 
		this->vscroll->SetPosition(0);
 

	
 
		this->FinishInitNested(desc, TRANSPORT_AIR);
 

	
 
		this->SetWidgetLoweredState(WID_AP_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage);
 
		this->SetWidgetLoweredState(WID_AP_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage);
 
		this->OnInvalidateData();
 

	
 
		this->vscroll->SetCount(AirportClass::GetCount(_selected_airport_class));
 
		this->vscroll->SetCount(AirportClass::Get(_selected_airport_class)->GetSpecCount());
 
		this->SelectFirstAvailableAirport(true);
 
	}
 

	
 
	virtual ~BuildAirportWindow()
 
	{
 
		DeleteWindowById(WC_SELECT_STATION, 0);
 
	}
 

	
 
	virtual void SetStringParameters(int widget) const
 
	{
 
		switch (widget) {
 
			case WID_AP_CLASS_DROPDOWN:
 
				SetDParam(0, AirportClass::Get(_selected_airport_class)->name);
 
				break;
 

	
 
			case WID_AP_LAYOUT_NUM:
 
				SetDParam(0, STR_EMPTY);
 
				if (_selected_airport_index != -1) {
 
					const AirportSpec *as = AirportClass::Get(_selected_airport_class, _selected_airport_index);
 
					const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
 
					StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_LAYOUT_NAME);
 
					if (string != STR_UNDEFINED) {
 
						SetDParam(0, string);
 
					} else if (as->num_table > 1) {
 
						SetDParam(0, STR_STATION_BUILD_AIRPORT_LAYOUT_NAME);
 
						SetDParam(1, _selected_airport_layout + 1);
 
					}
 
				}
 
				break;
 

	
 
			default: break;
 
		}
 
@@ -323,67 +323,68 @@ public:
 
				}
 
				break;
 

	
 
			default: break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (widget) {
 
			case WID_AP_AIRPORT_LIST: {
 
				int y = r.top;
 
				for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < AirportClass::GetCount(_selected_airport_class); i++) {
 
					const AirportSpec *as = AirportClass::Get(_selected_airport_class, i);
 
				AirportClass *apclass = AirportClass::Get(_selected_airport_class);
 
				for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < apclass->GetSpecCount(); i++) {
 
					const AirportSpec *as = apclass->GetSpec(i);
 
					if (!as->IsAvailable()) {
 
						GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, PC_BLACK, FILLRECT_CHECKER);
 
					}
 
					DrawString(r.left + WD_MATRIX_LEFT, r.right + WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK);
 
					y += this->line_height;
 
				}
 
				break;
 
			}
 

	
 
			case WID_AP_AIRPORT_SPRITE:
 
				if (this->preview_sprite != 0) {
 
					Dimension d = GetSpriteSize(this->preview_sprite);
 
					DrawSprite(this->preview_sprite, COMPANY_SPRITE_COLOUR(_local_company), (r.left + r.right - d.width) / 2, (r.top + r.bottom - d.height) / 2);
 
				}
 
				break;
 

	
 
			case WID_AP_EXTRA_TEXT:
 
				if (_selected_airport_index != -1) {
 
					const AirportSpec *as = AirportClass::Get(_selected_airport_class, _selected_airport_index);
 
					const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
 
					StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_ADDITIONAL_TEXT);
 
					if (string != STR_UNDEFINED) {
 
						SetDParam(0, string);
 
						DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_BLACK_STRING);
 
					}
 
				}
 
				break;
 
		}
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		this->DrawWidgets();
 

	
 
		uint16 top = this->GetWidget<NWidgetBase>(WID_AP_BTN_DOHILIGHT)->pos_y + this->GetWidget<NWidgetBase>(WID_AP_BTN_DOHILIGHT)->current_y + WD_PAR_VSEP_NORMAL;
 
		NWidgetBase *panel_nwi = this->GetWidget<NWidgetBase>(WID_AP_BOTTOMPANEL);
 

	
 
		int right = panel_nwi->pos_x +  panel_nwi->current_x;
 
		int bottom = panel_nwi->pos_y +  panel_nwi->current_y;
 

	
 
		if (_selected_airport_index != -1) {
 
			const AirportSpec *as = AirportClass::Get(_selected_airport_class, _selected_airport_index);
 
			const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
 
			int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED;
 

	
 
			/* only show the station (airport) noise, if the noise option is activated */
 
			if (_settings_game.economy.station_noise_level) {
 
				/* show the noise of the selected airport */
 
				SetDParam(0, as->noise_level);
 
				DrawString(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_STATION_BUILD_NOISE);
 
				top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
 
			}
 

	
 
			/* strings such as 'Size' and 'Coverage Area' */
 
			top = DrawStationCoverageAreaText(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL;
 
@@ -403,25 +404,25 @@ public:
 

	
 
		this->UpdateSelectSize();
 
		this->SetDirty();
 
	}
 

	
 
	void UpdateSelectSize()
 
	{
 
		if (_selected_airport_index == -1) {
 
			SetTileSelectSize(1, 1);
 
			this->DisableWidget(WID_AP_LAYOUT_DECREASE);
 
			this->DisableWidget(WID_AP_LAYOUT_INCREASE);
 
		} else {
 
			const AirportSpec *as = AirportClass::Get(_selected_airport_class, _selected_airport_index);
 
			const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
 
			int w = as->size_x;
 
			int h = as->size_y;
 
			Direction rotation = as->rotation[_selected_airport_layout];
 
			if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
 
			SetTileSelectSize(w, h);
 

	
 
			this->preview_sprite = GetCustomAirportSprite(as, _selected_airport_layout);
 

	
 
			this->SetWidgetDisabledState(WID_AP_LAYOUT_DECREASE, _selected_airport_layout == 0);
 
			this->SetWidgetDisabledState(WID_AP_LAYOUT_INCREASE, _selected_airport_layout + 1 >= as->num_table);
 

	
 
			int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED;
 
@@ -430,25 +431,25 @@ public:
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (widget) {
 
			case WID_AP_CLASS_DROPDOWN:
 
				ShowDropDownList(this, BuildAirportClassDropDown(), _selected_airport_class, WID_AP_CLASS_DROPDOWN);
 
				break;
 

	
 
			case WID_AP_AIRPORT_LIST: {
 
				int num_clicked = this->vscroll->GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height;
 
				if (num_clicked >= this->vscroll->GetCount()) break;
 
				const AirportSpec *as = AirportClass::Get(_selected_airport_class, num_clicked);
 
				const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
 
				if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);
 
				break;
 
			}
 

	
 
			case WID_AP_BTN_DONTHILIGHT: case WID_AP_BTN_DOHILIGHT:
 
				_settings_client.gui.station_show_coverage = (widget != WID_AP_BTN_DONTHILIGHT);
 
				this->SetWidgetLoweredState(WID_AP_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage);
 
				this->SetWidgetLoweredState(WID_AP_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage);
 
				this->SetDirty();
 
				SndPlayFx(SND_15_BEEP);
 
				this->UpdateSelectSize();
 
				break;
 
@@ -466,54 +467,56 @@ public:
 
				break;
 
		}
 
	}
 

	
 
	/**
 
	 * Select the first available airport.
 
	 * @param change_class If true, change the class if no airport in the current
 
	 *   class is available.
 
	 */
 
	void SelectFirstAvailableAirport(bool change_class)
 
	{
 
		/* First try to select an airport in the selected class. */
 
		for (uint i = 0; i < AirportClass::GetCount(_selected_airport_class); i++) {
 
			const AirportSpec *as = AirportClass::Get(_selected_airport_class, i);
 
		AirportClass *sel_apclass = AirportClass::Get(_selected_airport_class);
 
		for (uint i = 0; i < sel_apclass->GetSpecCount(); i++) {
 
			const AirportSpec *as = sel_apclass->GetSpec(i);
 
			if (as->IsAvailable()) {
 
				this->SelectOtherAirport(i);
 
				return;
 
			}
 
		}
 
		if (change_class) {
 
			/* If that fails, select the first available airport
 
			 * from a random class. */
 
			for (AirportClassID j = APC_BEGIN; j < APC_MAX; j++) {
 
				for (uint i = 0; i < AirportClass::GetCount(j); i++) {
 
					const AirportSpec *as = AirportClass::Get(j, i);
 
				AirportClass *apclass = AirportClass::Get(j);
 
				for (uint i = 0; i < apclass->GetSpecCount(); i++) {
 
					const AirportSpec *as = apclass->GetSpec(i);
 
					if (as->IsAvailable()) {
 
						_selected_airport_class = j;
 
						this->SelectOtherAirport(i);
 
						return;
 
					}
 
				}
 
			}
 
		}
 
		/* If all airports are unavailable, select nothing. */
 
		this->SelectOtherAirport(-1);
 
	}
 

	
 
	virtual void OnDropdownSelect(int widget, int index)
 
	{
 
		assert(widget == WID_AP_CLASS_DROPDOWN);
 
		_selected_airport_class = (AirportClassID)index;
 
		this->vscroll->SetCount(AirportClass::GetCount(_selected_airport_class));
 
		this->vscroll->SetCount(AirportClass::Get(_selected_airport_class)->GetSpecCount());
 
		this->SelectFirstAvailableAirport(false);
 
	}
 

	
 
	virtual void OnTick()
 
	{
 
		CheckRedrawStationCoverage(this);
 
	}
 
};
 

	
 
static const NWidgetPart _nested_build_airport_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
src/newgrf_class.h
Show inline comments
 
@@ -32,24 +32,27 @@ private:
 

	
 
	void ResetClass();
 

	
 
	/** Initialise the defaults. */
 
	static void InsertDefaults();
 

	
 
public:
 
	uint32 global_id; ///< Global ID for class, e.g. 'DFLT', 'WAYP', etc.
 
	StringID name;    ///< Name of this class.
 

	
 
	void Insert(Tspec *spec);
 

	
 
	/** Get the number of allocated specs within the class. */
 
	uint GetSpecCount() const { return this->count; }
 

	
 
	const Tspec *GetSpec(uint index) const;
 

	
 
	static void Reset();
 
	static Tid Allocate(uint32 global_id);
 
	static void Assign(Tspec *spec);
 
	static NewGRFClass *Get(Tid cls_id);
 

	
 
	static uint GetCount();
 
	static uint GetCount(Tid cls_id);
 
	static const Tspec *Get(Tid cls_id, uint index);
 
	static const Tspec *GetByGrf(uint32 grfid, byte local_id, int *index);
 
};
 

	
 
#endif /* NEWGRF_CLASS_H */
src/newgrf_class_func.h
Show inline comments
 
@@ -108,49 +108,32 @@ NewGRFClass<Tspec, Tid, Tmax> *NewGRFCla
 
/**
 
 * Get the number of allocated classes.
 
 * @return The number of classes.
 
 */
 
DEFINE_NEWGRF_CLASS_METHOD(uint)::GetCount()
 
{
 
	uint i;
 
	for (i = 0; i < Tmax && classes[i].global_id != 0; i++) {}
 
	return i;
 
}
 

	
 
/**
 
 * Get the number of allocated specs within a particular class.
 
 * @param cls_id The class to get the size of.
 
 * @pre cls_id < GetCount()
 
 * @return The size of the class.
 
 */
 
DEFINE_NEWGRF_CLASS_METHOD(uint)::GetCount(Tid cls_id)
 
{
 
	assert(cls_id < Tmax);
 
	return classes[cls_id].count;
 
}
 

	
 
/**
 
 * Get a spec from a particular class at a given index.
 
 * @param cls_id The class to get the spec from.
 
 * Get a spec from the class at a given index.
 
 * @param index  The index where to find the spec.
 
 * @pre index < GetCount(cls_id)
 
 * @return The spec at given location.
 
 */
 
DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::Get(Tid cls_id, uint index)
 
DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetSpec(uint index) const
 
{
 
	assert(cls_id < Tmax);
 
	if (index < classes[cls_id].count) return classes[cls_id].spec[index];
 

	
 
	/* If the custom spec isn't defined any more, then the GRF file probably was not loaded. */
 
	return NULL;
 
	return index < this->GetSpecCount() ? this->spec[index] : NULL;
 
}
 

	
 
/**
 
 * Retrieve a spec by GRF location.
 
 * @param grfid    GRF ID of spec.
 
 * @param local_id Index within GRF file of spec.
 
 * @param index    Pointer to return the index of the spec in its class. If NULL then not used.
 
 * @return The spec.
 
 */
 
DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetByGrf(uint32 grfid, byte local_id, int *index)
 
{
 
	uint j;
 
@@ -171,15 +154,14 @@ DEFINE_NEWGRF_CLASS_METHOD(const Tspec *
 

	
 
#undef DEFINE_NEWGRF_CLASS_METHOD
 

	
 
/** Force instantiation of the methods so we don't get linker errors. */
 
#define INSTANTIATE_NEWGRF_CLASS_METHODS(name, Tspec, Tid, Tmax) \
 
	template void name::ResetClass(); \
 
	template void name::Reset(); \
 
	template Tid name::Allocate(uint32 global_id); \
 
	template void name::Insert(Tspec *spec); \
 
	template void name::Assign(Tspec *spec); \
 
	template NewGRFClass<Tspec, Tid, Tmax> *name::Get(Tid cls_id); \
 
	template uint name::GetCount(); \
 
	template uint name::GetCount(Tid cls_id); \
 
	template const Tspec *name::Get(Tid cls_id, uint index); \
 
	template const Tspec *name::GetSpec(uint index) const; \
 
	template const Tspec *name::GetByGrf(uint32 grfid, byte localidx, int *index);
src/newgrf_station.cpp
Show inline comments
 
@@ -796,31 +796,30 @@ void DeallocateSpecFromStation(BaseStati
 
/**
 
 * Draw representation of a station tile for GUI purposes.
 
 * @param x Position x of image.
 
 * @param y Position y of image.
 
 * @param axis Axis.
 
 * @param railtype Rail type.
 
 * @param sclass, station Type of station.
 
 * @param station station ID
 
 * @return True if the tile was drawn (allows for fallback to default graphic)
 
 */
 
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
 
{
 
	const StationSpec *statspec;
 
	const DrawTileSprites *sprites = NULL;
 
	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
	PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
 
	uint tile = 2;
 

	
 
	statspec = StationClass::Get(sclass, station);
 
	const StationSpec *statspec = StationClass::Get(sclass)->GetSpec(station);
 
	if (statspec == NULL) return false;
 

	
 
	if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) {
 
		uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE);
 
		if (callback != CALLBACK_FAILED) tile = callback;
 
	}
 

	
 
	uint32 total_offset = rti->GetRailtypeSpriteOffset();
 
	uint32 relocation = 0;
 
	uint32 ground_relocation = 0;
 
	const NewGRFSpriteLayout *layout = NULL;
 
	DrawTileSprites tmp_rail_layout;
src/object_gui.cpp
Show inline comments
 
@@ -42,36 +42,36 @@ public:
 
		this->vscroll = this->GetScrollbar(WID_BO_SCROLLBAR);
 
		this->vscroll->SetCapacity(5);
 
		this->vscroll->SetPosition(0);
 
		this->vscroll->SetCount(ObjectClass::GetCount());
 

	
 
		this->FinishInitNested(desc, 0);
 

	
 
		this->SelectFirstAvailableObject(true);
 
		this->GetWidget<NWidgetMatrix>(WID_BO_OBJECT_MATRIX)->SetCount(4);
 

	
 
		NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BO_SELECT_MATRIX);
 
		matrix->SetScrollbar(this->GetScrollbar(WID_BO_SELECT_SCROLL));
 
		matrix->SetCount(ObjectClass::GetCount(_selected_object_class));
 
		matrix->SetCount(ObjectClass::Get(_selected_object_class)->GetSpecCount());
 
	}
 

	
 
	virtual ~BuildObjectWindow()
 
	{
 
	}
 

	
 
	virtual void SetStringParameters(int widget) const
 
	{
 
		switch (widget) {
 
			case WID_BO_OBJECT_SIZE: {
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
				int size = spec == NULL ? 0 : spec->size;
 
				SetDParam(0, GB(size, HasBit(_selected_object_view, 0) ? 4 : 0, 4));
 
				SetDParam(1, GB(size, HasBit(_selected_object_view, 0) ? 0 : 4, 4));
 
				break;
 
			}
 

	
 
			default: break;
 
		}
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
 
@@ -80,25 +80,25 @@ public:
 
				for (uint i = 0; i < ObjectClass::GetCount(); i++) {
 
					size->width = max(size->width, GetStringBoundingBox(ObjectClass::Get((ObjectClassID)i)->name).width);
 
				}
 
				size->width += padding.width;
 
				this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
 
				resize->height = this->line_height;
 
				size->height = this->vscroll->GetCapacity() * this->line_height;
 
				break;
 
			}
 

	
 
			case WID_BO_OBJECT_MATRIX: {
 
				/* Get the right amount of buttons based on the current spec. */
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
				if (spec != NULL) {
 
					if (spec->views >= 2) size->width  += resize->width;
 
					if (spec->views >= 4) size->height += resize->height;
 
				}
 
				resize->width = 0;
 
				resize->height = 0;
 
				break;
 
			}
 

	
 
			case WID_BO_OBJECT_SPRITE: {
 
				bool two_wide = false;  // Whether there will be two widgets next to eachother in the matrix or not.
 
				int height[2] = {0, 0}; // The height for the different views; in this case views 1/2 and 4.
 
@@ -120,25 +120,25 @@ public:
 
				/* Now determine the size of the minimum widgets. When there are two columns, then
 
				 * we want these columns to be slightly less wide. When there are two rows, then
 
				 * determine the size of the widgets based on the maximum size for a single row
 
				 * of widgets, or just the twice the widget height of the two row ones. */
 
				size->height = max(height[0], height[1] * 2 + 2);
 
				if (two_wide) {
 
					size->width  = (3 * TILE_PIXELS + 2 * OBJECT_MARGIN) * 2 + 2;
 
				} else {
 
					size->width  = 4 * TILE_PIXELS + 2 * OBJECT_MARGIN;
 
				}
 

	
 
				/* Get the right size for the single widget based on the current spec. */
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
				if (spec != NULL) {
 
					if (spec->views >= 2) size->width  = size->width  / 2 - 1;
 
					if (spec->views >= 4) size->height = size->height / 2 - 1;
 
				}
 
				break;
 
			}
 

	
 
			case WID_BO_INFO:
 
				size->height = this->info_height;
 
				break;
 

	
 
			case WID_BO_SELECT_MATRIX:
 
@@ -156,74 +156,74 @@ public:
 
			case WID_BO_CLASS_LIST: {
 
				int y = r.top;
 
				for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < ObjectClass::GetCount(); i++) {
 
					SetDParam(0, ObjectClass::Get((ObjectClassID)i)->name);
 
					DrawString(r.left + WD_MATRIX_LEFT, r.right + WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, STR_JUST_STRING,
 
							((int)i == _selected_object_class) ? TC_WHITE : TC_BLACK);
 
					y += this->line_height;
 
				}
 
				break;
 
			}
 

	
 
			case WID_BO_OBJECT_SPRITE: {
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
				if (spec == NULL) break;
 

	
 
				DrawPixelInfo tmp_dpi;
 
				/* Set up a clipping area for the preview. */
 
				if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) {
 
					DrawPixelInfo *old_dpi = _cur_dpi;
 
					_cur_dpi = &tmp_dpi;
 
					if (spec->grf_prop.grffile == NULL) {
 
						extern const DrawTileSprites _objects[];
 
						const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id];
 
						DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - TILE_PIXELS, dts, PAL_NONE);
 
					} else {
 
						DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - TILE_PIXELS, spec, GB(widget, 16, 16));
 
					}
 
					_cur_dpi = old_dpi;
 
				}
 
				break;
 
			}
 

	
 
			case WID_BO_SELECT_IMAGE: {
 
				if (_selected_object_index < 0) break;
 

	
 
				int obj_index = GB(widget, 16, 16);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, obj_index);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(obj_index);
 
				if (spec == NULL) break;
 

	
 
				if (!spec->IsAvailable()) {
 
					GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER);
 
				}
 
				DrawPixelInfo tmp_dpi;
 
				/* Set up a clipping area for the preview. */
 
				if (FillDrawPixelInfo(&tmp_dpi, r.left + 1, r.top, (r.right - 1) - (r.left + 1) + 1, r.bottom - r.top + 1)) {
 
					DrawPixelInfo *old_dpi = _cur_dpi;
 
					_cur_dpi = &tmp_dpi;
 
					if (spec->grf_prop.grffile == NULL) {
 
						extern const DrawTileSprites _objects[];
 
						const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id];
 
						DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - TILE_PIXELS, dts, PAL_NONE);
 
					} else {
 
						DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - TILE_PIXELS, spec,
 
								min(_selected_object_view, spec->views - 1));
 
					}
 
					_cur_dpi = old_dpi;
 
				}
 
				break;
 
			}
 

	
 
			case WID_BO_INFO: {
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
				if (spec == NULL) break;
 

	
 
				/* Get the extra message for the GUI */
 
				if (HasBit(spec->callback_mask, CBM_OBJ_FUND_MORE_TEXT)) {
 
					uint16 callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, NULL, INVALID_TILE, _selected_object_view);
 
					if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
 
						if (callback_res > 0x400) {
 
							ErrorUnknownCallbackResult(spec->grf_prop.grffile->grfid, CBID_OBJECT_FUND_MORE_TEXT, callback_res);
 
						} else {
 
							StringID message = GetGRFStringID(spec->grf_prop.grffile->grfid, 0xD000 + callback_res);
 
							if (message != STR_NULL && message != STR_UNDEFINED) {
 
								StartTextRefStackUsage(6);
 
@@ -244,107 +244,109 @@ public:
 
			}
 
		}
 
	}
 

	
 
	/**
 
	 * Select the specified object in #_selected_object_class class.
 
	 * @param object_index Object index to select, \c -1 means select nothing.
 
	 */
 
	void SelectOtherObject(int object_index)
 
	{
 
		_selected_object_index = object_index;
 
		if (_selected_object_index != -1) {
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
			_selected_object_view = min(_selected_object_view, spec->views - 1);
 
			this->ReInit();
 
		} else {
 
			_selected_object_view = 0;
 
		}
 

	
 
		this->GetWidget<NWidgetMatrix>(WID_BO_OBJECT_MATRIX)->SetClicked(_selected_object_view);
 
		this->GetWidget<NWidgetMatrix>(WID_BO_SELECT_MATRIX)->SetClicked(_selected_object_index);
 
		this->UpdateSelectSize();
 
		this->SetDirty();
 
	}
 

	
 
	void UpdateSelectSize()
 
	{
 
		if (_selected_object_index == -1) {
 
			SetTileSelectSize(1, 1);
 
		} else {
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, _selected_object_index);
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
 
			int w = GB(spec->size, HasBit(_selected_object_view, 0) ? 4 : 0, 4);
 
			int h = GB(spec->size, HasBit(_selected_object_view, 0) ? 0 : 4, 4);
 
			SetTileSelectSize(w, h);
 
		}
 
	}
 

	
 
	virtual void OnResize()
 
	{
 
		this->vscroll->SetCapacityFromWidget(this, WID_BO_CLASS_LIST);
 
		this->GetWidget<NWidgetCore>(WID_BO_CLASS_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (GB(widget, 0, 16)) {
 
			case WID_BO_CLASS_LIST: {
 
				int num_clicked = this->vscroll->GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height;
 
				if (num_clicked >= (int)ObjectClass::GetCount()) break;
 

	
 
				_selected_object_class = (ObjectClassID)num_clicked;
 
				this->GetWidget<NWidgetMatrix>(WID_BO_SELECT_MATRIX)->SetCount(ObjectClass::GetCount(_selected_object_class));
 
				this->GetWidget<NWidgetMatrix>(WID_BO_SELECT_MATRIX)->SetCount(ObjectClass::Get(_selected_object_class)->GetSpecCount());
 
				this->SelectFirstAvailableObject(false);
 
				break;
 
			}
 

	
 
			case WID_BO_SELECT_IMAGE: {
 
				int num_clicked = GB(widget, 16, 16);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, num_clicked);
 
				const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(num_clicked);
 
				if (spec->IsAvailable()) this->SelectOtherObject(num_clicked);
 
				break;
 
			}
 

	
 
			case WID_BO_OBJECT_SPRITE:
 
				if (_selected_object_index != -1) {
 
					_selected_object_view = GB(widget, 16, 16);
 
					this->GetWidget<NWidgetMatrix>(WID_BO_OBJECT_MATRIX)->SetClicked(_selected_object_view);
 
					this->UpdateSelectSize();
 
					this->SetDirty();
 
				}
 
				break;
 
		}
 
	}
 

	
 
	/**
 
	 * Select the first available object.
 
	 * @param change_class If true, change the class if no object in the current
 
	 *   class is available.
 
	 */
 
	void SelectFirstAvailableObject(bool change_class)
 
	{
 
		/* First try to select an object in the selected class. */
 
		for (uint i = 0; i < ObjectClass::GetCount(_selected_object_class); i++) {
 
			const ObjectSpec *spec = ObjectClass::Get(_selected_object_class, i);
 
		ObjectClass *sel_objclass = ObjectClass::Get(_selected_object_class);
 
		for (uint i = 0; i < sel_objclass->GetSpecCount(); i++) {
 
			const ObjectSpec *spec = sel_objclass->GetSpec(i);
 
			if (spec->IsAvailable()) {
 
				this->SelectOtherObject(i);
 
				return;
 
			}
 
		}
 
		if (change_class) {
 
			/* If that fails, select the first available object
 
			 * from a random class. */
 
			for (ObjectClassID j = OBJECT_CLASS_BEGIN; j < OBJECT_CLASS_MAX; j++) {
 
				for (uint i = 0; i < ObjectClass::GetCount(j); i++) {
 
					const ObjectSpec *spec = ObjectClass::Get(j, i);
 
				ObjectClass *objclass = ObjectClass::Get(j);
 
				for (uint i = 0; i < objclass->GetSpecCount(); i++) {
 
					const ObjectSpec *spec = objclass->GetSpec(i);
 
					if (spec->IsAvailable()) {
 
						_selected_object_class = j;
 
						this->SelectOtherObject(i);
 
						return;
 
					}
 
				}
 
			}
 
		}
 
		/* If all objects are unavailable, select nothing. */
 
		this->SelectOtherObject(-1);
 
	}
 
};
 
@@ -409,14 +411,14 @@ void ShowBuildObjectPicker(Window *w)
 
void InitializeObjectGui()
 
{
 
	_selected_object_class = (ObjectClassID)0;
 
}
 

	
 
/**
 
 * PlaceProc function, called when someone pressed the button if the
 
 *  object-tool is selected
 
 * @param tile on which to place the object
 
 */
 
void PlaceProc_Object(TileIndex tile)
 
{
 
	DoCommandP(tile, ObjectClass::Get(_selected_object_class, _selected_object_index)->Index(), _selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
 
	DoCommandP(tile, ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index(), _selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
 
}
src/rail_gui.cpp
Show inline comments
 
@@ -540,25 +540,25 @@ struct BuildRailToolbarWindow : Window {
 
				this->last_user_action = widget;
 
				break;
 

	
 
			case WID_RAT_BUILD_DEPOT:
 
				if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT)) {
 
					ShowBuildTrainDepotPicker(this);
 
					this->last_user_action = widget;
 
				}
 
				break;
 

	
 
			case WID_RAT_BUILD_WAYPOINT:
 
				this->last_user_action = widget;
 
				_waypoint_count = StationClass::GetCount(STAT_CLASS_WAYP);
 
				_waypoint_count = StationClass::Get(STAT_CLASS_WAYP)->GetSpecCount();
 
				if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT) && _waypoint_count > 1) {
 
					ShowBuildWaypointPicker(this);
 
				}
 
				break;
 

	
 
			case WID_RAT_BUILD_STATION:
 
				if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT)) {
 
					ShowStationBuilder(this);
 
					this->last_user_action = widget;
 
				}
 
				break;
 

	
 
@@ -936,25 +936,25 @@ public:
 
		}
 
		this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
 
		this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
 

	
 
		if (!newstation || _railstation.station_class >= (int)StationClass::GetCount()) {
 
			/* New stations are not available or changed, so ensure the default station
 
			 * type is 'selected'. */
 
			_railstation.station_class = STAT_CLASS_DFLT;
 
			_railstation.station_type = 0;
 
			this->vscroll2 = NULL;
 
		}
 
		if (newstation) {
 
			_railstation.station_count = StationClass::GetCount(_railstation.station_class);
 
			_railstation.station_count = StationClass::Get(_railstation.station_class)->GetSpecCount();
 
			_railstation.station_type = min(_railstation.station_type, _railstation.station_count - 1);
 

	
 
			int count = 0;
 
			for (uint i = 0; i < StationClass::GetCount(); i++) {
 
				if (i == STAT_CLASS_WAYP) continue;
 
				count++;
 
			}
 
			this->vscroll = this->GetScrollbar(WID_BRAS_NEWST_SCROLL);
 
			this->vscroll->SetCount(count);
 
			this->vscroll->SetCapacity(GB(this->GetWidget<NWidgetCore>(WID_BRAS_NEWST_LIST)->widget_data, MAT_ROW_START, MAT_ROW_BITS));
 
			this->vscroll->SetPosition(Clamp(_railstation.station_class - 2, 0, max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0)));
 

	
 
@@ -965,25 +965,25 @@ public:
 
			matrix->SetClicked(_railstation.station_type);
 
		}
 
	}
 

	
 
	virtual ~BuildRailStationWindow()
 
	{
 
		DeleteWindowById(WC_SELECT_STATION, 0);
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		bool newstations = _railstation.newstations;
 
		const StationSpec *statspec = newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
 
		const StationSpec *statspec = newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL;
 

	
 
		if (_settings_client.gui.station_dragdrop) {
 
			SetTileSelectSize(1, 1);
 
		} else {
 
			int x = _settings_client.gui.station_numtracks;
 
			int y = _settings_client.gui.station_platlength;
 
			if (_railstation.orientation == AXIS_X) Swap(x, y);
 
			if (!_remove_button_clicked) {
 
				SetTileSelectSize(x, y);
 
			}
 
		}
 

	
 
@@ -1039,26 +1039,27 @@ public:
 
			case WID_BRAS_SHOW_NEWST_TYPE: {
 
				if (!_railstation.newstations) {
 
					size->width = 0;
 
					size->height = 0;
 
					break;
 
				}
 

	
 
				/* If newstations exist, compute the non-zero minimal size. */
 
				Dimension d = {0, 0};
 
				StringID str = this->GetWidget<NWidgetCore>(widget)->widget_data;
 
				for (StationClassID statclass = STAT_CLASS_BEGIN; statclass < (StationClassID)StationClass::GetCount(); statclass++) {
 
					if (statclass == STAT_CLASS_WAYP) continue;
 
					for (uint16 j = 0; j < StationClass::GetCount(statclass); j++) {
 
						const StationSpec *statspec = StationClass::Get(statclass, j);
 
					StationClass *stclass = StationClass::Get(statclass);
 
					for (uint16 j = 0; j < stclass->GetSpecCount(); j++) {
 
						const StationSpec *statspec = stclass->GetSpec(j);
 
						SetDParam(0, (statspec != NULL && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT);
 
						d = maxdim(d, GetStringBoundingBox(str));
 
					}
 
				}
 
				size->width = max(size->width, d.width + padding.width);
 
				break;
 
			}
 

	
 
			case WID_BRAS_COVERAGE_TEXTS:
 
				size->height = this->coverage_height;
 
				break;
 

	
 
@@ -1109,25 +1110,25 @@ public:
 
								(StationClassID)i == _railstation.station_class ? TC_WHITE : TC_BLACK);
 
						row++;
 
					}
 
					statclass++;
 
				}
 
				break;
 
			}
 

	
 
			case WID_BRAS_IMAGE: {
 
				byte type = GB(widget, 16, 16);
 
				assert(type < _railstation.station_count);
 
				/* Check station availability callback */
 
				const StationSpec *statspec = StationClass::Get(_railstation.station_class, type);
 
				const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(type);
 
				if (!IsStationAvailable(statspec)) {
 
					GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER);
 
				}
 

	
 
				/* Set up a clipping area for the station preview. */
 
				if (FillDrawPixelInfo(&tmp_dpi, r.left + 1, r.top + 1, r.right - (r.left + 1) + 1, r.bottom - 1 - (r.top + 1) + 1)) {
 
					DrawPixelInfo *old_dpi = _cur_dpi;
 
					_cur_dpi = &tmp_dpi;
 
					if (!DrawStationTile(31, 29, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) {
 
						StationPickerDrawSprite(31, 29, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation);
 
					}
 
					_cur_dpi = old_dpi;
 
@@ -1139,25 +1140,25 @@ public:
 

	
 
	virtual void OnResize()
 
	{
 
		if (this->vscroll != NULL) { // New stations available.
 
			this->vscroll->SetCapacityFromWidget(this, WID_BRAS_NEWST_LIST);
 
			this->GetWidget<NWidgetCore>(WID_BRAS_NEWST_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START);
 
		}
 
	}
 

	
 
	virtual void SetStringParameters(int widget) const
 
	{
 
		if (widget == WID_BRAS_SHOW_NEWST_TYPE) {
 
			const StationSpec *statspec = StationClass::Get(_railstation.station_class, _railstation.station_type);
 
			const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type);
 
			SetDParam(0, (statspec != NULL && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT);
 
		}
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (GB(widget, 0, 16)) {
 
			case WID_BRAS_PLATFORM_DIR_X:
 
			case WID_BRAS_PLATFORM_DIR_Y:
 
				this->RaiseWidget(_railstation.orientation + WID_BRAS_PLATFORM_DIR_X);
 
				_railstation.orientation = (Axis)(widget - WID_BRAS_PLATFORM_DIR_X);
 
				this->LowerWidget(_railstation.orientation + WID_BRAS_PLATFORM_DIR_X);
 
@@ -1172,25 +1173,25 @@ public:
 
			case WID_BRAS_PLATFORM_NUM_4:
 
			case WID_BRAS_PLATFORM_NUM_5:
 
			case WID_BRAS_PLATFORM_NUM_6:
 
			case WID_BRAS_PLATFORM_NUM_7: {
 
				this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
 
				this->RaiseWidget(WID_BRAS_PLATFORM_DRAG_N_DROP);
 

	
 
				_settings_client.gui.station_numtracks = widget - WID_BRAS_PLATFORM_NUM_BEGIN;
 
				_settings_client.gui.station_dragdrop = false;
 

	
 
				_settings_client.gui.station_dragdrop = false;
 

	
 
				const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
 
				const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL;
 
				if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
 
					/* The previously selected number of platforms in invalid */
 
					for (uint i = 0; i < 7; i++) {
 
						if (!HasBit(statspec->disallowed_lengths, i)) {
 
							this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
 
							_settings_client.gui.station_platlength = i + 1;
 
							break;
 
						}
 
					}
 
				}
 

	
 
				this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
 
@@ -1207,25 +1208,25 @@ public:
 
			case WID_BRAS_PLATFORM_LEN_4:
 
			case WID_BRAS_PLATFORM_LEN_5:
 
			case WID_BRAS_PLATFORM_LEN_6:
 
			case WID_BRAS_PLATFORM_LEN_7: {
 
				this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
 
				this->RaiseWidget(WID_BRAS_PLATFORM_DRAG_N_DROP);
 

	
 
				_settings_client.gui.station_platlength = widget - WID_BRAS_PLATFORM_LEN_BEGIN;
 
				_settings_client.gui.station_dragdrop = false;
 

	
 
				_settings_client.gui.station_dragdrop = false;
 

	
 
				const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
 
				const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL;
 
				if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
 
					/* The previously selected number of tracks in invalid */
 
					for (uint i = 0; i < 7; i++) {
 
						if (!HasBit(statspec->disallowed_platforms, i)) {
 
							this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
 
							_settings_client.gui.station_numtracks = i + 1;
 
							break;
 
						}
 
					}
 
				}
 

	
 
				this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
 
@@ -1233,25 +1234,25 @@ public:
 
				SndPlayFx(SND_15_BEEP);
 
				this->SetDirty();
 
				DeleteWindowById(WC_SELECT_STATION, 0);
 
				break;
 
			}
 

	
 
			case WID_BRAS_PLATFORM_DRAG_N_DROP: {
 
				_settings_client.gui.station_dragdrop ^= true;
 

	
 
				this->ToggleWidgetLoweredState(WID_BRAS_PLATFORM_DRAG_N_DROP);
 

	
 
				/* get the first allowed length/number of platforms */
 
				const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class, _railstation.station_type) : NULL;
 
				const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL;
 
				if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) {
 
					for (uint i = 0; i < 7; i++) {
 
						if (!HasBit(statspec->disallowed_lengths, i)) {
 
							this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
 
							_settings_client.gui.station_platlength = i + 1;
 
							break;
 
						}
 
					}
 
				}
 
				if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) {
 
					for (uint i = 0; i < 7; i++) {
 
						if (!HasBit(statspec->disallowed_platforms, i)) {
 
@@ -1279,49 +1280,50 @@ public:
 
				SndPlayFx(SND_15_BEEP);
 
				this->SetDirty();
 
				break;
 

	
 
			case WID_BRAS_NEWST_LIST: {
 
				int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BRAS_NEWST_LIST, 0, this->line_height);
 
				if (y >= (int)StationClass::GetCount()) return;
 
				for (uint i = 0; i < StationClass::GetCount(); i++) {
 
					if (i == STAT_CLASS_WAYP) continue;
 
					if (y == 0) {
 
						if (_railstation.station_class != (StationClassID)i) {
 
							_railstation.station_class = (StationClassID)i;
 
							_railstation.station_count = StationClass::GetCount(_railstation.station_class);
 
							StationClass *stclass = StationClass::Get(_railstation.station_class);
 
							_railstation.station_count = stclass->GetSpecCount();
 
							_railstation.station_type  = min((int)_railstation.station_type, max(0, (int)_railstation.station_count - 1));
 

	
 
							this->CheckSelectedSize(StationClass::Get(_railstation.station_class, _railstation.station_type));
 
							this->CheckSelectedSize(stclass->GetSpec(_railstation.station_type));
 

	
 
							NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BRAS_MATRIX);
 
							matrix->SetCount(_railstation.station_count);
 
							matrix->SetClicked(_railstation.station_type);
 
						}
 
						SndPlayFx(SND_15_BEEP);
 
						this->SetDirty();
 
						DeleteWindowById(WC_SELECT_STATION, 0);
 
						break;
 
					}
 
					y--;
 
				}
 
				break;
 
			}
 

	
 
			case WID_BRAS_IMAGE: {
 
				int y = GB(widget, 16, 16);
 
				if (y >= _railstation.station_count) return;
 

	
 
				/* Check station availability callback */
 
				const StationSpec *statspec = StationClass::Get(_railstation.station_class, y);
 
				const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(y);
 
				if (!IsStationAvailable(statspec)) return;
 

	
 
				_railstation.station_type = y;
 

	
 
				this->CheckSelectedSize(statspec);
 
				this->GetWidget<NWidgetMatrix>(WID_BRAS_MATRIX)->SetClicked(_railstation.station_type);
 

	
 
				SndPlayFx(SND_15_BEEP);
 
				this->SetDirty();
 
				DeleteWindowById(WC_SELECT_STATION, 0);
 
				break;
 
			}
 
@@ -1426,25 +1428,25 @@ static const NWidgetPart _nested_station
 

	
 
/** High level window description of the station-build window (default & newGRF) */
 
static const WindowDesc _station_builder_desc(
 
	WDP_AUTO, 350, 0,
 
	WC_BUILD_STATION, WC_BUILD_TOOLBAR,
 
	WDF_CONSTRUCTION,
 
	_nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
 
);
 

	
 
/** Open station build window */
 
static void ShowStationBuilder(Window *parent)
 
{
 
	bool newstations = StationClass::GetCount() > 2 || StationClass::GetCount(STAT_CLASS_DFLT) != 1;
 
	bool newstations = StationClass::GetCount() > 2 || StationClass::Get(STAT_CLASS_DFLT)->GetSpecCount() != 1;
 
	new BuildRailStationWindow(&_station_builder_desc, parent, newstations);
 
}
 

	
 
struct BuildSignalWindow : public PickerWindowBase {
 
private:
 
	/**
 
	 * Draw dynamic a signal-sprite in a button in the signal GUI
 
	 * Draw the sprite +1px to the right and down if the button is lowered and change the sprite to sprite + 1 (red to green light)
 
	 *
 
	 * @param widget_index index of this widget in the window
 
	 * @param image        the sprite to draw
 
	 */
 
@@ -1732,43 +1734,43 @@ struct BuildRailWaypointWindow : PickerW
 

	
 
				/* Resizing in X direction only at blob size, but at pixel level in Y. */
 
				resize->height = 1;
 
				break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		switch (GB(widget, 0, 16)) {
 
			case WID_BRW_WAYPOINT: {
 
				byte type = GB(widget, 16, 16);
 
				const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
 
				const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(type);
 
				DrawWaypointSprite(r.left + TILE_PIXELS, r.bottom - TILE_PIXELS, type, _cur_railtype);
 

	
 
				if (!IsStationAvailable(statspec)) {
 
					GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER);
 
				}
 
			}
 
		}
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (GB(widget, 0, 16)) {
 
			case WID_BRW_WAYPOINT: {
 
				byte type = GB(widget, 16, 16);
 
				this->GetWidget<NWidgetMatrix>(WID_BRW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
 

	
 
				/* Check station availability callback */
 
				const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
 
				const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(type);
 
				if (!IsStationAvailable(statspec)) return;
 

	
 
				_cur_waypoint_type = type;
 
				this->GetWidget<NWidgetMatrix>(WID_BRW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
 
				SndPlayFx(SND_15_BEEP);
 
				this->SetDirty();
 
				break;
 
			}
 
		}
 
	}
 
};
 

	
src/saveload/waypoint_sl.cpp
Show inline comments
 
@@ -67,33 +67,34 @@ void MoveWaypointsToBaseStations()
 
	/* In version 17, ground type is moved from m2 to m4 for depots and
 
	 * waypoints to make way for storing the index in m2. The custom graphics
 
	 * id which was stored in m4 is now saved as a grf/id reference in the
 
	 * waypoint struct. */
 
	if (IsSavegameVersionBefore(17)) {
 
		for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
 
			if (wp->delete_ctr != 0) continue; // The waypoint was deleted
 

	
 
			/* Waypoint indices were not added to the map prior to this. */
 
			_m[wp->xy].m2 = (StationID)wp->index;
 

	
 
			if (HasBit(_m[wp->xy].m3, 4)) {
 
				wp->spec = StationClass::Get(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1);
 
				wp->spec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(_m[wp->xy].m4 + 1);
 
			}
 
		}
 
	} else {
 
		/* As of version 17, we recalculate the custom graphic ID of waypoints
 
		 * from the GRF ID / station index. */
 
		for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
 
			for (uint i = 0; i < StationClass::GetCount(STAT_CLASS_WAYP); i++) {
 
				const StationSpec *statspec =  StationClass::Get(STAT_CLASS_WAYP, i);
 
			StationClass* stclass = StationClass::Get(STAT_CLASS_WAYP);
 
			for (uint i = 0; i < stclass->GetSpecCount(); i++) {
 
				const StationSpec *statspec = stclass->GetSpec(i);
 
				if (statspec != NULL && statspec->grf_prop.grffile->grfid == wp->grfid && statspec->grf_prop.local_id == wp->localidx) {
 
					wp->spec = statspec;
 
					break;
 
				}
 
			}
 
		}
 
	}
 

	
 
	if (!Waypoint::CanAllocateItem(_old_waypoints.Length())) SlError(STR_ERROR_TOO_MANY_STATIONS_LOADING);
 

	
 
	/* All saveload conversions have been done. Create the new waypoints! */
 
	for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
src/station_cmd.cpp
Show inline comments
 
@@ -735,25 +735,25 @@ CommandCost CheckFlatLand(TileArea tile_
 
 * @param spec_class Station class.
 
 * @param spec_index Index into the station class.
 
 * @param plat_len Platform length.
 
 * @param numtracks Number of platforms.
 
 * @return The cost in case of success, or an error code if it failed.
 
 */
 
static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, SmallVector<Train *, 4> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
 
{
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	int allowed_z = -1;
 
	uint invalid_dirs = 5 << axis;
 

	
 
	const StationSpec *statspec = StationClass::Get(spec_class, spec_index);
 
	const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index);
 
	bool slope_cb = statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_SLOPE_CHECK);
 

	
 
	TILE_AREA_LOOP(tile_cur, tile_area) {
 
		CommandCost ret = CheckBuildableTile(tile_cur, invalid_dirs, allowed_z, false);
 
		if (ret.Failed()) return ret;
 
		cost.AddCost(ret);
 

	
 
		if (slope_cb) {
 
			/* Do slope check if requested. */
 
			ret = PerformStationTileSlopeCheck(tile_area.tile, tile_cur, statspec, axis, plat_len, numtracks);
 
			if (ret.Failed()) return ret;
 
		}
 
@@ -1097,25 +1097,25 @@ CommandCost CmdBuildRailStation(TileInde
 
	StationClassID spec_class = Extract<StationClassID, 0, 8>(p2);
 
	byte spec_index           = GB(p2, 8, 8);
 
	StationID station_to_join = GB(p2, 16, 16);
 

	
 
	/* Does the authority allow this? */
 
	CommandCost ret = CheckIfAuthorityAllowsNewStation(tile_org, flags);
 
	if (ret.Failed()) return ret;
 

	
 
	if (!ValParamRailtype(rt)) return CMD_ERROR;
 

	
 
	/* Check if the given station class is valid */
 
	if ((uint)spec_class >= StationClass::GetCount() || spec_class == STAT_CLASS_WAYP) return CMD_ERROR;
 
	if (spec_index >= StationClass::GetCount(spec_class)) return CMD_ERROR;
 
	if (spec_index >= StationClass::Get(spec_class)->GetSpecCount()) return CMD_ERROR;
 
	if (plat_len == 0 || numtracks == 0) return CMD_ERROR;
 

	
 
	int w_org, h_org;
 
	if (axis == AXIS_X) {
 
		w_org = plat_len;
 
		h_org = numtracks;
 
	} else {
 
		h_org = plat_len;
 
		w_org = numtracks;
 
	}
 

	
 
	bool reuse = (station_to_join != NEW_STATION);
 
@@ -1166,25 +1166,25 @@ CommandCost CmdBuildRailStation(TileInde
 
			st = new Station(tile_org);
 

	
 
			st->town = ClosestTownFromTile(tile_org, UINT_MAX);
 
			st->string_id = GenerateStationName(st, tile_org, STATIONNAMING_RAIL);
 

	
 
			if (Company::IsValidID(_current_company)) {
 
				SetBit(st->town->have_ratings, _current_company);
 
			}
 
		}
 
	}
 

	
 
	/* Check if we can allocate a custom stationspec to this station */
 
	const StationSpec *statspec = StationClass::Get(spec_class, spec_index);
 
	const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index);
 
	int specindex = AllocateSpecToStation(statspec, st, (flags & DC_EXEC) != 0);
 
	if (specindex == -1) return_cmd_error(STR_ERROR_TOO_MANY_STATION_SPECS);
 

	
 
	if (statspec != NULL) {
 
		/* Perform NewStation checks */
 

	
 
		/* Check if the station size is permitted */
 
		if (HasBit(statspec->disallowed_platforms, numtracks - 1) || HasBit(statspec->disallowed_lengths, plat_len - 1)) {
 
			return CMD_ERROR;
 
		}
 

	
 
		/* Check if the station is buildable */
src/waypoint_cmd.cpp
Show inline comments
 
@@ -161,25 +161,25 @@ CommandCost CmdBuildRailWaypoint(TileInd
 
	/* Unpack parameters */
 
	Axis axis      = Extract<Axis, 4, 1>(p1);
 
	byte width     = GB(p1,  8, 8);
 
	byte height    = GB(p1, 16, 8);
 
	bool adjacent  = HasBit(p1, 24);
 

	
 
	StationClassID spec_class = Extract<StationClassID, 0, 8>(p2);
 
	byte spec_index           = GB(p2, 8, 8);
 
	StationID station_to_join = GB(p2, 16, 16);
 

	
 
	/* Check if the given station class is valid */
 
	if (spec_class != STAT_CLASS_WAYP) return CMD_ERROR;
 
	if (spec_index >= StationClass::GetCount(spec_class)) return CMD_ERROR;
 
	if (spec_index >= StationClass::Get(spec_class)->GetSpecCount()) return CMD_ERROR;
 

	
 
	/* The number of parts to build */
 
	byte count = axis == AXIS_X ? height : width;
 

	
 
	if ((axis == AXIS_X ? width : height) != 1) return CMD_ERROR;
 
	if (count == 0 || count > _settings_game.station.station_spread) return CMD_ERROR;
 

	
 
	bool reuse = (station_to_join != NEW_STATION);
 
	if (!reuse) station_to_join = INVALID_STATION;
 
	bool distant_join = (station_to_join != INVALID_STATION);
 

	
 
	if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
 
@@ -233,25 +233,25 @@ CommandCost CmdBuildRailWaypoint(TileInd
 
		wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY);
 

	
 
		wp->delete_ctr = 0;
 
		wp->facilities |= FACIL_TRAIN;
 
		wp->build_date = _date;
 
		wp->string_id = STR_SV_STNAME_WAYPOINT;
 
		wp->train_station = new_location;
 

	
 
		if (wp->town == NULL) MakeDefaultName(wp);
 

	
 
		wp->UpdateVirtCoord();
 

	
 
		const StationSpec *spec = StationClass::Get(spec_class, spec_index);
 
		const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index);
 
		byte *layout_ptr = AllocaM(byte, count);
 
		if (spec == NULL) {
 
			/* The layout must be 0 for the 'normal' waypoints by design. */
 
			memset(layout_ptr, 0, count);
 
		} else {
 
			/* But for NewGRF waypoints we like to have their style. */
 
			GetStationLayout(layout_ptr, count, 1, spec);
 
		}
 
		byte map_spec_index = AllocateSpecToStation(spec, wp, true);
 

	
 
		Company *c = Company::Get(wp->owner);
 
		for (int i = 0; i < count; i++) {
0 comments (0 inline, 0 general)