Changeset - r12545:0db872ffb197
[Not reviewed]
master
0 7 0
rubidium - 15 years ago 2009-07-30 17:44:13
rubidium@openttd.org
(svn r16993) -Change: make the rail waypoint builder draggable
7 files changed with 128 insertions and 62 deletions:
0 comments (0 inline, 0 general)
src/pathfind.h
Show inline comments
 
@@ -90,10 +90,7 @@ void NewTrainPathfind(TileIndex tile, Ti
 
 */
 
static inline TileIndex CalcClosestStationTile(StationID station, TileIndex tile)
 
{
 
	const BaseStation *bst = BaseStation::Get(station);
 
	if (Waypoint::IsExpected(bst)) return bst->xy;
 

	
 
	const Station *st = Station::From(bst);
 
	const BaseStation *st = BaseStation::Get(station);
 

	
 
	/* If the rail station is (temporarily) not present, use the station sign to drive near the station */
 
	if (st->train_station.tile == INVALID_TILE) return st->xy;
src/rail_gui.cpp
Show inline comments
 
@@ -150,8 +150,18 @@ static void PlaceRail_Waypoint(TileIndex
 
{
 
	if (_remove_button_clicked) {
 
		VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_STATION);
 
		return;
 
	}
 

	
 
	TrackBits bits = IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_NORMAL ? GetTrackBits(tile) : TRACK_BIT_NONE;
 
	Track track = RemoveFirstTrack(&bits);
 
	if (bits == TRACK_BIT_NONE && IsDiagonalTrack(track)) {
 
		/* Valid tile for waypoints */
 
		VpStartPlaceSizing(tile, track == TRACK_X ? VPM_FIX_X : VPM_FIX_Y, DDSP_BUILD_STATION);
 
	} else {
 
		DoCommandP(tile, _cur_waypoint_type, 0, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT), CcPlaySound1E);
 
		/* Tile where we can't build rail waypoints. This is always going to fail,
 
		 * but provides the user with a proper error message. */
 
		DoCommandP(tile, 0, 0, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT));
 
	}
 
}
 

	
 
@@ -760,6 +770,13 @@ struct BuildRailToolbarWindow : Window {
 
						/* Waypoint */
 
						if (_remove_button_clicked) {
 
							DoCommandP(end_tile, start_tile, 0, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E);
 
						} else {
 
							TileArea ta(start_tile, end_tile);
 
							uint32 p1 = _cur_railtype | (select_method == VPM_FIX_X ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
 
							uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;
 

	
 
							CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT), CcPlaySound1E, "" };
 
							ShowSelectStationIfNeeded(cmdcont, ta);
 
						}
 
					}
 
					break;
src/saveload/afterload.cpp
Show inline comments
 
@@ -1882,6 +1882,22 @@ bool AfterLoadGame()
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(124)) {
 
		/* The train station tile area was added */
 
		Waypoint *wp;
 
		FOR_ALL_WAYPOINTS(wp) {
 
			if (wp->facilities & FACIL_TRAIN) {
 
				wp->train_station.tile = wp->xy;
 
				wp->train_station.w = 1;
 
				wp->train_station.h = 1;
 
			} else {;
 
				wp->train_station.tile = INVALID_TILE;
 
				wp->train_station.w = 0;
 
				wp->train_station.h = 0;
 
			}
 
		}
 
	}
 

	
 
	AfterLoadLabelMaps();
 

	
 
	GamelogPrintDebug(1);
src/saveload/saveload.cpp
Show inline comments
 
@@ -41,7 +41,7 @@
 

	
 
#include "saveload_internal.h"
 

	
 
extern const uint16 SAVEGAME_VERSION = 123;
 
extern const uint16 SAVEGAME_VERSION = 124;
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 

	
src/saveload/station_sl.cpp
Show inline comments
 
@@ -95,11 +95,6 @@ void AfterLoadStations()
 

	
 
		if (Station::IsExpected(st)) {
 
			for (CargoID c = 0; c < NUM_CARGO; c++) Station::From(st)->goods[c].cargo.InvalidateCache();
 
		} else if (st->facilities & FACIL_TRAIN) {
 
			/* Temporary fill this variable with correct data. */
 
			st->train_station.tile = st->xy;
 
			st->train_station.w = 1;
 
			st->train_station.h = 1;
 
		}
 

	
 
		StationUpdateAnimTriggers(st);
 
@@ -332,6 +327,10 @@ static const SaveLoad _waypoint_desc[] =
 

	
 
	      SLE_VAR(Waypoint, town_cn,                   SLE_UINT16),
 

	
 
	  SLE_CONDVAR(Waypoint, train_station.tile,        SLE_UINT32,                  124, SL_MAX_VERSION),
 
	  SLE_CONDVAR(Waypoint, train_station.w,           SLE_UINT8,                   124, SL_MAX_VERSION),
 
	  SLE_CONDVAR(Waypoint, train_station.h,           SLE_UINT8,                   124, SL_MAX_VERSION),
 

	
 
	      SLE_END()
 
};
 

	
src/station_cmd.cpp
Show inline comments
 
@@ -796,7 +796,7 @@ static inline byte *CreateMulti(byte *la
 
	return layout;
 
}
 

	
 
static void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec)
 
void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec)
 
{
 
	if (statspec != NULL && statspec->lengths >= plat_len &&
 
			statspec->platforms[plat_len - 1] >= numtracks &&
src/waypoint_cmd.cpp
Show inline comments
 
@@ -120,30 +120,16 @@ static Waypoint *FindDeletedWaypointClos
 
	return best;
 
}
 

	
 
/** Convert existing rail to waypoint. Eg build a waypoint station over
 
 * piece of rail
 
 * @param tile tile where waypoint will be built
 
 * @param flags type of operation
 
 * @param p1 graphics for waypoint type, 0 indicates standard graphics
 
 * @param p2 unused
 
 * @param text unused
 
 * @return cost of operation or error
 
 *
 
 * @todo When checking for the tile slope,
 
 * distingush between "Flat land required" and "land sloped in wrong direction"
 
/**
 
 * Check whether the given tile is suitable for a waypoint.
 
 * @param tile the tile to check for suitability
 
 * @param axis the axis of the waypoint
 
 */
 
CommandCost CmdBuildRailWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
static CommandCost IsValidTileForWaypoint(TileIndex tile, Axis axis)
 
{
 
	Axis axis;
 

	
 
	/* if custom gfx are used, make sure it is within bounds */
 
	if (p1 >= GetNumCustomStations(STAT_CLASS_WAYP)) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_RAILWAY) ||
 
			GetRailTileType(tile) != RAIL_TILE_NORMAL || (
 
				(axis = AXIS_X, GetTrackBits(tile) != TRACK_BIT_X) &&
 
				(axis = AXIS_Y, GetTrackBits(tile) != TRACK_BIT_Y)
 
			)) {
 
			GetRailTileType(tile) != RAIL_TILE_NORMAL ||
 
			GetTrackBits(tile) != AxisToTrackBits(axis)) {
 
		return_cmd_error(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK);
 
	}
 

	
 
@@ -159,55 +145,106 @@ CommandCost CmdBuildRailWaypoint(TileInd
 

	
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	return CommandCost();
 
}
 

	
 
extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec);
 

	
 
/** Convert existing rail to waypoint. Eg build a waypoint station over
 
 * piece of rail
 
 * @param start_tile northern most tile where waypoint will be built
 
 * @param flags type of operation
 
 * @param p1 various bitstuffed elements
 
 * - p1 = (bit  4)    - orientation (Axis)
 
 * - p1 = (bit  8-15) - width of waypoint
 
 * - p1 = (bit 16-23) - height of waypoint
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit  0- 7) - custom station class
 
 * - p2 = (bit  8-15) - custom station id
 
 * @param text unused
 
 * @return cost of operation or error
 
 */
 
CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	/* Unpack parameters */
 
	Axis axis      = (Axis)GB(p1,  4, 1);
 
	byte width     = GB(p1,  8, 8);
 
	byte height    = GB(p1, 16, 8);
 

	
 
	StationClassID spec_class = (StationClassID)GB(p2, 0, 8);
 
	byte spec_index           = GB(p2, 8, 8);
 

	
 
	/* Check if the given station class is valid */
 
	if (spec_class != STAT_CLASS_WAYP) return CMD_ERROR;
 
	if (spec_index >= GetNumCustomStations(spec_class)) 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;
 

	
 
	/* Check whether the tiles we're building on are valid rail or not. */
 
	TileIndexDiff offset = TileOffsByDiagDir(AxisToDiagDir(OtherAxis(axis)));
 
	for (int i = 0; i < count; i++) {
 
		TileIndex tile = start_tile + i * offset;
 
		CommandCost ret = IsValidTileForWaypoint(tile, axis);
 
		if (ret.Failed()) return ret;
 
	}
 

	
 
	/* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
 
	Waypoint *wp = FindDeletedWaypointCloseTo(tile, STR_SV_STNAME_WAYPOINT);
 
	TileIndex center_tile = start_tile + (count / 2) * offset;
 
	Waypoint *wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT);
 
	if (wp == NULL && !Waypoint::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING);
 

	
 
	if (flags & DC_EXEC) {
 
		if (wp == NULL) {
 
			wp = new Waypoint(tile);
 
		} else {
 
			wp = new Waypoint(start_tile);
 
		} else if (!wp->IsInUse()) {
 
			/* Move existing (recently deleted) waypoint to the new location */
 

	
 
			/* First we update the destination for all vehicles that
 
			 * have the old waypoint in their orders. */
 
			Vehicle *v;
 
			FOR_ALL_TRAINS(v) {
 
				if (v->First() == v && v->current_order.IsType(OT_GOTO_WAYPOINT) &&
 
						v->dest_tile == wp->xy) {
 
					v->dest_tile = tile;
 
				}
 
			}
 

	
 
			wp->xy = tile;
 
			wp->xy = start_tile;
 
			InvalidateWindowData(WC_WAYPOINT_VIEW, wp->index);
 
		}
 
		wp->owner = owner;
 

	
 
		wp->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
 
		wp->owner = GetTileOwner(start_tile);
 

	
 
		bool reserved = HasBit(GetRailReservationTrackBits(tile), AxisToTrack(axis));
 
		MakeRailWaypoint(tile, owner, wp->index, axis, 0, GetRailType(tile));
 
		SetRailStationReservation(tile, reserved);
 
		MarkTileDirtyByTile(tile);
 

	
 
		SetCustomStationSpecIndex(tile, AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, p1), wp, true));
 
		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.tile = tile;
 
		wp->train_station.w = 1;
 
		wp->train_station.h = 1;
 
		wp->train_station.tile = start_tile;
 
		wp->train_station.w = width;
 
		wp->train_station.h = height;
 

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

	
 
		wp->UpdateVirtCoord();
 
		YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
 

	
 
		const StationSpec *spec = GetCustomStationSpec(spec_class, 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);
 

	
 
		for (int i = 0; i < count; i++) {
 
			TileIndex tile = start_tile + i * offset;
 
			bool reserved = HasBit(GetRailReservationTrackBits(tile), AxisToTrack(axis));
 
			MakeRailWaypoint(tile, wp->owner, wp->index, axis, layout_ptr[i], GetRailType(tile));
 
			SetCustomStationSpecIndex(tile, map_spec_index);
 
			SetRailStationReservation(tile, reserved);
 
			MarkTileDirtyByTile(tile);
 

	
 
			YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
 
		}
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_train_depot);
 
	return CommandCost(EXPENSES_CONSTRUCTION, count * _price.build_train_depot);
 
}
 

	
 
/** Build a buoy.
0 comments (0 inline, 0 general)