Changeset - r12462:a7cb564c6c56
[Not reviewed]
master
0 40 0
rubidium - 15 years ago 2009-07-22 08:59:57
rubidium@openttd.org
(svn r16909) -Fix [FS#2996]: NewGRF stations would be triggering assertions all over the place when using the more advanced station types.
-Change: make (rail) waypoints sub classes of 'base stations', make buoys waypoints and unify code between them where possible.
40 files changed with 605 insertions and 609 deletions:
0 comments (0 inline, 0 general)
src/ai/api/ai_buoylist.cpp
Show inline comments
 
@@ -3,12 +3,12 @@
 
/** @file ai_buoylist.cpp Implementation of AIBuoyList and friends. */
 

	
 
#include "ai_buoylist.hpp"
 
#include "../../station_base.h"
 
#include "../../waypoint.h"
 

	
 
AIBuoyList::AIBuoyList()
 
{
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		if (st->IsBuoy()) this->AddItem(st->xy);
 
	Waypoint *wp;
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->facilities & FACIL_DOCK) this->AddItem(wp->xy);
 
	}
 
}
src/ai/api/ai_order.cpp
Show inline comments
 
@@ -25,18 +25,14 @@ static OrderType GetOrderTypeByTile(Tile
 
	switch (::GetTileType(t)) {
 
		default: break;
 
		case MP_STATION:
 
			if (IsBuoy(t) || IsRailWaypoint(t)) return OT_GOTO_WAYPOINT;
 
			if (IsHangar(t)) return OT_GOTO_DEPOT;
 
			if (IsBuoy(t)) return OT_GOTO_WAYPOINT;
 
			return OT_GOTO_STATION;
 
			break;
 
		case MP_WATER:   if (::IsShipDepot(t)) return OT_GOTO_DEPOT; break;
 
		case MP_ROAD:    if (::GetRoadTileType(t) == ROAD_TILE_DEPOT) return OT_GOTO_DEPOT; break;
 
		case MP_RAILWAY:
 
			switch (::GetRailTileType(t)) {
 
				case RAIL_TILE_DEPOT:    return OT_GOTO_DEPOT;
 
				case RAIL_TILE_WAYPOINT: return OT_GOTO_WAYPOINT;
 
				default: break;
 
			}
 
			if (IsRailDepot(t)) return OT_GOTO_DEPOT;
 
			break;
 
	}
 

	
 
@@ -359,7 +355,7 @@ static const Order *ResolveOrder(Vehicle
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
 
			order.MakeGoToWaypoint(::Vehicle::Get(vehicle_id)->type == VEH_TRAIN ? ::GetWaypointIndex(destination) : ::GetStationIndex(destination));
 
			order.MakeGoToWaypoint(::GetStationIndex(destination));
 
			break;
 

	
 
		default:
src/ai/api/ai_rail.cpp
Show inline comments
 
@@ -45,7 +45,7 @@
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_RAILWAY) && ::IsRailWaypointTile(tile);
 
	return ::IsRailWaypointTile(tile);
 
}
 

	
 
/* static */ bool AIRail::IsRailTypeAvailable(RailType rail_type)
 
@@ -200,8 +200,7 @@
 
{
 
	if (!IsRailTile(tile)) return RAILTRACK_INVALID;
 

	
 
	if (IsRailWaypointTile(tile)) return ::GetRailWaypointBits(tile);
 
	if (IsRailStationTile(tile)) return ::TrackToTrackBits(::GetRailStationTrack(tile));
 
	if (IsRailStationTile(tile) || IsRailWaypointTile(tile)) return ::TrackToTrackBits(::GetRailStationTrack(tile));
 
	if (IsLevelCrossingTile(tile)) return ::GetCrossingRailBits(tile);
 
	if (IsRailDepotTile(tile)) return ::TRACK_BIT_NONE;
 
	return ::GetTrackBits(tile);
src/ai/api/ai_waypoint.cpp
Show inline comments
 
@@ -22,7 +22,7 @@
 
{
 
	if (!AIRail::IsRailWaypointTile(tile)) return WAYPOINT_INVALID;
 

	
 
	return ::GetWaypointIndex(tile);
 
	return ::GetStationIndex(tile);
 
}
 

	
 
/* static */ char *AIWaypoint::GetName(WaypointID waypoint_id)
src/ai/api/ai_waypointlist.cpp
Show inline comments
 
@@ -13,7 +13,7 @@ AIWaypointList::AIWaypointList()
 
{
 
	const Waypoint *wp;
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->owner == _current_company) this->AddItem(wp->index);
 
		if (wp->facilities & FACIL_TRAIN && wp->owner == _current_company) this->AddItem(wp->index);
 
	}
 
}
 

	
src/date.cpp
Show inline comments
 
@@ -154,7 +154,6 @@ Date ConvertYMDToDate(Year year, Month m
 

	
 
/** Functions used by the IncreaseDate function */
 

	
 
extern void WaypointsDailyLoop();
 
extern void EnginesDailyLoop();
 
extern void DisasterDailyLoop();
 
extern void IndustryDailyLoop();
 
@@ -222,7 +221,6 @@ void IncreaseDate()
 
#endif /* ENABLE_NETWORK */
 

	
 
	DisasterDailyLoop();
 
	WaypointsDailyLoop();
 
	IndustryDailyLoop();
 

	
 
	if (_game_mode != GM_MENU) {
src/elrail.cpp
Show inline comments
 
@@ -81,8 +81,6 @@ static TrackBits GetRailTrackBitsUnivers
 
			switch (GetRailTileType(t)) {
 
				case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
 
					return GetTrackBits(t);
 
				case RAIL_TILE_WAYPOINT:
 
					return GetRailWaypointBits(t);
 
				default:
 
					return TRACK_BIT_NONE;
 
			}
 
@@ -101,7 +99,7 @@ static TrackBits GetRailTrackBitsUnivers
 
			return GetCrossingRailBits(t);
 

	
 
		case MP_STATION:
 
			if (!IsRailwayStation(t)) return TRACK_BIT_NONE;
 
			if (!IsRailwayStation(t) && !IsRailWaypoint(t)) return TRACK_BIT_NONE;
 
			if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
 
			if (!IsStationTileElectrifiable(t)) return TRACK_BIT_NONE;
 
			return TrackToTrackBits(GetRailStationTrack(t));
src/lang/english.txt
Show inline comments
 
@@ -1185,8 +1185,10 @@ STR_HEADING_FOR_WAYPOINT_VEL            
 
STR_GO_TO_WAYPOINT                                              :Go via {WAYPOINT}
 
STR_GO_NON_STOP_TO_WAYPOINT                                     :Go non-stop via {WAYPOINT}
 

	
 
STR_WAYPOINTNAME_CITY                                           :Waypoint {TOWN}
 
STR_WAYPOINTNAME_CITY_SERIAL                                    :Waypoint {TOWN} #{COMMA}
 
STR_WAYPOINTNAME_CITY                                           :{TOWN} Waypoint
 
STR_WAYPOINTNAME_CITY_SERIAL                                    :{TOWN} Waypoint #{COMMA}
 
STR_BUOYNAME_CITY                                               :{TOWN} Buoy
 
STR_BUOYNAME_CITY_SERIAL                                        :{TOWN} Buoy #{COMMA}
 
STR_LANDINFO_WAYPOINT                                           :Waypoint
 

	
 
STR_WAYPOINT                                                    :{WHITE}Waypoint
 
@@ -2077,15 +2079,9 @@ STR_SV_STNAME_AIRPORT                   
 
STR_SV_STNAME_OILFIELD                                          :{STRING1} Oilfield
 
STR_SV_STNAME_MINES                                             :{STRING1} Mines
 
STR_SV_STNAME_DOCKS                                             :{STRING1} Docks
 
STR_SV_STNAME_BUOY_1                                            :{STRING1} Buoy 1
 
STR_SV_STNAME_BUOY_2                                            :{STRING1} Buoy 2
 
STR_SV_STNAME_BUOY_3                                            :{STRING1} Buoy 3
 
STR_SV_STNAME_BUOY_4                                            :{STRING1} Buoy 4
 
STR_SV_STNAME_BUOY_5                                            :{STRING1} Buoy 5
 
STR_SV_STNAME_BUOY_6                                            :{STRING1} Buoy 6
 
STR_SV_STNAME_BUOY_7                                            :{STRING1} Buoy 7
 
STR_SV_STNAME_BUOY_8                                            :{STRING1} Buoy 8
 
STR_SV_STNAME_BUOY_9                                            :{STRING1} Buoy 9
 
STR_SV_STNAME_BUOY                                              :{STRING2}
 
STR_SV_STNAME_WAYPOINT                                          :{STRING2}
 
##id 0x6020
 
STR_SV_STNAME_ANNEXE                                            :{STRING1} Annexe
 
STR_SV_STNAME_SIDINGS                                           :{STRING1} Sidings
 
STR_SV_STNAME_BRANCH                                            :{STRING1} Branch
src/misc.cpp
Show inline comments
 
@@ -31,7 +31,6 @@ extern TileIndex _cur_tileloop_tile;
 
extern void MakeNewgameSettingsLive();
 

	
 
void InitializeVehicles();
 
void InitializeWaypoints();
 
void InitializeDepots();
 
void InitializeEngineRenews();
 
void InitializeOrders();
 
@@ -79,7 +78,6 @@ void InitializeGame(uint size_x, uint si
 

	
 
	InitializeEngineRenews();
 
	InitializeVehicles();
 
	InitializeWaypoints();
 
	InitializeDepots();
 
	InitializeOrders();
 
	InitializeGroup();
src/newgrf_station.cpp
Show inline comments
 
@@ -272,30 +272,20 @@ uint32 GetPlatformInfo(Axis axis, byte t
 
 */
 
static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
 
{
 
	bool waypoint;
 
	byte orig_type = 0;
 
	Axis orig_axis = AXIS_X;
 

	
 
	waypoint = IsTileType(tile, MP_RAILWAY);
 
	StationID sid = GetStationIndex(tile);
 

	
 
	if (waypoint) {
 
		if (check_axis) orig_axis = GetWaypointAxis(tile);
 
	} else {
 
		if (check_type) orig_type = GetCustomStationSpecIndex(tile);
 
		if (check_axis) orig_axis = GetRailStationAxis(tile);
 
	}
 

	
 
	while (true) {
 
		TileIndex new_tile = TILE_ADD(tile, delta);
 

	
 
		if (waypoint) {
 
			if (!IsRailWaypointTile(new_tile)) break;
 
			if (check_axis && GetWaypointAxis(new_tile) != orig_axis) break;
 
		} else {
 
			if (!IsRailwayStationTile(new_tile)) break;
 
		if (!IsTileType(new_tile, MP_STATION) || GetStationIndex(new_tile) != sid) break;
 
		if (!IsRailwayStation(new_tile) && !IsRailWaypoint(new_tile)) break;
 
			if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
 
			if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
 
		}
 

	
 
		tile = new_tile;
 
	}
 
@@ -311,12 +301,11 @@ static uint32 GetPlatformInfoHelper(Tile
 
	int sy = TileY(FindRailStationEnd(tile, TileDiffXY( 0, -1), check_type, check_axis));
 
	int ex = TileX(FindRailStationEnd(tile, TileDiffXY( 1,  0), check_type, check_axis)) + 1;
 
	int ey = TileY(FindRailStationEnd(tile, TileDiffXY( 0,  1), check_type, check_axis)) + 1;
 
	Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
 

	
 
	tx -= sx; ex -= sx;
 
	ty -= sy; ey -= sy;
 

	
 
	return GetPlatformInfo(axis, IsTileType(tile, MP_RAILWAY) ? 2 : GetStationGfx(tile), ex, ey, tx, ty, centred);
 
	return GetPlatformInfo(GetRailStationAxis(tile), GetStationGfx(tile), ex, ey, tx, ty, centred);
 
}
 

	
 

	
 
@@ -330,7 +319,7 @@ static uint32 GetRailContinuationInfo(Ti
 
	static const Direction y_dir[8] = { DIR_SE, DIR_NW, DIR_SW, DIR_NE, DIR_S, DIR_W, DIR_E, DIR_N };
 
	static const DiagDirection y_exits[8] = { DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SE, DIAGDIR_NW };
 

	
 
	Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
 
	Axis axis = GetRailStationAxis(tile);
 

	
 
	/* Choose appropriate lookup table to use */
 
	const Direction *dir = axis == AXIS_X ? x_dir : y_dir;
 
@@ -450,12 +439,7 @@ static uint32 StationGetVariable(const R
 

	
 
		case 0x42: return GetTerrainType(tile) | (GetRailType(tile) << 8);
 
		case 0x43: return st->owner; // Station owner
 
		case 0x44:
 
			if (IsRailWaypointTile(tile)) {
 
				return HasDepotReservation(tile) ? 7 : 4;
 
			} else {
 
				return HasStationReservation(tile) ? 7 : 4; // PBS status
 
			}
 
		case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status
 
		case 0x45:
 
			if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(tile); SetBit(_svc.valid, 2); }
 
			return _svc.v45;
 
@@ -583,7 +567,7 @@ uint32 Waypoint::GetNewGRFVariable(const
 
{
 
	switch (variable) {
 
		case 0x48: return 0; // Accepted cargo types
 
		case 0x8A: return HVOT_TRAIN;
 
		case 0x8A: return HVOT_WAYPOINT;
 
		case 0xF1: return 0; // airport type
 
		case 0xF2: return 0; // truck stop status
 
		case 0xF3: return 0; // bus stop status
 
@@ -944,7 +928,6 @@ bool DrawStationTile(int x, int y, RailT
 

	
 
const StationSpec *GetStationSpec(TileIndex t)
 
{
 
	if (IsRailwayStationTile(t)) {
 
		if (!IsCustomStationSpecIndex(t)) return NULL;
 

	
 
		const BaseStation *st = BaseStation::GetByTile(t);
 
@@ -952,14 +935,6 @@ const StationSpec *GetStationSpec(TileIn
 
		return specindex < st->num_specs ? st->speclist[specindex].spec : NULL;
 
	}
 

	
 
	if (IsRailWaypointTile(t)) {
 
		const BaseStation *st = BaseStation::GetByTile(t);
 
		return st->num_specs != 0 ? st->speclist[1].spec : NULL;
 
	}
 

	
 
	return NULL;
 
}
 

	
 

	
 
/* Check if a rail station tile is traversable.
 
 * XXX This could be cached (during build) in the map array to save on all the dereferencing */
src/order_cmd.cpp
Show inline comments
 
@@ -542,18 +542,19 @@ CommandCost CmdInsertOrder(TileIndex til
 
		}
 

	
 
		case OT_GOTO_WAYPOINT: {
 
			const Waypoint *wp = Waypoint::GetIfValid(new_order.GetDestination());
 
			if (wp == NULL) return CMD_ERROR;
 

	
 
			switch (v->type) {
 
				default: return CMD_ERROR;
 

	
 
				case VEH_TRAIN: {
 
					const Waypoint *wp = Waypoint::GetIfValid(new_order.GetDestination());
 
					if (wp == NULL || !CheckOwnership(wp->owner)) return CMD_ERROR;
 
				} break;
 
				case VEH_TRAIN:
 
					if (!CheckOwnership(wp->owner)) return CMD_ERROR;
 
					break;
 

	
 
				case VEH_SHIP: {
 
					const Station *st = Station::GetIfValid(new_order.GetDestination());
 
					if (st == NULL || (!CheckOwnership(st->owner) && st->owner != OWNER_NONE)) return CMD_ERROR;
 
				} break;
 
				case VEH_SHIP:
 
					if (!CheckOwnership(wp->owner) && wp->owner != OWNER_NONE) return CMD_ERROR;
 
					break;
 
			}
 

	
 
			/* Order flags can be any of the following for waypoints:
src/order_gui.cpp
Show inline comments
 
@@ -253,15 +253,8 @@ void DrawOrderString(const Vehicle *v, c
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
 
			if (v->type == VEH_TRAIN) {
 
				SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
 
				SetDParam(2, order->GetDestination());
 
			} else {
 
				SetDParam(1, STR_GO_TO_STATION);
 
				SetDParam(2, STR_ORDER_GO_VIA);
 
				SetDParam(3, order->GetDestination());
 
				SetDParam(4, STR_EMPTY);
 
			}
 
			break;
 

	
 
		case OT_CONDITIONAL:
 
@@ -357,7 +350,7 @@ static Order GetOrderCmdFromTile(const V
 
		return order;
 
	}
 

	
 
	if (IsBuoyTile(tile) && v->type == VEH_SHIP) {
 
	if ((IsBuoyTile(tile) && v->type == VEH_SHIP) || (IsRailWaypointTile(tile) && v->type == VEH_TRAIN)) {
 
		order.MakeGoToWaypoint(GetStationIndex(tile));
 
		return order;
 
	}
 
@@ -775,12 +768,9 @@ public:
 
			this->SetWidgetLoweredState(ORDER_WIDGET_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 
			switch (order->GetType()) {
 
				case OT_GOTO_STATION:
 
					if (!Station::Get(order->GetDestination())->IsBuoy()) {
 
						this->SetWidgetLoweredState(ORDER_WIDGET_FULL_LOAD, order->GetLoadType() == OLF_FULL_LOAD_ANY);
 
						this->SetWidgetLoweredState(ORDER_WIDGET_UNLOAD, order->GetUnloadType() == OUFB_UNLOAD);
 
						break;
 
					}
 
					/* Fall-through */
 

	
 
				case OT_GOTO_WAYPOINT:
 
					this->DisableWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
src/pbs.cpp
Show inline comments
 
@@ -26,7 +26,7 @@ TrackBits GetReservedTrackbits(TileIndex
 
			break;
 

	
 
		case MP_STATION:
 
			if (IsRailwayStation(t)) return GetStationReservationTrackBits(t);
 
			if (IsRailwayStation(t) || IsRailWaypoint(t)) return GetStationReservationTrackBits(t);
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
@@ -99,7 +99,7 @@ bool TryReserveRailTrack(TileIndex tile,
 
			break;
 

	
 
		case MP_STATION:
 
			if (IsRailwayStation(tile) && !HasStationReservation(tile)) {
 
			if ((IsRailwayStation(tile) || IsRailWaypoint(tile)) && !HasStationReservation(tile)) {
 
				SetRailwayStationReservation(tile, true);
 
				MarkTileDirtyByTile(tile); // some GRFs need redraw after reserving track
 
				return true;
 
@@ -150,7 +150,7 @@ bool TryReserveRailTrack(TileIndex tile,
 
			break;
 

	
 
		case MP_STATION:
 
			if (IsRailwayStation(tile)) {
 
			if (IsRailwayStation(tile) || IsRailWaypoint(tile)) {
 
				SetRailwayStationReservation(tile, false);
 
				MarkTileDirtyByTile(tile);
 
			}
src/rail.cpp
Show inline comments
 
@@ -155,7 +155,7 @@ RailType GetTileRailType(TileIndex tile)
 
			break;
 

	
 
		case MP_STATION:
 
			if (IsRailwayStationTile(tile)) return GetRailType(tile);
 
			if (IsRailwayStation(tile) || IsRailWaypoint(tile)) return GetRailType(tile);
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
src/rail_cmd.cpp
Show inline comments
 
@@ -1281,7 +1281,7 @@ CommandCost CmdConvertRail(TileIndex til
 
				case MP_RAILWAY:
 
					break;
 
				case MP_STATION:
 
					if (!IsRailwayStation(tile)) continue;
 
					if (!IsRailwayStation(tile) && !IsRailWaypoint(tile)) continue;
 
					break;
 
				case MP_ROAD:
 
					if (!IsLevelCrossing(tile)) continue;
 
@@ -1329,14 +1329,6 @@ CommandCost CmdConvertRail(TileIndex til
 
			switch (tt) {
 
				case MP_RAILWAY:
 
					switch (GetRailTileType(tile)) {
 
						case RAIL_TILE_WAYPOINT:
 
							if (flags & DC_EXEC) {
 
								/* notify YAPF about the track layout change */
 
								YapfNotifyTrackLayoutChange(tile, GetRailWaypointTrack(tile));
 
							}
 
							cost.AddCost(RailConvertCost(type, totype));
 
							break;
 

	
 
						case RAIL_TILE_DEPOT:
 
							if (flags & DC_EXEC) {
 
								/* notify YAPF about the track layout change */
 
@@ -1501,9 +1493,6 @@ static CommandCost ClearTile_Track(TileI
 
		case RAIL_TILE_DEPOT:
 
			return RemoveTrainDepot(tile, flags);
 

	
 
		case RAIL_TILE_WAYPOINT:
 
			return RemoveTrainWaypoint(tile, flags, false);
 

	
 
		default:
 
			return CMD_ERROR;
 
	}
 
@@ -1906,7 +1895,7 @@ static void DrawTile_Track(TileInfo *ti)
 

	
 
		if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
 
	} else {
 
		/* draw depot/waypoint */
 
		/* draw depot */
 
		const DrawTileSprites *dts;
 
		const DrawTileSeqStruct *dtss;
 
		uint32 relocation;
 
@@ -1914,7 +1903,6 @@ static void DrawTile_Track(TileInfo *ti)
 

	
 
		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 

	
 
		if (IsRailDepot(ti->tile)) {
 
			if (IsInvisibilitySet(TO_BUILDINGS)) {
 
				/* Draw rail instead of depot */
 
				dts = &_depot_invisible_gfx_table[GetRailDepotDirection(ti->tile)];
 
@@ -1936,56 +1924,16 @@ static void DrawTile_Track(TileInfo *ti)
 
					image = SPR_FLAT_SNOWY_TILE; // flat ground
 
				}
 
			}
 
		} else {
 
			/* look for customization */
 
			const StationSpec *statspec = GetStationSpec(ti->tile);
 

	
 
			if (statspec != NULL) {
 
				const BaseStation *st = BaseStation::GetByTile(ti->tile);
 
				uint gfx = 2;
 

	
 
				if (HasBit(statspec->callbackmask, CBM_STATION_SPRITE_LAYOUT)) {
 
					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
 
					if (callback != CALLBACK_FAILED) gfx = callback;
 
				}
 

	
 
				if (statspec->renderdata == NULL) {
 
					dts = GetStationTileLayout(STATION_RAIL, gfx);
 
				} else {
 
					dts = &statspec->renderdata[(gfx < statspec->tiles ? gfx : 0) + GetWaypointAxis(ti->tile)];
 
				}
 

	
 
				if (dts != NULL && dts->seq != NULL) {
 
					relocation = GetCustomStationRelocation(statspec, st, ti->tile);
 

	
 
					image = dts->ground.sprite;
 
					if (HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) {
 
						image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 
						image += rti->custom_ground_offset;
 
					} else {
 
						image += rti->total_offset;
 
					}
 

	
 
					pal = dts->ground.pal;
 
				} else {
 
					goto default_waypoint;
 
				}
 
			} else {
 
default_waypoint:
 
				/* There is no custom layout, fall back to the default graphics */
 
				dts = GetStationTileLayout(STATION_WAYPOINT, GetWaypointAxis(ti->tile));
 
				relocation = 0;
 
				image = dts->ground.sprite + rti->total_offset;
 
				if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
 
			}
 
		}
 

	
 
		DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, _drawtile_track_palette));
 

	
 
		/* PBS debugging, draw reserved tracks darker */
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile) &&
 
				(!IsRailDepot(ti->tile) || GetRailDepotDirection(ti->tile) == DIAGDIR_SW || GetRailDepotDirection(ti->tile) == DIAGDIR_SE)) {
 
			DrawGroundSprite(GetWaypointAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_y : rti->base_sprites.single_x, PALETTE_CRASH);
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
 
			switch (GetRailDepotDirection(ti->tile)) {
 
				case DIAGDIR_SW: DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); break;
 
				case DIAGDIR_SE: DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); break;
 
				default: break;
 
			}
 
		}
 

	
 
		if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
 
@@ -2292,10 +2240,6 @@ static TrackStatus GetTileTrackStatus_Tr
 
			trackbits = DiagDirToDiagTrackBits(dir);
 
			break;
 
		}
 

	
 
		case RAIL_TILE_WAYPOINT:
 
			trackbits = GetRailWaypointBits(tile);
 
			break;
 
	}
 

	
 
	return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), red_signals);
 
@@ -2303,11 +2247,10 @@ static TrackStatus GetTileTrackStatus_Tr
 

	
 
static bool ClickTile_Track(TileIndex tile)
 
{
 
	switch (GetRailTileType(tile)) {
 
		case RAIL_TILE_DEPOT:    ShowDepotWindow(tile, VEH_TRAIN);              return true;
 
		case RAIL_TILE_WAYPOINT: ShowWaypointWindow(Waypoint::GetByTile(tile)); return true;
 
		default: return false;
 
	}
 
	if (!IsRailDepot(tile)) return false;
 

	
 
	ShowDepotWindow(tile, VEH_TRAIN);
 
	return true;
 
}
 

	
 
static void GetTileDesc_Track(TileIndex tile, TileDesc *td)
 
@@ -2387,10 +2330,8 @@ static void GetTileDesc_Track(TileIndex 
 
			td->str = STR_RAILROAD_TRAIN_DEPOT;
 
			break;
 

	
 
		case RAIL_TILE_WAYPOINT:
 
		default:
 
			td->str = STR_LANDINFO_WAYPOINT;
 
			break;
 
			NOT_REACHED();
 
	}
 
}
 

	
 
@@ -2579,22 +2520,9 @@ static CommandCost TerraformTile_Track(T
 

	
 
		/* allow terraforming */
 
		return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price.clear_water : (Money)0);
 
	} else {
 
		if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
 
			switch (GetRailTileType(tile)) {
 
				case RAIL_TILE_WAYPOINT: {
 
					CommandCost cost = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, GetRailWaypointBits(tile));
 
					if (!CmdFailed(cost)) return cost; // allow autoslope
 
					break;
 
				}
 

	
 
				case RAIL_TILE_DEPOT:
 
					if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 
					break;
 

	
 
				default: NOT_REACHED();
 
			}
 
		}
 
	} else if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() &&
 
			AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) {
 
		return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 
	}
 
	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
}
src/rail_map.h
Show inline comments
 
@@ -18,7 +18,6 @@
 
enum RailTileType {
 
	RAIL_TILE_NORMAL   = 0, ///< Normal rail tile without signals
 
	RAIL_TILE_SIGNALS  = 1, ///< Normal rail tile with signals
 
	RAIL_TILE_WAYPOINT = 2, ///< Waypoint (X or Y direction)
 
	RAIL_TILE_DEPOT    = 3, ///< Depot (one entrance)
 
};
 

	
 
@@ -83,27 +82,6 @@ static inline void SetHasSignals(TileInd
 
}
 

	
 
/**
 
 * Is this rail tile a rail waypoint?
 
 * @param t the tile to get the information from
 
 * @pre IsTileType(t, MP_RAILWAY)
 
 * @return true if and only if the tile is a rail waypoint
 
 */
 
static inline bool IsRailWaypoint(TileIndex t)
 
{
 
	return GetRailTileType(t) == RAIL_TILE_WAYPOINT;
 
}
 

	
 
/**
 
 * Is this tile rail tile and a rail waypoint?
 
 * @param t the tile to get the information from
 
 * @return true if and only if the tile is a rail waypoint
 
 */
 
static inline bool IsRailWaypointTile(TileIndex t)
 
{
 
	return IsTileType(t, MP_RAILWAY) && IsRailWaypoint(t);
 
}
 

	
 
/**
 
 * Is this rail tile a rail depot?
 
 * @param t the tile to get the information from
 
 * @pre IsTileType(t, MP_RAILWAY)
 
@@ -203,51 +181,6 @@ static inline Track GetRailDepotTrack(Ti
 

	
 

	
 
/**
 
 * Returns the axis of the waypoint
 
 * @param t the tile to get the waypoint axis from
 
 * @pre IsRailWaypointTile(t)
 
 * @return the axis of the waypoint
 
 */
 
static inline Axis GetWaypointAxis(TileIndex t)
 
{
 
	return (Axis)GB(_m[t].m5, 0, 1);
 
}
 

	
 
/**
 
 * Returns the track of the waypoint
 
 * @param t the tile to get the waypoint track from
 
 * @pre IsRailWaypointTile(t)
 
 * @return the track of the waypoint
 
 */
 
static inline Track GetRailWaypointTrack(TileIndex t)
 
{
 
	return AxisToTrack(GetWaypointAxis(t));
 
}
 

	
 
/**
 
 * Returns the track bits of the waypoint
 
 * @param t the tile to get the waypoint track bits from
 
 * @pre IsRailWaypointTile(t)
 
 * @return the track bits of the waypoint
 
 */
 
static inline TrackBits GetRailWaypointBits(TileIndex t)
 
{
 
	return TrackToTrackBits(GetRailWaypointTrack(t));
 
}
 

	
 
/**
 
 * Returns waypoint index (for the waypoint pool)
 
 * @param t the tile to get the waypoint index from
 
 * @pre IsRailWaypointTile(t)
 
 * @return the waypoint index
 
 */
 
static inline WaypointID GetWaypointIndex(TileIndex t)
 
{
 
	return (WaypointID)_m[t].m2;
 
}
 

	
 

	
 
/**
 
 * Returns the reserved track bits of the tile
 
 * @pre IsPlainRailTile(t)
 
 * @param t the tile to query
 
@@ -336,17 +269,6 @@ static inline void SetDepotReservation(T
 
}
 

	
 
/**
 
 * Get the reserved track bits for a waypoint
 
 * @pre IsRailWaypoint(t)
 
 * @param t the tile
 
 * @return reserved track bits
 
 */
 
static inline TrackBits GetWaypointReservationTrackBits(TileIndex t)
 
{
 
	return HasDepotReservation(t) ? GetRailWaypointBits(t) : TRACK_BIT_NONE;
 
}
 

	
 
/**
 
 * Get the reserved track bits for a depot
 
 * @pre IsRailDepot(t)
 
 * @param t the tile
 
@@ -635,17 +557,4 @@ static inline void MakeRailDepot(TileInd
 
	_me[t].m7 = 0;
 
}
 

	
 

	
 
static inline void MakeRailWaypoint(TileIndex t, Owner o, Axis a, RailType r, uint index)
 
{
 
	SetTileType(t, MP_RAILWAY);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = index;
 
	_m[t].m3 = r;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = RAIL_TILE_WAYPOINT << 6 | a;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
 
}
 

	
 
#endif /* RAIL_MAP_H */
src/saveload/afterload.cpp
Show inline comments
 
@@ -606,9 +606,7 @@ bool AfterLoadGame()
 
		switch (GetTileType(t)) {
 
			case MP_STATION: {
 
				Station *st = Station::GetByTile(t);
 

	
 
				/* Set up station spread; buoys do not have one */
 
				if (!IsBuoy(t)) st->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
 
				if (st == NULL) break;
 

	
 
				switch (GetStationType(t)) {
 
					case STATION_TRUCK:
 
@@ -987,29 +985,11 @@ bool AfterLoadGame()
 
		FOR_ALL_COMPANIES(c) c->settings.renew_keep_length = false;
 
	}
 

	
 
	/* 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 (CheckSavegameVersion(17)) {
 
		Waypoint *wp;
 

	
 
		FOR_ALL_WAYPOINTS(wp) {
 
			if (wp->delete_ctr == 0) {
 
				if (HasBit(_m[wp->xy].m3, 4)) {
 
					AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1), wp, true);
 
				}
 

	
 
				/* Move ground type bits from m2 to m4. */
 
				_m[wp->xy].m4 = GB(_m[wp->xy].m2, 0, 4);
 
				/* Store waypoint index in the tile. */
 
				_m[wp->xy].m2 = wp->index;
 
			}
 
		}
 
	} else {
 
		/* As of version 17, we recalculate the custom graphic ID of waypoints
 
		 * from the GRF ID / station index. */
 
		AfterLoadWaypoints();
 
	if (CheckSavegameVersion(123)) {
 
		/* Waypoints became subclasses of stations ... */
 
		MoveWaypointsToBaseStations();
 
		/* ... and buoys were moved to waypoints. */
 
		MoveBuoysToWaypoints();
 
	}
 

	
 
	/* From version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making
 
@@ -1275,9 +1255,9 @@ bool AfterLoadGame()
 
	/* Buoys do now store the owner of the previous water tile, which can never
 
	 * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
 
	if (CheckSavegameVersion(46)) {
 
		Station *st;
 
		FOR_ALL_STATIONS(st) {
 
			if (st->IsBuoy() && IsTileOwner(st->xy, OWNER_NONE) && TileHeight(st->xy) == 0) SetTileOwner(st->xy, OWNER_WATER);
 
		Waypoint *wp;
 
		FOR_ALL_WAYPOINTS(wp) {
 
			if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER);
 
		}
 
	}
 

	
 
@@ -1487,15 +1467,6 @@ bool AfterLoadGame()
 
	}
 

	
 
	if (CheckSavegameVersion(84)) {
 
		/* Update go to buoy orders because they are just waypoints */
 
		Order *order;
 
		FOR_ALL_ORDERS(order) {
 
			if (order->IsType(OT_GOTO_STATION) && Station::Get(order->GetDestination())->IsBuoy()) {
 
				order->SetLoadType(OLF_LOAD_IF_POSSIBLE);
 
				order->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
 
			}
 
		}
 

	
 
		/* Set all share owners to INVALID_COMPANY for
 
		 * 1) all inactive companies
 
		 *     (when inactive companies were stored in the savegame - TTD, TTDP and some
 
@@ -1561,7 +1532,7 @@ bool AfterLoadGame()
 
				if (IsBuoyTile(t)) {
 
					/* reset buoy owner to OWNER_NONE in the station struct
 
					 * (even if it is owned by active company) */
 
					Station::GetByTile(t)->owner = OWNER_NONE;
 
					Waypoint::GetByTile(t)->owner = OWNER_NONE;
 
				}
 
			} else if (IsTileType(t, MP_ROAD)) {
 
				/* works for all RoadTileType */
 
@@ -1805,16 +1776,6 @@ bool AfterLoadGame()
 
		FOR_ALL_STATIONS(st) {
 
			if (!Company::IsValidID(st->owner)) st->owner = OWNER_NONE;
 
		}
 

	
 
		/* Give owners to waypoints, based on rail tracks it is sitting on.
 
		 * If none is available, specify OWNER_NONE.
 
		 * This code was in CheckSavegameVersion(101) in the past, but in some cases,
 
		 * the owner of waypoints could be incorrect. */
 
		Waypoint *wp;
 
		FOR_ALL_WAYPOINTS(wp) {
 
			Owner owner = IsTileType(wp->xy, MP_RAILWAY) ? GetTileOwner(wp->xy) : OWNER_NONE;
 
			wp->owner = Company::IsValidID(owner) ? owner : OWNER_NONE;
 
		}
 
	}
 

	
 
	/* Trains could now stop in a specific location. */
 
@@ -1913,14 +1874,6 @@ bool AfterLoadGame()
 
			}
 
			s->cargo_type = CT_INVALID;
 
		}
 

	
 
		Order *o;
 
		FOR_ALL_ORDERS(o) {
 
			/* Buoys are now go to waypoint orders */
 
			if (!o->IsType(OT_GOTO_STATION) || !Station::Get(o->GetDestination())->IsBuoy()) continue;
 

	
 
			o->MakeGoToWaypoint(o->GetDestination());
 
		}
 
	}
 

	
 
	AfterLoadLabelMaps();
 
@@ -1950,8 +1903,7 @@ void ReloadNewGRFData()
 
	AfterLoadVehicles(false);
 
	StartupEngines();
 
	SetCachedEngineCounts();
 
	/* update station and waypoint graphics */
 
	AfterLoadWaypoints();
 
	/* update station graphics */
 
	AfterLoadStations();
 
	/* Check and update house and town values */
 
	UpdateHousesAndTowns();
src/saveload/saveload.cpp
Show inline comments
 
@@ -41,7 +41,7 @@
 

	
 
#include "saveload_internal.h"
 

	
 
extern const uint16 SAVEGAME_VERSION = 122;
 
extern const uint16 SAVEGAME_VERSION = 123;
 

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

	
 
@@ -873,6 +873,7 @@ size_t SlCalcObjMemberLength(const void 
 
			break;
 
		case SL_WRITEBYTE: return 1; // a byte is logically of size 1
 
		case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
 
		case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
 
		default: NOT_REACHED();
 
	}
 
	return 0;
 
@@ -934,6 +935,10 @@ bool SlObjectMember(void *ptr, const Sav
 
			SlObject(ptr, GetVehicleDescription(VEH_END));
 
			break;
 

	
 
		case SL_ST_INCLUDE:
 
			SlObject(ptr, GetBaseStationDescription());
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 
	return true;
src/saveload/saveload.h
Show inline comments
 
@@ -182,6 +182,7 @@ enum SaveLoadTypes {
 
	/* non-normal save-load types */
 
	SL_WRITEBYTE   =  8,
 
	SL_VEH_INCLUDE =  9,
 
	SL_ST_INCLUDE  = 10,
 
	SL_END         = 15
 
};
 

	
 
@@ -235,6 +236,7 @@ typedef SaveLoad SaveLoadGlobVarList;
 

	
 
#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, 0, something, 0)
 
#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION)
 
#define SLE_ST_INCLUDEX() SLE_GENERALX(SL_ST_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION)
 

	
 
/* End marker */
 
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
src/saveload/saveload_internal.h
Show inline comments
 
@@ -16,7 +16,10 @@ StringID RemapOldStringID(StringID s);
 
char *CopyFromOldName(StringID id);
 
void ResetOldNames();
 

	
 
void AfterLoadWaypoints();
 
void MoveBuoysToWaypoints();
 
void MoveWaypointsToBaseStations();
 
const SaveLoad *GetBaseStationDescription();
 

	
 
void AfterLoadVehicles(bool part_of_load);
 
void AfterLoadStations();
 
void AfterLoadLabelMaps();
src/saveload/station_sl.cpp
Show inline comments
 
@@ -4,27 +4,98 @@
 

	
 
#include "../stdafx.h"
 
#include "../station_base.h"
 
#include "../waypoint.h"
 
#include "../roadstop_base.h"
 
#include "../order_base.h"
 
#include "../vehicle_base.h"
 
#include "../core/bitmath_func.hpp"
 
#include "../core/alloc_func.hpp"
 
#include "../variables.h"
 
#include "../newgrf_station.h"
 

	
 
#include "saveload.h"
 
#include "table/strings.h"
 

	
 
/**
 
 * Update the buoy orders to be waypoint orders.
 
 * @param o the order 'list' to check.
 
 */
 
static void UpdateWaypointOrder(Order *o)
 
{
 
	if (!o->IsType(OT_GOTO_STATION)) return;
 

	
 
	const Station *st = Station::Get(o->GetDestination());
 
	if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) return;
 

	
 
	o->MakeGoToWaypoint(o->GetDestination());
 
}
 

	
 
/**
 
 * Perform all steps to upgrade from the old station buoys to the new version
 
 * that uses waypoints. This includes some old saveload mechanics.
 
 */
 
void MoveBuoysToWaypoints()
 
{
 
	/* Buoy orders become waypoint orders */
 
	OrderList *ol;
 
	FOR_ALL_ORDER_LISTS(ol) {
 
		if (ol->GetFirstSharedVehicle()->type != VEH_SHIP) continue;
 

	
 
		for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o);
 
	}
 

	
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type != VEH_SHIP) continue;
 

	
 
		UpdateWaypointOrder(&v->current_order);
 
	}
 

	
 
	/* Now make the stations waypoints */
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) continue;
 

	
 
		StationID index    = st->index;
 
		TileIndex xy       = st->xy;
 
		Town *town         = st->town;
 
		StringID string_id = st->string_id;
 
		char *name         = st->name;
 
		Date build_date    = st->build_date;
 

	
 
		/* Delete the station, so we can make it a real waypoint. */
 
		delete st;
 

	
 
		Waypoint *wp = new (index) Waypoint(xy);
 
		wp->town       = town;
 
		wp->string_id  = STR_SV_STNAME_BUOY;
 
		wp->name       = name;
 
		wp->delete_ctr = 0; // Just reset delete counter for once.
 
		wp->build_date = build_date;
 
		wp->owner      = OWNER_NONE;
 

	
 
		if (IsInsideBS(string_id, STR_SV_STNAME_BUOY, 9)) wp->town_cn = string_id - STR_SV_STNAME_BUOY;
 

	
 
		if (IsBuoyTile(xy) && GetStationIndex(xy) == index) {
 
			wp->facilities |= FACIL_DOCK;
 
		}
 
	}
 
}
 

	
 
void AfterLoadStations()
 
{
 
	/* Update the speclists of all stations to point to the currently loaded custom stations. */
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
	BaseStation *st;
 
	FOR_ALL_BASE_STATIONS(st) {
 
		for (uint i = 0; i < st->num_specs; i++) {
 
			if (st->speclist[i].grfid == 0) continue;
 

	
 
			st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx, NULL);
 
		}
 

	
 
		for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
 
		if (Station::IsExpected(st)) {
 
			for (CargoID c = 0; c < NUM_CARGO; c++) Station::From(st)->goods[c].cargo.InvalidateCache();
 
		}
 

	
 
		StationUpdateAnimTriggers(st);
 
	}
 
@@ -48,7 +119,7 @@ static const SaveLoad _roadstop_desc[] =
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _station_desc[] = {
 
static const SaveLoad _old_station_desc[] = {
 
	SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
 
	SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
 
	SLE_CONDNULL(4, 0, 5),  ///< bus/lorry tile
 
@@ -145,9 +216,13 @@ const SaveLoad *GetGoodsDesc()
 
}
 

	
 

	
 
static void SaveLoad_STNS(Station *st)
 
static void Load_STNS()
 
{
 
	SlObject(st, _station_desc);
 
	int index;
 
	while ((index = SlIterateArray()) != -1) {
 
		Station *st = new (index) Station();
 

	
 
		SlObject(st, _old_station_desc);
 

	
 
	_waiting_acceptance = 0;
 

	
 
@@ -176,35 +251,19 @@ static void SaveLoad_STNS(Station *st)
 

	
 
	if (st->num_specs != 0) {
 
		/* Allocate speclist memory when loading a game */
 
		if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
 
			st->speclist = CallocT<StationSpecList>(st->num_specs);
 
		for (uint i = 0; i < st->num_specs; i++) {
 
			SlObject(&st->speclist[i], _station_speclist_desc);
 
		}
 
	}
 
}
 

	
 
static void Save_STNS()
 
{
 
	Station *st;
 
	/* Write the stations */
 
	FOR_ALL_STATIONS(st) {
 
		SlSetArrayIndex(st->index);
 
		SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
 
	}
 
}
 

	
 
static void Load_STNS()
 
{
 
	int index;
 
	while ((index = SlIterateArray()) != -1) {
 
		Station *st = new (index) Station();
 

	
 
		SaveLoad_STNS(st);
 
	}
 
}
 

	
 
void Ptrs_STNS()
 
{
 
	/* Don't run when savegame version is higher than or equal to 123. */
 
	if (!CheckSavegameVersion(123)) return;
 

	
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		if (!CheckSavegameVersion(68)) {
 
@@ -213,11 +272,147 @@ void Ptrs_STNS()
 
				SlObject(ge, GetGoodsDesc());
 
			}
 
		}
 
		SlObject(st, _station_desc);
 
		SlObject(st, _old_station_desc);
 
	}
 
}
 

	
 

	
 
static const SaveLoad _base_station_desc[] = {
 
	      SLE_VAR(BaseStation, xy,                     SLE_UINT32),
 
	      SLE_REF(BaseStation, town,                   REF_TOWN),
 
	      SLE_VAR(BaseStation, string_id,              SLE_STRINGID),
 
	      SLE_STR(BaseStation, name,                   SLE_STR, 0),
 
	      SLE_VAR(BaseStation, delete_ctr,             SLE_UINT8),
 
	      SLE_VAR(BaseStation, owner,                  SLE_UINT8),
 
	      SLE_VAR(BaseStation, facilities,             SLE_UINT8),
 
	      SLE_VAR(BaseStation, build_date,             SLE_INT32),
 

	
 
	/* Used by newstations for graphic variations */
 
	      SLE_VAR(BaseStation, random_bits,            SLE_UINT16),
 
	      SLE_VAR(BaseStation, waiting_triggers,       SLE_UINT8),
 
	      SLE_VAR(BaseStation, num_specs,              SLE_UINT8),
 

	
 
	      SLE_END()
 
};
 

	
 
static const SaveLoad _station_desc[] = {
 
	SLE_WRITEBYTE(Station, facilities,                 FACIL_NONE),
 
	SLE_ST_INCLUDEX(),
 

	
 
	      SLE_VAR(Station, train_tile,                 SLE_UINT32),
 
	      SLE_VAR(Station, trainst_w,                  SLE_UINT8),
 
	      SLE_VAR(Station, trainst_h,                  SLE_UINT8),
 

	
 
	      SLE_REF(Station, bus_stops,                  REF_ROADSTOPS),
 
	      SLE_REF(Station, truck_stops,                REF_ROADSTOPS),
 
	      SLE_VAR(Station, dock_tile,                  SLE_UINT32),
 
	      SLE_VAR(Station, airport_tile,               SLE_UINT32),
 
	      SLE_VAR(Station, airport_type,               SLE_UINT8),
 
	      SLE_VAR(Station, airport_flags,              SLE_UINT64),
 

	
 
	      SLE_VAR(Station, indtype,                    SLE_UINT8),
 

	
 
	      SLE_VAR(Station, time_since_load,            SLE_UINT8),
 
	      SLE_VAR(Station, time_since_unload,          SLE_UINT8),
 
	      SLE_VAR(Station, last_vehicle_type,          SLE_UINT8),
 
	      SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT8),
 
	      SLE_LST(Station, loading_vehicles,           REF_VEHICLE),
 

	
 
	      SLE_END()
 
};
 

	
 
static const SaveLoad _waypoint_desc[] = {
 
	SLE_WRITEBYTE(Waypoint, facilities,                FACIL_WAYPOINT),
 
	SLE_ST_INCLUDEX(),
 

	
 
	      SLE_VAR(Waypoint, town_cn,                   SLE_UINT16),
 

	
 
	      SLE_END()
 
};
 

	
 
/**
 
 * Get the base station description to be used for SL_ST_INCLUDE
 
 * @return the base station description.
 
 */
 
const SaveLoad *GetBaseStationDescription()
 
{
 
	return _base_station_desc;
 
}
 

	
 
static void RealSave_STNN(BaseStation *bst)
 
{
 
	bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0;
 
	SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
 

	
 
	if (!waypoint) {
 
		Station *st = Station::From(bst);
 
		for (CargoID i = 0; i < NUM_CARGO; i++) {
 
			SlObject(&st->goods[i], GetGoodsDesc());
 
		}
 
	}
 

	
 
	for (uint i = 0; i < bst->num_specs; i++) {
 
		SlObject(&bst->speclist[i], _station_speclist_desc);
 
	}
 
}
 

	
 
static void Save_STNN()
 
{
 
	BaseStation *st;
 
	/* Write the stations */
 
	FOR_ALL_BASE_STATIONS(st) {
 
		SlSetArrayIndex(st->index);
 
		SlAutolength((AutolengthProc*)RealSave_STNN, st);
 
	}
 
}
 

	
 
static void Load_STNN()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
 

	
 
		BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
 
		SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
 

	
 
		if (!waypoint) {
 
			Station *st = Station::From(bst);
 
			for (CargoID i = 0; i < NUM_CARGO; i++) {
 
				SlObject(&st->goods[i], GetGoodsDesc());
 
			}
 
		}
 

	
 
		if (bst->num_specs != 0) {
 
			/* Allocate speclist memory when loading a game */
 
			bst->speclist = CallocT<StationSpecList>(bst->num_specs);
 
			for (uint i = 0; i < bst->num_specs; i++) {
 
				SlObject(&bst->speclist[i], _station_speclist_desc);
 
			}
 
		}
 
	}
 
}
 

	
 
static void Ptrs_STNN()
 
{
 
	/* Don't run when savegame version lower than 123. */
 
	if (CheckSavegameVersion(123)) return;
 

	
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		for (CargoID i = 0; i < NUM_CARGO; i++) {
 
			GoodsEntry *ge = &st->goods[i];
 
			SlObject(ge, GetGoodsDesc());
 
		}
 
		SlObject(st, _station_desc);
 
	}
 

	
 
	Waypoint *wp;
 
	FOR_ALL_WAYPOINTS(wp) {
 
		SlObject(wp, _waypoint_desc);
 
	}
 
}
 

	
 
static void Save_ROADSTOP()
 
{
 
	RoadStop *rs;
 
@@ -248,6 +443,7 @@ static void Ptrs_ROADSTOP()
 
}
 

	
 
extern const ChunkHandler _station_chunk_handlers[] = {
 
	{ 'STNS', Save_STNS,     Load_STNS,     Ptrs_STNS,     CH_ARRAY },
 
	{ 'STNS', NULL,          Load_STNS,     Ptrs_STNS,     CH_ARRAY },
 
	{ 'STNN', Save_STNN,     Load_STNN,     Ptrs_STNN,     CH_ARRAY },
 
	{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, CH_ARRAY | CH_LAST},
 
};
src/saveload/waypoint_sl.cpp
Show inline comments
 
@@ -5,120 +5,187 @@
 
#include "../stdafx.h"
 
#include "../waypoint.h"
 
#include "../newgrf_station.h"
 
#include "../vehicle_base.h"
 
#include "../town.h"
 
#include "../station_map.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "saveload.h"
 
#include "saveload_internal.h"
 

	
 
/** Helper structure to convert from the old waypoint system. */
 
struct OldWaypoint {
 
	size_t index;
 
	TileIndex xy;
 
	TownID town_index;
 
	Town *town;
 
	uint16 town_cn;
 
	StringID string_id;
 
	char *name;
 
	uint8 delete_ctr;
 
	Date build_date;
 
	uint8 localidx;
 
	uint32 grfid;
 
	const StationSpec *spec;
 
	OwnerByte owner;
 

	
 
	size_t new_index;
 
};
 

	
 
/** Temporary array with old waypoints. */
 
static SmallVector<OldWaypoint, 16> _old_waypoints;
 

	
 
/**
 
 * Update waypoint graphics id against saved GRFID/localidx.
 
 * This is to ensure the chosen graphics are correct if GRF files are changed.
 
 * Update the waypoint orders to get the new waypoint ID.
 
 * @param o the order 'list' to check.
 
 */
 
void AfterLoadWaypoints()
 
static void UpdateWaypointOrder(Order *o)
 
{
 
	Waypoint *wp;
 
	if (!o->IsType(OT_GOTO_WAYPOINT)) return;
 

	
 
	for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
 
		if (wp->index != o->GetDestination()) continue;
 

	
 
		o->SetDestination(wp->new_index);
 
		return;
 
	}
 
}
 

	
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->num_specs == 0) continue;
 

	
 
/**
 
 * Perform all steps to upgrade from the old waypoints to the new version
 
 * that uses station. This includes some old saveload mechanics.
 
 */
 
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 (CheckSavegameVersion(17)) {
 
		for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
 
			if (wp->delete_ctr == 0 && HasBit(_m[wp->xy].m3, 4)) {
 
				wp->spec = GetCustomStationSpec(STAT_CLASS_WAYP, _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 < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
 
			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
 
			if (statspec != NULL && statspec->grffile->grfid == wp->speclist[1].grfid && statspec->localidx == wp->speclist[1].localidx) {
 
				wp->speclist[1].spec = statspec;
 
				if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
 
					wp->spec = statspec;
 
				break;
 
			}
 
		}
 
	}
 
}
 

	
 
static uint16 _waypoint_town_index;
 
static StringID _waypoint_string_id;
 
static StationSpecList _waypoint_spec;
 
	/* All saveload conversions have been done. Create the new waypoints! */
 
	for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
 
		Waypoint *new_wp = new Waypoint(wp->xy);
 
		new_wp->town       = wp->town;
 
		new_wp->town_cn    = wp->town_cn;
 
		new_wp->name       = wp->name;
 
		new_wp->delete_ctr = 0; // Just reset delete counter for once.
 
		new_wp->build_date = wp->build_date;
 
		new_wp->owner      = wp->owner;
 

	
 
		new_wp->string_id = STR_SV_STNAME_WAYPOINT;
 

	
 
		TileIndex t = wp->xy;
 
		if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp->index) {
 
			/* The tile might've been reserved! */
 
			bool reserved = !CheckSavegameVersion(100) && HasBit(_m[t].m5, 4);
 

	
 
			/* The tile really has our waypoint, so reassign the map array */
 
			MakeRailWaypoint(t, GetTileOwner(t), new_wp->index, (Axis)GB(_m[t].m5, 0, 1), 0, GetRailType(t));
 
			new_wp->facilities |= FACIL_TRAIN;
 
			new_wp->owner = GetTileOwner(t);
 

	
 
			SetRailwayStationReservation(t, reserved);
 

	
 
			if (wp->spec != NULL) {
 
				SetCustomStationSpecIndex(t, AllocateSpecToStation(wp->spec, new_wp, true));
 
			}
 
		}
 

	
 
		wp->new_index = new_wp->index;
 
	}
 

	
 
static const SaveLoad _waypoint_desc[] = {
 
	 SLE_CONDVAR(Waypoint, xy,            SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
 
	 SLE_CONDVAR(Waypoint, xy,            SLE_UINT32,                  6, SL_MAX_VERSION),
 
	SLEG_CONDVAR(_waypoint_town_index,    SLE_UINT16,                 12, 121),
 
	 SLE_CONDREF(Waypoint, town,          REF_TOWN,                  122, SL_MAX_VERSION),
 
	 SLE_CONDVAR(Waypoint, town_cn,       SLE_FILE_U8 | SLE_VAR_U16,  12, 88),
 
	 SLE_CONDVAR(Waypoint, town_cn,       SLE_UINT16,                 89, SL_MAX_VERSION),
 
	SLEG_CONDVAR(_waypoint_string_id,     SLE_STRINGID,                0, 83),
 
	 SLE_CONDSTR(Waypoint, name,          SLE_STR, 0,                 84, SL_MAX_VERSION),
 
	     SLE_VAR(Waypoint, delete_ctr,    SLE_UINT8),
 
	/* Update the orders of vehicles */
 
	OrderList *ol;
 
	FOR_ALL_ORDER_LISTS(ol) {
 
		if (ol->GetFirstSharedVehicle()->type != VEH_TRAIN) continue;
 

	
 
		for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o);
 
	}
 

	
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type != VEH_TRAIN) continue;
 

	
 
		UpdateWaypointOrder(&v->current_order);
 
	}
 

	
 
	 SLE_CONDVAR(Waypoint, build_date,    SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
 
	 SLE_CONDVAR(Waypoint, build_date,    SLE_INT32,                  31, SL_MAX_VERSION),
 
	SLEG_CONDVAR(_waypoint_spec.localidx, SLE_UINT8,                   3, SL_MAX_VERSION),
 
	SLEG_CONDVAR(_waypoint_spec.grfid,    SLE_UINT32,                 17, SL_MAX_VERSION),
 
	 SLE_CONDVAR(Waypoint, owner,         SLE_UINT8,                 101, SL_MAX_VERSION),
 
	_old_waypoints.Reset();
 
}
 

	
 
static const SaveLoad _old_waypoint_desc[] = {
 
	SLE_CONDVAR(OldWaypoint, xy,         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
 
	SLE_CONDVAR(OldWaypoint, xy,         SLE_UINT32,                  6, SL_MAX_VERSION),
 
	SLE_CONDVAR(OldWaypoint, town_index, SLE_UINT16,                 12, 121),
 
	SLE_CONDREF(OldWaypoint, town,       REF_TOWN,                  122, SL_MAX_VERSION),
 
	SLE_CONDVAR(OldWaypoint, town_cn,    SLE_FILE_U8 | SLE_VAR_U16,  12, 88),
 
	SLE_CONDVAR(OldWaypoint, town_cn,    SLE_UINT16,                 89, SL_MAX_VERSION),
 
	SLE_CONDVAR(OldWaypoint, string_id,  SLE_STRINGID,                0, 83),
 
	SLE_CONDSTR(OldWaypoint, name,       SLE_STR, 0,                 84, SL_MAX_VERSION),
 
	    SLE_VAR(OldWaypoint, delete_ctr, SLE_UINT8),
 

	
 
	SLE_CONDVAR(OldWaypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
 
	SLE_CONDVAR(OldWaypoint, build_date, SLE_INT32,                  31, SL_MAX_VERSION),
 
	SLE_CONDVAR(OldWaypoint, localidx,   SLE_UINT8,                   3, SL_MAX_VERSION),
 
	SLE_CONDVAR(OldWaypoint, grfid,      SLE_UINT32,                 17, SL_MAX_VERSION),
 
	SLE_CONDVAR(OldWaypoint, owner,      SLE_UINT8,                 101, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static void Save_WAYP()
 
{
 
	Waypoint *wp;
 

	
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->num_specs == 0) {
 
			_waypoint_spec.grfid = 0;
 
		} else {
 
			_waypoint_spec = wp->speclist[1];
 
		}
 

	
 
		SlSetArrayIndex(wp->index);
 
		SlObject(wp, _waypoint_desc);
 
	}
 
}
 

	
 
static void Load_WAYP()
 
{
 
	/* Precaution for when loading failed and it didn't get cleared */
 
	_old_waypoints.Clear();
 

	
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		_waypoint_string_id = 0;
 
		_waypoint_town_index = 0;
 
		_waypoint_spec.grfid = 0;
 

	
 
		Waypoint *wp = new (index) Waypoint();
 
		SlObject(wp, _waypoint_desc);
 

	
 
		wp->facilities |= FACIL_TRAIN;
 
		OldWaypoint *wp = _old_waypoints.Append();
 
		memset(wp, 0, sizeof(*wp));
 

	
 
		if (_waypoint_spec.grfid != 0) {
 
			wp->num_specs = 2;
 
			wp->speclist = CallocT<StationSpecList>(2);
 
			wp->speclist[1] = _waypoint_spec;
 
		}
 

	
 
		if (CheckSavegameVersion(84)) wp->name = (char *)(size_t)_waypoint_string_id;
 
		if (CheckSavegameVersion(122)) wp->town = (Town *)(size_t)_waypoint_town_index;
 
		wp->index = index;
 
		SlObject(wp, _old_waypoint_desc);
 
	}
 
}
 

	
 
static void Ptrs_WAYP()
 
{
 
	Waypoint *wp;
 
	for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
 
		SlObject(wp, _old_waypoint_desc);
 

	
 
	FOR_ALL_WAYPOINTS(wp) {
 
		SlObject(wp, _waypoint_desc);
 

	
 
		StringID sid = (StringID)(size_t)wp->name;
 
		if (CheckSavegameVersion(12)) {
 
			wp->town_cn = (sid & 0xC000) == 0xC000 ? (sid >> 8) & 0x3F : 0;
 
			wp->town_cn = (wp->string_id & 0xC000) == 0xC000 ? (wp->string_id >> 8) & 0x3F : 0;
 
			wp->town = ClosestTownFromTile(wp->xy, UINT_MAX);
 
		} else if (CheckSavegameVersion(122)) {
 
			/* Only for versions 12 .. 122 */
 
			wp->town = Town::Get((size_t)wp->town);
 
			wp->town = Town::Get(wp->town_index);
 
		}
 
		if (CheckSavegameVersion(84)) {
 
			wp->name = CopyFromOldName(sid);
 
			wp->name = CopyFromOldName(wp->string_id);
 
		}
 
	}
 
}
 

	
 
extern const ChunkHandler _waypoint_chunk_handlers[] = {
 
	{ 'CHKP', Save_WAYP, Load_WAYP, Ptrs_WAYP, CH_ARRAY | CH_LAST},
 
	{ 'CHKP', NULL, Load_WAYP, Ptrs_WAYP, CH_ARRAY | CH_LAST},
 
};
src/signal.cpp
Show inline comments
 
@@ -288,14 +288,6 @@ static SigFlags ExploreSegment(Owner own
 
					}
 
				}
 

	
 
				if (GetRailTileType(tile) == RAIL_TILE_WAYPOINT) {
 
					if (GetWaypointAxis(tile) != DiagDirToAxis(enterdir)) continue;
 
					if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN;
 
					tile += TileOffsByDiagDir(exitdir);
 
					/* enterdir and exitdir stay the same */
 
					break;
 
				}
 

	
 
				TrackBits tracks = GetTrackBits(tile); // trackbits of tile
 
				TrackBits tracks_masked = (TrackBits)(tracks & _enterdir_to_trackbits[enterdir]); // only incidating trackbits
 

	
src/station.cpp
Show inline comments
 
@@ -50,12 +50,6 @@ Station::Station(TileIndex tile) :
 
	/* this->random_bits is set in Station::AddFacility() */
 
}
 

	
 
/* static */ BaseStation *BaseStation::GetByTile(TileIndex tile)
 
{
 
	if (IsRailWaypointTile(tile)) return Waypoint::GetByTile(tile);
 
	return Station::GetByTile(tile);
 
}
 

	
 
/**
 
 * Clean up a station by clearing vehicle orders and invalidating windows.
 
 * Aircraft-Hangar orders need special treatment here, as the hangars are
src/station_base.h
Show inline comments
 
@@ -21,7 +21,7 @@
 
#include "station_map.h"
 
#include <list>
 

	
 
typedef Pool<Station, StationID, 32, 64000> StationPool;
 
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
 
extern StationPool _station_pool;
 

	
 
static const byte INITIAL_STATION_RATING = 175;
 
@@ -85,7 +85,7 @@ struct TileArea {
 
};
 

	
 
/** Base class for all station-ish types */
 
struct BaseStation {
 
struct BaseStation : StationPool::PoolItem<&_station_pool> {
 
	TileIndex xy;                   ///< Base tile of the station
 
	ViewportSign sign;              ///< NOSAVE: Dimensions of sign
 
	byte delete_ctr;                ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
 
@@ -144,9 +144,14 @@ struct BaseStation {
 
	 * @param tile The tile to get the base station from.
 
	 * @return the station associated with that tile.
 
	 */
 
	static BaseStation *GetByTile(TileIndex tile);
 
	static FORCEINLINE BaseStation *GetByTile(TileIndex tile)
 
	{
 
		return BaseStation::Get(GetStationIndex(tile));
 
	}
 
};
 

	
 
#define FOR_ALL_BASE_STATIONS(var) FOR_ALL_ITEMS_FROM(BaseStation, station_index, var, 0)
 

	
 
/**
 
 * Class defining several overloaded accessors so we don't
 
 * have to cast base stations that often
 
@@ -176,6 +181,44 @@ struct SpecializedStation : public BaseS
 
	}
 

	
 
	/**
 
	 * Tests whether given index is a valid index for station of this type
 
	 * @param index tested index
 
	 * @return is this index valid index of T?
 
	 */
 
	static FORCEINLINE bool IsValidID(size_t index)
 
	{
 
		return BaseStation::IsValidID(index) && IsExpected(BaseStation::Get(index));
 
	}
 

	
 
	/**
 
	 * Gets station with given index
 
	 * @return pointer to station with given index casted to T *
 
	 */
 
	static FORCEINLINE T *Get(size_t index)
 
	{
 
		return (T *)BaseStation::Get(index);
 
	}
 

	
 
	/**
 
	 * Returns station if the index is a valid index for this station type
 
	 * @return pointer to station with given index if it's a station of this type
 
	 */
 
	static FORCEINLINE T *GetIfValid(size_t index)
 
	{
 
		return IsValidID(index) ? Get(index) : NULL ;
 
	}
 

	
 
	/**
 
	 * Get the station belonging to a specific tile.
 
	 * @param tile The tile to get the station from.
 
	 * @return the station associated with that tile.
 
	 */
 
	static FORCEINLINE T *GetByTile(TileIndex tile)
 
	{
 
		return GetIfValid(GetStationIndex(tile));
 
	}
 

	
 
	/**
 
	 * Converts a BaseStation to SpecializedStation with type checking.
 
	 * @param st BaseStation pointer
 
	 * @return pointer to SpecializedStation
 
@@ -198,11 +241,13 @@ struct SpecializedStation : public BaseS
 
	}
 
};
 

	
 
#define FOR_ALL_BASE_STATIONS_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, station_index, var, 0) if (name::IsExpected(var))
 

	
 

	
 
typedef SmallVector<Industry *, 2> IndustryVector;
 

	
 
/** Station data structure */
 
struct Station : StationPool::PoolItem<&_station_pool>, SpecializedStation<Station, false> {
 
struct Station : SpecializedStation<Station, false> {
 
public:
 
	RoadStop *GetPrimaryRoadStop(RoadStopType type) const
 
	{
 
@@ -274,24 +319,9 @@ public:
 

	
 
	/* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
 

	
 
	/**
 
	 * Determines whether a station is a buoy only.
 
	 * @todo Ditch this encoding of buoys
 
	 */
 
	FORCEINLINE bool IsBuoy() const
 
	{
 
		return (this->had_vehicle_of_type & HVOT_BUOY) != 0;
 
	}
 

	
 
	static FORCEINLINE Station *GetByTile(TileIndex tile)
 
	{
 
		return Station::Get(GetStationIndex(tile));
 
	}
 

	
 
	static void PostDestructor(size_t index);
 
};
 

	
 
#define FOR_ALL_STATIONS_FROM(var, start) FOR_ALL_ITEMS_FROM(Station, station_index, var, start)
 
#define FOR_ALL_STATIONS(var) FOR_ALL_STATIONS_FROM(var, 0)
 
#define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
 

	
 
#endif /* STATION_BASE_H */
src/station_cmd.cpp
Show inline comments
 
@@ -197,7 +197,6 @@ enum StationNaming {
 
	STATIONNAMING_AIRPORT,
 
	STATIONNAMING_OILRIG,
 
	STATIONNAMING_DOCK,
 
	STATIONNAMING_BUOY,
 
	STATIONNAMING_HELIPORT,
 
};
 

	
 
@@ -239,7 +238,6 @@ static StringID GenerateStationName(Stat
 
		1U << M(STR_SV_STNAME_AIRPORT),          // STATIONNAMING_AIRPORT
 
		1U << M(STR_SV_STNAME_OILFIELD),         // STATIONNAMING_OILRIG
 
		1U << M(STR_SV_STNAME_DOCKS),            // STATIONNAMING_DOCK
 
		0x1FFU << M(STR_SV_STNAME_BUOY_1),       // STATIONNAMING_BUOY
 
		1U << M(STR_SV_STNAME_HELIPORT),         // STATIONNAMING_HELIPORT
 
	};
 

	
 
@@ -266,7 +264,6 @@ static StringID GenerateStationName(Stat
 
		}
 
	}
 

	
 
	if (name_class != STATIONNAMING_BUOY) {
 
		TileIndex indtile = tile;
 
		StationNameInformation sni = { free_names, indtypes };
 
		if (CircularTileSearch(&indtile, 7, FindNearIndustryName, &sni)) {
 
@@ -282,7 +279,6 @@ static StringID GenerateStationName(Stat
 

	
 
		/* Oil rigs/mines name could be marked not free by looking for a near by industry. */
 
		free_names = sni.free_names;
 
	}
 

	
 
	/* check default names */
 
	uint32 tmp = free_names & _gen_station_name_bits[name_class];
 
@@ -540,9 +536,6 @@ CargoArray GetAcceptanceAroundTiles(Tile
 
 */
 
static void UpdateStationAcceptance(Station *st, bool show_msg)
 
{
 
	/* Don't update acceptance for a buoy */
 
	if (st->IsBuoy()) return;
 

	
 
	/* old accepted goods types */
 
	uint old_acc = GetAcceptanceMask(st);
 

	
 
@@ -1963,31 +1956,23 @@ CommandCost CmdBuildBuoy(TileIndex tile,
 
	if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
 

	
 
	/* allocate and initialize new station */
 
	if (!Station::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING);
 
	if (!Waypoint::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING);
 

	
 
	if (flags & DC_EXEC) {
 
		Station *st = new Station(tile);
 

	
 
		st->town = ClosestTownFromTile(tile, UINT_MAX);
 
		st->string_id = GenerateStationName(st, tile, STATIONNAMING_BUOY);
 

	
 
		if (Company::IsValidID(_current_company)) {
 
			SetBit(st->town->have_ratings, _current_company);
 
		}
 
		st->dock_tile = tile;
 
		Waypoint *st = new Waypoint(tile);
 

	
 
		st->string_id = STR_SV_STNAME_BUOY;
 

	
 
		st->facilities |= FACIL_DOCK;
 
		/* Buoys are marked in the Station struct by this flag. Yes, it is this
 
		 * braindead.. */
 
		st->had_vehicle_of_type |= HVOT_BUOY;
 
		st->owner = OWNER_NONE;
 

	
 
		st->build_date = _date;
 

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

	
 
		MakeBuoy(tile, st->index, GetWaterClass(tile));
 

	
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
		st->RecomputeIndustriesNear();
 
		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
 
	}
 
@@ -2008,7 +1993,7 @@ bool HasStationInUse(StationID station, 
 
		if (company == INVALID_COMPANY || v->owner == company) {
 
			const Order *order;
 
			FOR_VEHICLE_ORDERS(v, order) {
 
				if (order->IsType(OT_GOTO_STATION) && order->GetDestination() == station) {
 
				if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT)) && order->GetDestination() == station) {
 
					return true;
 
				}
 
			}
 
@@ -2028,18 +2013,14 @@ static CommandCost RemoveBuoy(TileIndex 
 
	/* XXX: strange stuff, allow clearing as invalid company when clearing landscape */
 
	if (!Company::IsValidID(_current_company) && !(flags & DC_BANKRUPT)) return_cmd_error(INVALID_STRING_ID);
 

	
 
	Station *st = Station::GetByTile(tile);
 
	Waypoint *st = Waypoint::GetByTile(tile);
 

	
 
	if (HasStationInUse(st->index, INVALID_COMPANY)) return_cmd_error(STR_BUOY_IS_IN_USE);
 
	/* remove the buoy if there is a ship on tile when company goes bankrupt... */
 
	if (!(flags & DC_BANKRUPT) && !EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		st->dock_tile = INVALID_TILE;
 
		/* Buoys are marked in the Station struct by this flag. Yes, it is this
 
		 * braindead.. */
 
		st->facilities &= ~FACIL_DOCK;
 
		st->had_vehicle_of_type &= ~HVOT_BUOY;
 

	
 
		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
 

	
 
@@ -2050,8 +2031,7 @@ static CommandCost RemoveBuoy(TileIndex 
 
		MarkTileDirtyByTile(tile);
 

	
 
		st->UpdateVirtCoord();
 
		st->RecomputeIndustriesNear();
 
		DeleteStationIfEmpty(st);
 
		st->delete_ctr = 0;
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_truck_station);
 
@@ -2227,7 +2207,7 @@ static void DrawTile_Station(TileInfo *t
 
	int32 total_offset;
 
	int32 custom_ground_offset;
 

	
 
	if (IsRailwayStation(ti->tile)) {
 
	if (IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) {
 
		const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
		roadtypes = ROADTYPES_NONE;
 
		total_offset = rti->total_offset;
 
@@ -2238,7 +2218,7 @@ static void DrawTile_Station(TileInfo *t
 
		custom_ground_offset = 0;
 
	}
 
	uint32 relocation = 0;
 
	const Station *st = NULL;
 
	const BaseStation *st = NULL;
 
	const StationSpec *statspec = NULL;
 
	Owner owner = GetTileOwner(ti->tile);
 

	
 
@@ -2256,7 +2236,7 @@ static void DrawTile_Station(TileInfo *t
 

	
 
	if (IsCustomStationSpecIndex(ti->tile)) {
 
		/* look for customization */
 
		st = Station::GetByTile(ti->tile);
 
		st = BaseStation::GetByTile(ti->tile);
 
		statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
 

	
 
		if (statspec != NULL) {
 
@@ -2304,13 +2284,13 @@ static void DrawTile_Station(TileInfo *t
 
		DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
 

	
 
		/* PBS debugging, draw reserved tracks darker */
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && IsRailwayStation(ti->tile) && HasStationReservation(ti->tile)) {
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && (IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) && HasStationReservation(ti->tile)) {
 
			const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
			DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_y : rti->base_sprites.single_x, PALETTE_CRASH);
 
		}
 
	}
 

	
 
	if (IsRailwayStation(ti->tile) && HasCatenaryDrawn(GetRailType(ti->tile)) && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
 
	if ((IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) && HasCatenaryDrawn(GetRailType(ti->tile)) && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
 

	
 
	if (HasBit(roadtypes, ROADTYPE_TRAM)) {
 
		Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
 
@@ -2318,6 +2298,11 @@ static void DrawTile_Station(TileInfo *t
 
		DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
 
	}
 

	
 
	if (IsRailWaypoint(ti->tile)) {
 
		/* Don't offset the waypoint graphics; they're always the same. */
 
		total_offset = 0;
 
	}
 

	
 
	const DrawTileSeqStruct *dtss;
 
	foreach_draw_tile_seq(dtss, t->seq) {
 
		SpriteID image = dtss->image.sprite;
 
@@ -2408,7 +2393,7 @@ static void GetTileDesc_Station(TileInde
 
			}
 
		}
 
	}
 
	td->build_date = Station::GetByTile(tile)->build_date;
 
	td->build_date = BaseStation::GetByTile(tile)->build_date;
 

	
 
	const StationSpec *spec = GetStationSpec(tile);
 

	
 
@@ -2434,6 +2419,7 @@ static void GetTileDesc_Station(TileInde
 
		case STATION_OILRIG:  str = STR_INDUSTRY_NAME_OIL_RIG; break;
 
		case STATION_DOCK:    str = STR_STATION_DESCRIPTION_SHIP_DOCK; break;
 
		case STATION_BUOY:    str = STR_STATION_DESCRIPTION_BUOY; break;
 
		case STATION_WAYPOINT: str = STR_LANDINFO_WAYPOINT; break;
 
	}
 
	td->str = str;
 
}
 
@@ -2445,7 +2431,7 @@ static TrackStatus GetTileTrackStatus_St
 

	
 
	switch (mode) {
 
		case TRANSPORT_RAIL:
 
			if (IsRailwayStation(tile) && !IsStationTileBlocked(tile)) {
 
			if ((IsRailwayStation(tile) || IsRailWaypoint(tile)) && !IsStationTileBlocked(tile)) {
 
				trackbits = TrackToTrackBits(GetRailStationTrack(tile));
 
			}
 
			break;
 
@@ -2551,10 +2537,14 @@ static void AnimateTile_Station(TileInde
 

	
 
static bool ClickTile_Station(TileIndex tile)
 
{
 
	if (IsHangar(tile)) {
 
	const BaseStation *st = BaseStation::GetByTile(tile);
 

	
 
	if (st->facilities & FACIL_WAYPOINT) {
 
		ShowWaypointWindow(Waypoint::From(st));
 
	} else if (IsHangar(tile)) {
 
		ShowDepotWindow(tile, VEH_AIRCRAFT);
 
	} else {
 
		ShowStationViewWindow(GetStationIndex(tile));
 
		ShowStationViewWindow(st->index);
 
	}
 
	return true;
 
}
 
@@ -2650,15 +2640,15 @@ static VehicleEnterTileStatus VehicleEnt
 
 * @param st the station receiving the tick.
 
 * @return true if the station is still valid (wasn't deleted)
 
 */
 
static bool StationHandleBigTick(Station *st)
 
static bool StationHandleBigTick(BaseStation *st)
 
{
 
	UpdateStationAcceptance(st, true);
 

	
 
	if (st->facilities == 0 && ++st->delete_ctr >= 8) {
 
	if ((st->facilities & ~FACIL_WAYPOINT) == 0 && ++st->delete_ctr >= 8) {
 
		delete st;
 
		return false;
 
	}
 

	
 
	if ((st->facilities & FACIL_WAYPOINT) == 0) UpdateStationAcceptance(Station::From(st), true);
 

	
 
	return true;
 
}
 

	
 
@@ -2778,23 +2768,23 @@ static void UpdateStationRating(Station 
 
}
 

	
 
/* called for every station each tick */
 
static void StationHandleSmallTick(Station *st)
 
static void StationHandleSmallTick(BaseStation *st)
 
{
 
	if (st->facilities == 0) return;
 
	if ((st->facilities & FACIL_WAYPOINT) != 0 || st->facilities == 0) return;
 

	
 
	byte b = st->delete_ctr + 1;
 
	if (b >= 185) b = 0;
 
	st->delete_ctr = b;
 

	
 
	if (b == 0) UpdateStationRating(st);
 
	if (b == 0) UpdateStationRating(Station::From(st));
 
}
 

	
 
void OnTick_Station()
 
{
 
	if (_game_mode == GM_EDITOR) return;
 

	
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
	BaseStation *st;
 
	FOR_ALL_BASE_STATIONS(st) {
 
		StationHandleSmallTick(st);
 

	
 
		/* Run 250 tick interval trigger for station animation.
 
@@ -2884,7 +2874,7 @@ CommandCost CmdRenameStation(TileIndex t
 
}
 

	
 
/**
 
 * Find all (non-buoy) stations around a rectangular producer (industry, house, headquarter, ...)
 
 * Find all stations around a rectangular producer (industry, house, headquarter, ...)
 
 *
 
 * @param tile North tile of producer
 
 * @param w_prod X extent of producer
 
@@ -2903,8 +2893,7 @@ void FindStationsAroundTiles(TileIndex t
 
			if (cur_tile == INVALID_TILE || !IsTileType(cur_tile, MP_STATION)) continue;
 

	
 
			Station *st = Station::GetByTile(cur_tile);
 

	
 
			if (st->IsBuoy()) continue; // bouys don't accept cargo
 
			if (st == NULL) continue;
 

	
 
			if (_settings_game.station.modified_catchment) {
 
				int rad = st->GetCatchmentRadius();
 
@@ -3121,6 +3110,7 @@ static CommandCost ClearTile_Station(Til
 
		switch (GetStationType(tile)) {
 
			default: break;
 
			case STATION_RAIL:    return_cmd_error(STR_ERROR_MUST_DEMOLISH_RAILROAD);
 
			case STATION_WAYPOINT: return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
 
			case STATION_AIRPORT: return_cmd_error(STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST);
 
			case STATION_TRUCK:   return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST);
 
			case STATION_BUS:     return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST);
 
@@ -3134,6 +3124,7 @@ static CommandCost ClearTile_Station(Til
 

	
 
	switch (GetStationType(tile)) {
 
		case STATION_RAIL:    return RemoveRailroadStation(tile, flags);
 
		case STATION_WAYPOINT: return RemoveTrainWaypoint(tile, flags, false);
 
		case STATION_AIRPORT: return RemoveAirport(tile, flags);
 
		case STATION_TRUCK:
 
			if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile, flags))
 
@@ -3159,6 +3150,7 @@ static CommandCost TerraformTile_Station
 
		 */
 
		if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
 
			switch (GetStationType(tile)) {
 
				case STATION_WAYPOINT:
 
				case STATION_RAIL: {
 
					DiagDirection direction = AxisToDiagDir(GetRailStationAxis(tile));
 
					if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
src/station_gui.cpp
Show inline comments
 
@@ -143,7 +143,7 @@ protected:
 

	
 
		const Station *st;
 
		FOR_ALL_STATIONS(st) {
 
			if (st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy() && HasStationInUse(st->index, owner))) {
 
			if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, owner))) {
 
				if (this->facilities & st->facilities) { // only stations with selected facilities
 
					int num_waiting_cargo = 0;
 
					for (CargoID j = 0; j < NUM_CARGO; j++) {
 
@@ -378,7 +378,7 @@ public:
 

	
 
			/* Do not do the complex check HasStationInUse here, it may be even false
 
			 * when the order had been removed and the station list hasn't been removed yet */
 
			assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
 
			assert(st->owner == owner || st->owner == OWNER_NONE);
 

	
 
			SetDParam(0, st->index);
 
			SetDParam(1, st->facilities);
 
@@ -409,7 +409,7 @@ public:
 

	
 
				const Station *st = this->stations[id_v];
 
				/* do not check HasStationInUse - it is slow and may be invalid */
 
				assert(st->owner == (Owner)this->window_number || (st->owner == OWNER_NONE && !st->IsBuoy()));
 
				assert(st->owner == (Owner)this->window_number || st->owner == OWNER_NONE);
 

	
 
				if (_ctrl_pressed) {
 
					ShowExtraViewPortWindow(st->xy);
src/station_map.h
Show inline comments
 
@@ -88,6 +88,28 @@ static inline bool IsRailwayStationTile(
 
	return IsTileType(t, MP_STATION) && IsRailwayStation(t);
 
}
 

	
 
/**
 
 * Is this station tile a rail waypoint?
 
 * @param t the tile to get the information from
 
 * @pre IsTileType(t, MP_STATION)
 
 * @return true if and only if the tile is a rail waypoint
 
 */
 
static inline bool IsRailWaypoint(TileIndex t)
 
{
 
	return GetStationType(t) == STATION_WAYPOINT;
 
}
 

	
 
/**
 
 * Is this tile a station tile and a rail waypoint?
 
 * @param t the tile to get the information from
 
 * @return true if and only if the tile is a rail waypoint
 
 */
 
static inline bool IsRailWaypointTile(TileIndex t)
 
{
 
	return IsTileType(t, MP_STATION) && IsRailWaypoint(t);
 
}
 

	
 

	
 
static inline bool IsAirport(TileIndex t)
 
{
 
	return GetStationType(t) == STATION_AIRPORT;
 
@@ -186,7 +208,7 @@ static inline bool IsHangarTile(TileInde
 

	
 
static inline Axis GetRailStationAxis(TileIndex t)
 
{
 
	assert(IsRailwayStation(t));
 
	assert(IsRailwayStation(t) || IsRailWaypoint(t));
 
	return HasBit(GetStationGfx(t), 0) ? AXIS_Y : AXIS_X;
 
}
 

	
 
@@ -214,31 +236,31 @@ static inline bool IsCompatibleTrainStat
 

	
 
/**
 
 * Get the reservation state of the rail station
 
 * @pre IsRailwayStationTile(t)
 
 * @pre IsRailwayStation(t) || IsRailWaypoint(t)
 
 * @param t the station tile
 
 * @return reservation state
 
 */
 
static inline bool HasStationReservation(TileIndex t)
 
{
 
	assert(IsRailwayStationTile(t));
 
	assert(IsRailwayStation(t) || IsRailWaypoint(t));
 
	return HasBit(_m[t].m6, 2);
 
}
 

	
 
/**
 
 * Set the reservation state of the rail station
 
 * @pre IsRailwayStationTile(t)
 
 * @pre IsRailwayStation(t) || IsRailWaypoint(t)
 
 * @param t the station tile
 
 * @param b the reservation state
 
 */
 
static inline void SetRailwayStationReservation(TileIndex t, bool b)
 
{
 
	assert(IsRailwayStationTile(t));
 
	assert(IsRailwayStation(t) || IsRailWaypoint(t));
 
	SB(_m[t].m6, 2, 1, b ? 1 : 0);
 
}
 

	
 
/**
 
 * Get the reserved track bits for a waypoint
 
 * @pre IsRailwayStationTile(t)
 
 * @pre IsRailwayStation(t) || IsRailWaypoint(t)
 
 * @param t the tile
 
 * @return reserved track bits
 
 */
 
@@ -325,6 +347,13 @@ static inline void MakeRailStation(TileI
 
	SetRailwayStationReservation(t, false);
 
}
 

	
 
static inline void MakeRailWaypoint(TileIndex t, Owner o, StationID sid, Axis a, byte section, RailType rt)
 
{
 
	MakeStation(t, o, sid, STATION_WAYPOINT, section + a);
 
	SetRailType(t, rt);
 
	SetRailwayStationReservation(t, false);
 
}
 

	
 
static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopType rst, RoadTypes rt, DiagDirection d)
 
{
 
	MakeStation(t, o, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), d);
src/station_type.h
Show inline comments
 
@@ -57,9 +57,8 @@ enum StationHadVehicleOfType {
 
	HVOT_TRUCK    = 1 << 3, ///< Station has seen a truck
 
	HVOT_AIRCRAFT = 1 << 4, ///< Station has seen an aircraft
 
	HVOT_SHIP     = 1 << 5, ///< Station has seen a ship
 
	/* This bit is used to mark stations. No, it does not belong here, but what
 
	 * can we do? ;-) */
 
	HVOT_BUOY     = 1 << 6
 

	
 
	HVOT_WAYPOINT = 1 << 6, ///< Station is a waypoint (NewGRF only!)
 
};
 
DECLARE_ENUM_AS_BIT_SET(StationHadVehicleOfType);
 
typedef SimpleTinyEnumT<StationHadVehicleOfType, byte> StationHadVehicleOfTypeByte;
src/strings.cpp
Show inline comments
 
@@ -863,8 +863,8 @@ static char *FormatString(char *buff, co
 
					int64 temp[2];
 
					temp[0] = wp->town->index;
 
					temp[1] = wp->town_cn + 1;
 
					StringID str = wp->town_cn == 0 ? STR_WAYPOINTNAME_CITY : STR_WAYPOINTNAME_CITY_SERIAL;
 

	
 
					StringID str = ((wp->string_id == STR_SV_STNAME_BUOY) ? STR_BUOYNAME_CITY : STR_WAYPOINTNAME_CITY);
 
					if (wp->town_cn != 0) str++;
 
					buff = GetStringWithArgs(buff, str, temp, last);
 
				}
 
				break;
src/terraform_gui.cpp
Show inline comments
 
@@ -635,10 +635,10 @@ static void ResetLandscapeConfirmationCa
 
		_generating_world = false;
 

	
 
		/* Delete all station signs */
 
		Station *st;
 
		FOR_ALL_STATIONS(st) {
 
		BaseStation *st;
 
		FOR_ALL_BASE_STATIONS(st) {
 
			/* There can be buoys, remove them */
 
			if (st->IsBuoy() && IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
 
			if (IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
 
			if (st->facilities == 0) delete st;
 
		}
 

	
src/train_cmd.cpp
Show inline comments
 
@@ -482,7 +482,7 @@ static int GetTrainAcceleration(Train *v
 
	assert(max_speed == GetTrainCurveSpeedLimit(v)); // safety check, will be removed later
 
	int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
 

	
 
	if (IsTileType(v->tile, MP_STATION) && v->IsFrontEngine()) {
 
	if (IsRailwayStationTile(v->tile) && v->IsFrontEngine()) {
 
		StationID sid = GetStationIndex(v->tile);
 
		if (v->current_order.ShouldStopAtStation(v, sid)) {
 
			int station_ahead;
 
@@ -4443,12 +4443,10 @@ static bool TrainLocoHandler(Train *v, b
 

	
 
			OrderType order_type = v->current_order.GetType();
 
			/* Do not skip waypoints (incl. 'via' stations) when passing through at full speed. */
 
			if ((order_type == OT_GOTO_WAYPOINT &&
 
						v->dest_tile == v->tile) ||
 
					(order_type == OT_GOTO_STATION &&
 
			if ((order_type == OT_GOTO_WAYPOINT || order_type == OT_GOTO_STATION) &&
 
						(v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) &&
 
						IsTileType(v->tile, MP_STATION) &&
 
						v->current_order.GetDestination() == GetStationIndex(v->tile))) {
 
						v->current_order.GetDestination() == GetStationIndex(v->tile)) {
 
				ProcessOrders(v);
 
			}
 
		}
src/vehicle_gui.cpp
Show inline comments
 
@@ -788,8 +788,6 @@ static void DrawSmallOrderList(const Veh
 
		sel--;
 

	
 
		if (order->IsType(OT_GOTO_STATION)) {
 
			if (v->type == VEH_SHIP && Station::Get(order->GetDestination())->IsBuoy()) continue;
 

	
 
			SetDParam(0, order->GetDestination());
 
			DrawString(left, right, y, STR_ORDER_STATION_SMALL);
 

	
 
@@ -1950,7 +1948,7 @@ struct VehicleViewWindow : Window {
 
				case OT_GOTO_WAYPOINT: {
 
					assert(v->type == VEH_TRAIN || v->type == VEH_SHIP);
 
					SetDParam(0, v->current_order.GetDestination());
 
					str = (v->type == VEH_TRAIN ? STR_HEADING_FOR_WAYPOINT : STR_HEADING_FOR_STATION) + _settings_client.gui.vehicle_speed;
 
					str = STR_HEADING_FOR_WAYPOINT + _settings_client.gui.vehicle_speed;
 
					SetDParam(1, v->GetDisplaySpeed());
 
					break;
 
				}
src/viewport.cpp
Show inline comments
 
@@ -1218,7 +1218,7 @@ static void ViewportAddSigns(DrawPixelIn
 

	
 
static void AddWaypoint(const Waypoint *wp, StringID str, uint16 width)
 
{
 
	AddStringToDraw(wp->sign.left + 1, wp->sign.top + 1, str, wp->index, 0, (wp->delete_ctr != 0 ? 0xE : _company_colours[wp->owner]), width);
 
	AddStringToDraw(wp->sign.left + 1, wp->sign.top + 1, str, wp->index, 0, (wp->owner == OWNER_NONE || (wp->facilities & ~FACIL_WAYPOINT) == 0) ? 0xE : _company_colours[wp->owner], width);
 
}
 

	
 

	
src/waypoint.cpp
Show inline comments
 
@@ -12,23 +12,6 @@
 
#include "window_func.h"
 
#include "newgrf_station.h"
 
#include "order_func.h"
 
#include "core/pool_func.hpp"
 

	
 
WaypointPool _waypoint_pool("Waypoint");
 
INSTANTIATE_POOL_METHODS(Waypoint)
 

	
 
/**
 
 * Daily loop for waypoints
 
 */
 
void WaypointsDailyLoop()
 
{
 
	Waypoint *wp;
 

	
 
	/* Check if we need to delete a waypoint */
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->delete_ctr != 0 && --wp->delete_ctr == 0) delete wp;
 
	}
 
}
 

	
 
/**
 
 * Draw a waypoint
 
@@ -67,8 +50,3 @@ Waypoint::~Waypoint()
 

	
 
	this->sign.MarkDirty();
 
}
 

	
 
void InitializeWaypoints()
 
{
 
	_waypoint_pool.CleanPool();
 
}
src/waypoint.h
Show inline comments
 
@@ -14,10 +14,7 @@
 
#include "date_type.h"
 
#include "core/pool_type.hpp"
 

	
 
typedef Pool<Waypoint, WaypointID, 32, 64000> WaypointPool;
 
extern WaypointPool _waypoint_pool;
 

	
 
struct Waypoint : WaypointPool::PoolItem<&_waypoint_pool>, SpecializedStation<Waypoint, true> {
 
struct Waypoint : SpecializedStation<Waypoint, true> {
 
	uint16 town_cn;    ///< The Nth waypoint for this town (consecutive number)
 

	
 
	Waypoint(TileIndex tile = INVALID_TILE) : SpecializedStation<Waypoint, true>(tile) { }
 
@@ -27,29 +24,19 @@ struct Waypoint : WaypointPool::PoolItem
 

	
 
	/* virtual */ FORCEINLINE bool TileBelongsToRailStation(TileIndex tile) const
 
	{
 
		return this->delete_ctr == 0 && this->xy == tile;
 
		return IsRailWaypointTile(tile) && GetStationIndex(tile) == this->index;
 
	}
 

	
 
	/* virtual */ uint32 GetNewGRFVariable(const struct ResolverObject *object, byte variable, byte parameter, bool *available) const;
 

	
 
	/* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
 

	
 
	/**
 
	 * Fetch a waypoint by tile
 
	 * @param tile Tile of waypoint
 
	 * @return Waypoint
 
	 */
 
	static FORCEINLINE Waypoint *GetByTile(TileIndex tile)
 
	{
 
		return Waypoint::Get(GetWaypointIndex(tile));
 
	}
 
};
 

	
 
#define FOR_ALL_WAYPOINTS_FROM(var, start) FOR_ALL_ITEMS_FROM(Waypoint, waypoint_index, var, start)
 
#define FOR_ALL_WAYPOINTS(var) FOR_ALL_WAYPOINTS_FROM(var, 0)
 
#define FOR_ALL_WAYPOINTS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Waypoint, var)
 

	
 
CommandCost RemoveTrainWaypoint(TileIndex tile, DoCommandFlag flags, bool justremove);
 
void ShowWaypointWindow(const Waypoint *wp);
 
void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype);
 
void MakeDefaultWaypointName(Waypoint *wp);
 

	
 
#endif /* WAYPOINT_H */
src/waypoint_cmd.cpp
Show inline comments
 
@@ -39,7 +39,7 @@ void Waypoint::UpdateVirtCoord()
 
 * Set the default name for a waypoint
 
 * @param wp Waypoint to work on
 
 */
 
static void MakeDefaultWaypointName(Waypoint *wp)
 
void MakeDefaultWaypointName(Waypoint *wp)
 
{
 
	uint32 used = 0; // bitmap of used waypoint numbers, sliding window with 'next' as base
 
	uint32 next = 0; // first waypoint number in the bitmap
 
@@ -64,7 +64,7 @@ static void MakeDefaultWaypointName(Wayp
 
		/* check only valid waypoints... */
 
		if (lwp != NULL && wp != lwp) {
 
			/* only waypoints with 'generic' name within the same city */
 
			if (lwp->name == NULL && lwp->town == wp->town) {
 
			if (lwp->name == NULL && lwp->town == wp->town && lwp->string_id == wp->string_id) {
 
				/* if lwp->town_cn < next, uint will overflow to '+inf' */
 
				uint i = (uint)lwp->town_cn - next;
 

	
 
@@ -104,7 +104,7 @@ static Waypoint *FindDeletedWaypointClos
 
	uint thres = 8;
 

	
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->delete_ctr != 0 && wp->owner == _current_company) {
 
		if ((wp->facilities & ~FACIL_WAYPOINT) == 0 && wp->owner == _current_company) {
 
			uint cur_dist = DistanceManhattan(tile, wp->xy);
 

	
 
			if (cur_dist < thres) {
 
@@ -163,10 +163,6 @@ CommandCost CmdBuildTrainWaypoint(TileIn
 
	if (flags & DC_EXEC) {
 
		if (wp == NULL) {
 
			wp = new Waypoint(tile);
 

	
 
			wp->town = NULL;
 
			wp->name = NULL;
 
			wp->town_cn = 0;
 
		} else {
 
			/* Move existing (recently deleted) waypoint to the new location */
 

	
 
@@ -186,15 +182,16 @@ CommandCost CmdBuildTrainWaypoint(TileIn
 
		wp->owner = owner;
 

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

	
 
		AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, p1), wp, true);
 
		SetCustomStationSpecIndex(tile, AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, p1), wp, true));
 

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

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

	
 
@@ -224,22 +221,22 @@ CommandCost RemoveTrainWaypoint(TileInde
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		Track track = GetRailWaypointTrack(tile);
 
		Track track = GetRailStationTrack(tile);
 
		wp = Waypoint::GetByTile(tile);
 

	
 
		wp->delete_ctr = 30; // let it live for this many days before we do the actual deletion.
 
		wp->sign.MarkDirty();
 
		wp->facilities &= ~FACIL_TRAIN;
 

	
 
		Train *v = NULL;
 
		uint specindex = GetCustomStationSpecIndex(tile);
 
		if (justremove) {
 
			TrackBits tracks = GetRailWaypointBits(tile);
 
			bool reserved = HasDepotReservation(tile);
 
			TrackBits tracks = GetRailStationTrackBits(tile);
 
			bool reserved = HasStationReservation(tile);
 
			MakeRailNormal(tile, wp->owner, tracks, GetRailType(tile));
 
			if (reserved) SetTrackReservation(tile, tracks);
 
			MarkTileDirtyByTile(tile);
 
		} else {
 
			if (HasDepotReservation(tile)) {
 
			if (HasStationReservation(tile)) {
 
				v = GetTrainForReservation(tile, track);
 
				if (v != NULL) FreeTrainTrackReservation(v);
 
			}
 
@@ -249,7 +246,7 @@ CommandCost RemoveTrainWaypoint(TileInde
 
		YapfNotifyTrackLayoutChange(tile, track);
 
		if (v != NULL) TryPathReserve(v, true);
 

	
 
		DeallocateSpecFromStation(wp, wp->num_specs > 0 ? 1 : 0);
 
		DeallocateSpecFromStation(wp, specindex);
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot);
 
@@ -290,7 +287,7 @@ static bool IsUniqueWaypointName(const c
 
CommandCost CmdRenameWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Waypoint *wp = Waypoint::GetIfValid(p1);
 
	if (wp == NULL || !CheckOwnership(wp->owner)) return CMD_ERROR;
 
	if (wp == NULL || !(CheckOwnership(wp->owner) || wp->owner == OWNER_NONE)) return CMD_ERROR;
 

	
 
	bool reset = StrEmpty(text);
 

	
src/waypoint_gui.cpp
Show inline comments
 
@@ -37,7 +37,7 @@ public:
 
	WaypointWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 
	{
 
		this->wp = Waypoint::Get(this->window_number);
 
		this->vt = (wp->facilities & FACIL_TRAIN) ? VEH_TRAIN : VEH_SHIP;
 
		this->vt = (wp->string_id == STR_SV_STNAME_WAYPOINT) ? VEH_TRAIN : VEH_SHIP;
 

	
 
		if (this->wp->owner != OWNER_NONE) this->owner = this->wp->owner;
 

	
src/yapf/yapf_costrail.hpp
Show inline comments
 
@@ -406,7 +406,7 @@ no_entry_cost: // jump here at the begin
 
				/* We will end in this pass (station is possible target) */
 
				end_segment_reason |= ESRB_STATION;
 

	
 
			} else if (cur.tile_type == MP_RAILWAY && IsRailWaypoint(cur.tile)) {
 
			} else if (cur.tile_type == MP_STATION && IsRailWaypoint(cur.tile)) {
 
				/* Waypoint is also a good reason to finish. */
 
				end_segment_reason |= ESRB_WAYPOINT;
 
			} else if (TrackFollower::DoTrackMasking() && cur.tile_type == MP_RAILWAY) {
src/yapf/yapf_destrail.hpp
Show inline comments
 
@@ -134,22 +134,11 @@ public:
 
				m_destTrackdirs = INVALID_TRACKDIR_BIT;
 
				break;
 

	
 
			case OT_GOTO_WAYPOINT: {
 
				Waypoint *wp = Waypoint::Get(v->current_order.GetDestination());
 
				if (wp == NULL) {
 
					/* Invalid waypoint in orders! */
 
					DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, company %d)", v->current_order.GetDestination(), v->unitnumber, (CompanyID)v->owner);
 
			case OT_GOTO_WAYPOINT:
 
				m_destTile = Waypoint::Get(v->current_order.GetDestination())->xy;
 
				m_dest_station_id = INVALID_STATION;
 
				m_destTrackdirs = IsRailWaypointTile(m_destTile) ? TrackToTrackdirBits(GetRailStationTrack(m_destTile)) : INVALID_TRACKDIR_BIT;
 
					break;
 
				}
 
				m_destTile = wp->xy;
 
				if (m_destTile != v->dest_tile) {
 
					/* Something is wrong with orders! */
 
					DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, company %d)", v->dest_tile, v->unitnumber, (CompanyID)v->owner);
 
				}
 
				m_dest_station_id = INVALID_STATION;
 
				m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
 
				break;
 
			}
 

	
 
			default:
 
				m_destTile = v->dest_tile;
0 comments (0 inline, 0 general)