File diff r10498:bb2b452f76fe → r10499:570896340d7a
src/rail_gui.cpp
Show inline comments
 
@@ -73,28 +73,29 @@ static void HandleStationPlacement(TileI
 
static void ShowBuildTrainDepotPicker(Window *parent);
 
static void ShowBuildWaypointPicker(Window *parent);
 
static void ShowStationBuilder(Window *parent);
 
static void ShowSignalBuilder(Window *parent);
 

	
 
void CcPlaySound1E(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
	if (success) SndPlayTileFx(SND_20_SPLAT_2, tile);
 
}
 

	
 
static void GenericPlaceRail(TileIndex tile, int cmd)
 
{
 
	DoCommandP(tile, _cur_railtype, cmd, CcPlaySound1E,
 
	DoCommandP(tile, _cur_railtype, cmd,
 
		_remove_button_clicked ?
 
		CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) | CMD_NO_WATER :
 
		CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) | CMD_NO_WATER
 
		CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) | CMD_NO_WATER,
 
		CcPlaySound1E
 
	);
 
}
 

	
 
static void PlaceRail_N(TileIndex tile)
 
{
 
	int cmd = _tile_fract_coords.x > _tile_fract_coords.y ? 4 : 5;
 
	GenericPlaceRail(tile, cmd);
 
}
 

	
 
static void PlaceRail_NE(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_FIX_Y, DDSP_PLACE_RAIL_NE);
 
@@ -118,25 +119,25 @@ static void PlaceRail_AutoRail(TileIndex
 

	
 
/**
 
 * Try to add an additional rail-track at the entrance of a depot
 
 * @param tile  Tile to use for adding the rail-track
 
 * @param extra Track to add
 
 * @see CcRailDepot()
 
 */
 
static void PlaceExtraDepotRail(TileIndex tile, uint16 extra)
 
{
 
	if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
 
	if ((GetTrackBits(tile) & GB(extra, 8, 8)) == 0) return;
 

	
 
	DoCommandP(tile, _cur_railtype, extra & 0xFF, NULL, CMD_BUILD_SINGLE_RAIL | CMD_NO_WATER);
 
	DoCommandP(tile, _cur_railtype, extra & 0xFF, CMD_BUILD_SINGLE_RAIL | CMD_NO_WATER);
 
}
 

	
 
/** Additional pieces of track to add at the entrance of a depot. */
 
static const uint16 _place_depot_extra[12] = {
 
	0x0604, 0x2102, 0x1202, 0x0505,  // First additional track for directions 0..3
 
	0x2400, 0x2801, 0x1800, 0x1401,  // Second additional track
 
	0x2203, 0x0904, 0x0A05, 0x1103,  // Third additional track
 
};
 

	
 

	
 
void CcRailDepot(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
@@ -149,133 +150,133 @@ void CcRailDepot(bool success, TileIndex
 
		tile += TileOffsByDiagDir(dir);
 

	
 
		if (IsTileType(tile, MP_RAILWAY)) {
 
			PlaceExtraDepotRail(tile, _place_depot_extra[dir]);
 
			PlaceExtraDepotRail(tile, _place_depot_extra[dir + 4]);
 
			PlaceExtraDepotRail(tile, _place_depot_extra[dir + 8]);
 
		}
 
	}
 
}
 

	
 
static void PlaceRail_Depot(TileIndex tile)
 
{
 
	DoCommandP(tile, _cur_railtype, _build_depot_direction, CcRailDepot,
 
		CMD_BUILD_TRAIN_DEPOT | CMD_NO_WATER | CMD_MSG(STR_100E_CAN_T_BUILD_TRAIN_DEPOT));
 
	DoCommandP(tile, _cur_railtype, _build_depot_direction,
 
		CMD_BUILD_TRAIN_DEPOT | CMD_NO_WATER | CMD_MSG(STR_100E_CAN_T_BUILD_TRAIN_DEPOT),
 
		CcRailDepot);
 
}
 

	
 
static void PlaceRail_Waypoint(TileIndex tile)
 
{
 
	if (_remove_button_clicked) {
 
		DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT));
 
		DoCommandP(tile, 0, 0, CMD_REMOVE_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E);
 
	} else {
 
		DoCommandP(tile, _cur_waypoint_type, 0, CcPlaySound1E, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT));
 
		DoCommandP(tile, _cur_waypoint_type, 0, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT), CcPlaySound1E);
 
	}
 
}
 

	
 
void CcStation(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
	if (success) {
 
		SndPlayTileFx(SND_20_SPLAT_2, tile);
 
		/* Only close the station builder window if the default station is chosen. */
 
		if (_railstation.station_class == STAT_CLASS_DFLT && _railstation.station_type == 0) ResetObjectToPlace();
 
	}
 
}
 

	
 
static void PlaceRail_Station(TileIndex tile)
 
{
 
	if (_remove_button_clicked) {
 
		VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_REMOVE_STATION);
 
		VpSetPlaceSizingLimit(-1);
 
	} else if (_railstation.dragdrop) {
 
		VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
 
		VpSetPlaceSizingLimit(_settings_game.station.station_spread);
 
	} else {
 
		DoCommandP(tile,
 
				_railstation.orientation | (_railstation.numtracks << 8) | (_railstation.platlength << 16) | (_ctrl_pressed << 24),
 
				_cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16), CcStation,
 
				CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION));
 
				_cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16),
 
				CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION), CcStation);
 
	}
 
}
 

	
 
/**
 
 * Build a new signal or edit/remove a present signal, use CmdBuildSingleSignal() or CmdRemoveSingleSignal() in rail_cmd.cpp
 
 *
 
 * @param tile The tile where the signal will build or edit
 
 */
 
static void GenericPlaceSignals(TileIndex tile)
 
{
 
	TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
 

	
 
	if (trackbits & TRACK_BIT_VERT) { // N-S direction
 
		trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
 
	}
 

	
 
	if (trackbits & TRACK_BIT_HORZ) { // E-W direction
 
		trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
 
	}
 

	
 
	Track track = FindFirstTrack(trackbits);
 

	
 
	if (_remove_button_clicked) {
 
		DoCommandP(tile, track, 0, CcPlaySound1E,
 
			CMD_REMOVE_SIGNALS | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM));
 
		DoCommandP(tile, track, 0, CMD_REMOVE_SIGNALS | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound1E);
 
	} else {
 
		const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
 

	
 
		/* Map _patches.cycle_signal_types to the lower and upper allowed signal type. */
 
		static const uint cycle_bounds[] = {SIGTYPE_NORMAL | (SIGTYPE_LAST_NOPBS << 3), SIGTYPE_PBS | (SIGTYPE_LAST << 3), SIGTYPE_NORMAL | (SIGTYPE_LAST << 3)};
 

	
 
		/* various bitstuffed elements for CmdBuildSingleSignal() */
 
		uint32 p1 = track;
 

	
 
		if (w != NULL) {
 
			/* signal GUI is used */
 
			SB(p1, 3, 1, _ctrl_pressed);
 
			SB(p1, 4, 1, _cur_signal_variant);
 
			SB(p1, 5, 3, _cur_signal_type);
 
			SB(p1, 8, 1, _convert_signal_button);
 
			SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
 
		} else {
 
			SB(p1, 3, 1, _ctrl_pressed);
 
			SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
 
			SB(p1, 5, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
 
			SB(p1, 8, 1, 0);
 
			SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
 
		}
 

	
 
		DoCommandP(tile, p1, 0, CcPlaySound1E, CMD_BUILD_SIGNALS |
 
			CMD_MSG((w != NULL && _convert_signal_button) ? STR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_1010_CAN_T_BUILD_SIGNALS_HERE));
 
		DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS |
 
			CMD_MSG((w != NULL && _convert_signal_button) ? STR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_1010_CAN_T_BUILD_SIGNALS_HERE),
 
			CcPlaySound1E);
 
	}
 
}
 

	
 
static void PlaceRail_Bridge(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
 
}
 

	
 
/** Command callback for building a tunnel */
 
void CcBuildRailTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
	if (success) {
 
		SndPlayTileFx(SND_20_SPLAT_2, tile);
 
		ResetObjectToPlace();
 
	} else {
 
		SetRedErrorSquare(_build_tunnel_endtile);
 
	}
 
}
 

	
 
static void PlaceRail_Tunnel(TileIndex tile)
 
{
 
	DoCommandP(tile, _cur_railtype, 0, CcBuildRailTunnel,
 
		CMD_BUILD_TUNNEL | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE));
 
	DoCommandP(tile, _cur_railtype, 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
 
}
 

	
 
static void PlaceRail_ConvertRail(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_RAIL);
 
}
 

	
 
static void PlaceRail_AutoSignals(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_SIGNALDIRS, DDSP_BUILD_SIGNALS);
 
}
 

	
 
@@ -505,25 +506,25 @@ static void BuildRailClick_Remove(Window
 
 * Switches to 'convert-rail' mode
 
 * @param w Build-rail toolbar window
 
 * @see BuildRailToolbWndProc()
 
 */
 
static void BuildRailClick_Convert(Window *w)
 
{
 
	HandlePlacePushButton(w, RTW_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, VHM_RECT, PlaceRail_ConvertRail);
 
}
 

	
 

	
 
static void DoRailroadTrack(int mode)
 
{
 
	DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL,
 
	DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
 
		_remove_button_clicked ?
 
		CMD_REMOVE_RAILROAD_TRACK | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
 
		CMD_BUILD_RAILROAD_TRACK  | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
 
	);
 
}
 

	
 
static void HandleAutodirPlacement()
 
{
 
	TileHighlightData *thd = &_thd;
 
	int trackstat = thd->drawstyle & 0xF; // 0..5
 

	
 
	if (thd->drawstyle & HT_RAIL) { // one tile case
 
@@ -564,29 +565,28 @@ static void HandleAutoSignalPlacement()
 
		SB(p2,  4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
 
		SB(p2,  6, 1, _ctrl_pressed);
 
		SB(p2,  7, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
 
		SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
 
	}
 

	
 
	/* _settings_client.gui.drag_signals_density is given as a parameter such that each user
 
	 * in a network game can specify his/her own signal density */
 
	DoCommandP(
 
		TileVirtXY(thd->selstart.x, thd->selstart.y),
 
		TileVirtXY(thd->selend.x, thd->selend.y),
 
		p2,
 
		CcPlaySound1E,
 
		_remove_button_clicked ?
 
			CMD_REMOVE_SIGNAL_TRACK | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
 
			CMD_BUILD_SIGNAL_TRACK  | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE)
 
	);
 
			CMD_BUILD_SIGNAL_TRACK  | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE),
 
		CcPlaySound1E);
 
}
 

	
 

	
 
typedef void OnButtonClick(Window *w);
 

	
 
/** Data associated with a push button in the build rail toolbar window */
 
struct RailBuildingGUIButtonData {
 
	uint16 keycode;            ///< Keycode associated with the button
 
	OnButtonClick *click_proc; ///< Procedure to call when button is clicked
 
};
 

	
 
/**
 
@@ -718,31 +718,31 @@ struct BuildRailToolbarWindow : Window {
 
					HandleAutodirPlacement();
 
					break;
 

	
 
				case DDSP_BUILD_SIGNALS:
 
					HandleAutoSignalPlacement();
 
					break;
 

	
 
				case DDSP_DEMOLISH_AREA:
 
					GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
 
					break;
 

	
 
				case DDSP_CONVERT_RAIL:
 
					DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL));
 
					DoCommandP(end_tile, start_tile, _cur_railtype, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL), CcPlaySound10);
 
					break;
 

	
 
				case DDSP_REMOVE_STATION:
 
				case DDSP_BUILD_STATION:
 
					if (_remove_button_clicked) {
 
						DoCommandP(end_tile, start_tile, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION));
 
						DoCommandP(end_tile, start_tile, 0, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION), CcPlaySound1E);
 
						break;
 
					}
 
					HandleStationPlacement(start_tile, end_tile);
 
					break;
 

	
 
				case DDSP_PLACE_RAIL_NE:
 
				case DDSP_PLACE_RAIL_NW:
 
					DoRailroadTrack(select_proc == DDSP_PLACE_RAIL_NE ? TRACK_X : TRACK_Y);
 
					break;
 
			}
 
		}
 
	}
 
@@ -871,26 +871,26 @@ static void HandleStationPlacement(TileI
 
	uint ex = TileX(end);
 
	uint ey = TileY(end);
 
	uint w,h;
 

	
 
	if (sx > ex) Swap(sx, ex);
 
	if (sy > ey) Swap(sy, ey);
 
	w = ex - sx + 1;
 
	h = ey - sy + 1;
 
	if (_railstation.orientation == AXIS_X) Swap(w, h);
 

	
 
	DoCommandP(TileXY(sx, sy),
 
			_railstation.orientation | (w << 8) | (h << 16) | (_ctrl_pressed << 24),
 
			_cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16), CcStation,
 
			CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION));
 
			_cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16),
 
			CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION), CcStation);
 
}
 

	
 
struct BuildRailStationWindow : public PickerWindowBase {
 
private:
 
	/** Enum referring to the widgets of the rail stations window */
 
	enum BuildRailStationWidgets {
 
		BRSW_CLOSEBOX = 0,
 
		BRSW_CAPTION,
 
		BRSW_BACKGROUND,
 

	
 
		BRSW_PLATFORM_DIR_X,
 
		BRSW_PLATFORM_DIR_Y,