src/station_cmd.cpp
changeset 10224 4f7e3408936b
parent 10222 b6919c94cc77
child 10229 fba3f9fa44d7
equal deleted inserted replaced
10223:eba00e1551eb 10224:4f7e3408936b
    68 	}
    68 	}
    69 
    69 
    70 	return false;
    70 	return false;
    71 }
    71 }
    72 
    72 
    73 RoadStop* GetRoadStopByTile(TileIndex tile, RoadStopType type)
    73 RoadStop *GetRoadStopByTile(TileIndex tile, RoadStopType type)
    74 {
    74 {
    75 	const Station* st = GetStationByTile(tile);
    75 	const Station *st = GetStationByTile(tile);
    76 
    76 
    77 	for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) {
    77 	for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) {
    78 		if (rs->xy == tile) return rs;
    78 		if (rs->xy == tile) return rs;
    79 		assert(rs->next != NULL);
    79 		assert(rs->next != NULL);
    80 	}
    80 	}
    81 }
    81 }
    82 
    82 
    83 
    83 
    84 static uint GetNumRoadStopsInStation(const Station* st, RoadStopType type)
    84 static uint GetNumRoadStopsInStation(const Station *st, RoadStopType type)
    85 {
    85 {
    86 	uint num = 0;
    86 	uint num = 0;
    87 
    87 
    88 	assert(st != NULL);
    88 	assert(st != NULL);
    89 	for (const RoadStop *rs = st->GetPrimaryRoadStop(type); rs != NULL; rs = rs->next) {
    89 	for (const RoadStop *rs = st->GetPrimaryRoadStop(type); rs != NULL; rs = rs->next) {
    97 /** Calculate the radius of the station. Basicly it is the biggest
    97 /** Calculate the radius of the station. Basicly it is the biggest
    98  *  radius that is available within the station
    98  *  radius that is available within the station
    99  * @param st Station to query
    99  * @param st Station to query
   100  * @return the so calculated radius
   100  * @return the so calculated radius
   101  */
   101  */
   102 static uint FindCatchmentRadius(const Station* st)
   102 static uint FindCatchmentRadius(const Station *st)
   103 {
   103 {
   104 	uint ret = CA_NONE;
   104 	uint ret = CA_NONE;
   105 
   105 
   106 	if (st->bus_stops   != NULL) ret = max<uint>(ret, CA_BUS);
   106 	if (st->bus_stops   != NULL) ret = max<uint>(ret, CA_BUS);
   107 	if (st->truck_stops != NULL) ret = max<uint>(ret, CA_TRUCK);
   107 	if (st->truck_stops != NULL) ret = max<uint>(ret, CA_TRUCK);
   112 	return ret;
   112 	return ret;
   113 }
   113 }
   114 
   114 
   115 #define CHECK_STATIONS_ERR ((Station*)-1)
   115 #define CHECK_STATIONS_ERR ((Station*)-1)
   116 
   116 
   117 static Station* GetStationAround(TileIndex tile, int w, int h, StationID closest_station)
   117 static Station *GetStationAround(TileIndex tile, int w, int h, StationID closest_station)
   118 {
   118 {
   119 	/* check around to see if there's any stations there */
   119 	/* check around to see if there's any stations there */
   120 	BEGIN_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
   120 	BEGIN_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
   121 		if (IsTileType(tile_cur, MP_STATION)) {
   121 		if (IsTileType(tile_cur, MP_STATION)) {
   122 			StationID t = GetStationIndex(tile_cur);
   122 			StationID t = GetStationIndex(tile_cur);
   247 		1 << M(STR_SV_STNAME_DOCKS),            /* 3 */
   247 		1 << M(STR_SV_STNAME_DOCKS),            /* 3 */
   248 		0x1FF << M(STR_SV_STNAME_BUOY_1),       /* 4 */
   248 		0x1FF << M(STR_SV_STNAME_BUOY_1),       /* 4 */
   249 		1 << M(STR_SV_STNAME_HELIPORT),         /* 5 */
   249 		1 << M(STR_SV_STNAME_HELIPORT),         /* 5 */
   250 	};
   250 	};
   251 
   251 
   252 	Town *t = st->town;
   252 	const Town *t = st->town;
   253 	uint32 free_names = (uint32)-1;
   253 	uint32 free_names = UINT32_MAX;
   254 	int found;
       
   255 	unsigned long tmp;
       
   256 
   254 
   257 	{
   255 	{
   258 		Station *s;
   256 		const Station *s;
   259 
   257 
   260 		FOR_ALL_STATIONS(s) {
   258 		FOR_ALL_STATIONS(s) {
   261 			if (s != st && s->town == t) {
   259 			if (s != st && s->town == t) {
   262 				uint str = M(s->string_id);
   260 				uint str = M(s->string_id);
   263 				if (str <= 0x20) {
   261 				if (str <= 0x20) {
   264 					if (str == M(STR_SV_STNAME_FOREST))
   262 					if (str == M(STR_SV_STNAME_FOREST)) {
   265 						str = M(STR_SV_STNAME_WOODS);
   263 						str = M(STR_SV_STNAME_WOODS);
       
   264 					}
   266 					ClrBit(free_names, str);
   265 					ClrBit(free_names, str);
   267 				}
   266 				}
   268 			}
   267 			}
   269 		}
   268 		}
   270 	}
   269 	}
   271 
   270 
   272 	/* check default names */
   271 	/* check default names */
   273 	tmp = free_names & _gen_station_name_bits[flag];
   272 	uint32 tmp = free_names & _gen_station_name_bits[flag];
       
   273 	int found;
   274 	if (tmp != 0) {
   274 	if (tmp != 0) {
   275 		found = FindFirstBit(tmp);
   275 		found = FindFirstBit(tmp);
   276 		goto done;
   276 		goto done;
   277 	}
   277 	}
   278 
   278 
   345 	st->string_id = found + STR_SV_STNAME;
   345 	st->string_id = found + STR_SV_STNAME;
   346 	return true;
   346 	return true;
   347 }
   347 }
   348 #undef M
   348 #undef M
   349 
   349 
   350 static Station* GetClosestStationFromTile(TileIndex tile)
   350 static Station *GetClosestStationFromTile(TileIndex tile)
   351 {
   351 {
   352 	uint threshold = 8;
   352 	uint threshold = 8;
   353 	Station* best_station = NULL;
   353 	Station *best_station = NULL;
   354 	Station* st;
   354 	Station *st;
   355 
   355 
   356 	FOR_ALL_STATIONS(st) {
   356 	FOR_ALL_STATIONS(st) {
   357 		if (st->facilities == 0 && st->owner == _current_player) {
   357 		if (st->facilities == 0 && st->owner == _current_player) {
   358 			uint cur_dist = DistanceManhattan(tile, st->xy);
   358 			uint cur_dist = DistanceManhattan(tile, st->xy);
   359 
   359 
   383 }
   383 }
   384 
   384 
   385 /** Update the virtual coords needed to draw the station sign for all stations. */
   385 /** Update the virtual coords needed to draw the station sign for all stations. */
   386 void UpdateAllStationVirtCoord()
   386 void UpdateAllStationVirtCoord()
   387 {
   387 {
   388 	Station* st;
   388 	Station *st;
   389 
   389 
   390 	FOR_ALL_STATIONS(st) {
   390 	FOR_ALL_STATIONS(st) {
   391 		UpdateStationVirtCoord(st);
   391 		UpdateStationVirtCoord(st);
   392 	}
   392 	}
   393 }
   393 }
   530 	uint min_y;
   530 	uint min_y;
   531 	uint max_x;
   531 	uint max_x;
   532 	uint max_y;
   532 	uint max_y;
   533 };
   533 };
   534 
   534 
   535 static inline void MergePoint(ottd_Rectangle* rect, TileIndex tile)
   535 static inline void MergePoint(ottd_Rectangle *rect, TileIndex tile)
   536 {
   536 {
   537 	uint x = TileX(tile);
   537 	uint x = TileX(tile);
   538 	uint y = TileY(tile);
   538 	uint y = TileY(tile);
   539 
   539 
   540 	if (rect->min_x > x) rect->min_x = x;
   540 	if (rect->min_x > x) rect->min_x = x;
   562 	uint old_acc = GetAcceptanceMask(st);
   562 	uint old_acc = GetAcceptanceMask(st);
   563 
   563 
   564 	/* Put all the tiles that span an area in the table. */
   564 	/* Put all the tiles that span an area in the table. */
   565 	if (st->train_tile != 0) {
   565 	if (st->train_tile != 0) {
   566 		MergePoint(&rect, st->train_tile);
   566 		MergePoint(&rect, st->train_tile);
   567 		MergePoint(&rect,
   567 		MergePoint(&rect, st->train_tile + TileDiffXY(st->trainst_w - 1, st->trainst_h - 1));
   568 			st->train_tile + TileDiffXY(st->trainst_w - 1, st->trainst_h - 1)
       
   569 		);
       
   570 	}
   568 	}
   571 
   569 
   572 	if (st->airport_tile != 0) {
   570 	if (st->airport_tile != 0) {
   573 		const AirportFTAClass* afc = st->Airport();
   571 		const AirportFTAClass *afc = st->Airport();
   574 
   572 
   575 		MergePoint(&rect, st->airport_tile);
   573 		MergePoint(&rect, st->airport_tile);
   576 		MergePoint(&rect,
   574 		MergePoint(&rect, st->airport_tile + TileDiffXY(afc->size_x - 1, afc->size_y - 1));
   577 			st->airport_tile + TileDiffXY(afc->size_x - 1, afc->size_y - 1)
       
   578 		);
       
   579 	}
   575 	}
   580 
   576 
   581 	if (st->dock_tile != 0) MergePoint(&rect, st->dock_tile);
   577 	if (st->dock_tile != 0) MergePoint(&rect, st->dock_tile);
   582 
   578 
   583 	for (const RoadStop *rs = st->bus_stops; rs != NULL; rs = rs->next) {
   579 	for (const RoadStop *rs = st->bus_stops; rs != NULL; rs = rs->next) {
   607 		uint amt = min(accepts[i], 15);
   603 		uint amt = min(accepts[i], 15);
   608 
   604 
   609 		/* Make sure the station can accept the goods type. */
   605 		/* Make sure the station can accept the goods type. */
   610 		bool is_passengers = IsCargoInClass(i, CC_PASSENGERS);
   606 		bool is_passengers = IsCargoInClass(i, CC_PASSENGERS);
   611 		if ((!is_passengers && !(st->facilities & (byte)~FACIL_BUS_STOP)) ||
   607 		if ((!is_passengers && !(st->facilities & (byte)~FACIL_BUS_STOP)) ||
   612 				(is_passengers && !(st->facilities & (byte)~FACIL_TRUCK_STOP)))
   608 				(is_passengers && !(st->facilities & (byte)~FACIL_TRUCK_STOP))) {
   613 			amt = 0;
   609 			amt = 0;
       
   610 		}
   614 
   611 
   615 		SB(st->goods[i].acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, amt >= 8);
   612 		SB(st->goods[i].acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, amt >= 8);
   616 	}
   613 	}
   617 
   614 
   618 	/* Only show a message in case the acceptance was actually changed. */
   615 	/* Only show a message in case the acceptance was actually changed. */
   619 	uint new_acc = GetAcceptanceMask(st);
   616 	uint new_acc = GetAcceptanceMask(st);
   620 	if (old_acc == new_acc)
   617 	if (old_acc == new_acc) return;
   621 		return;
       
   622 
   618 
   623 	/* show a message to report that the acceptance was changed? */
   619 	/* show a message to report that the acceptance was changed? */
   624 	if (show_msg && st->owner == _local_player && st->facilities) {
   620 	if (show_msg && st->owner == _local_player && st->facilities) {
   625 		/* List of accept and reject strings for different number of
   621 		/* List of accept and reject strings for different number of
   626 		 * cargo types */
   622 		 * cargo types */
   774 	} END_TILE_LOOP(tile_cur, w, h, tile)
   770 	} END_TILE_LOOP(tile_cur, w, h, tile)
   775 
   771 
   776 	return cost;
   772 	return cost;
   777 }
   773 }
   778 
   774 
   779 static bool CanExpandRailroadStation(const Station* st, uint* fin, Axis axis)
   775 static bool CanExpandRailroadStation(const Station *st, uint *fin, Axis axis)
   780 {
   776 {
   781 	uint curw = st->trainst_w;
   777 	uint curw = st->trainst_w;
   782 	uint curh = st->trainst_h;
   778 	uint curh = st->trainst_h;
   783 	TileIndex tile = fin[0];
   779 	TileIndex tile = fin[0];
   784 	uint w = fin[1];
   780 	uint w = fin[1];
   897  * - p2 = (bit  8-15) - custom station class
   893  * - p2 = (bit  8-15) - custom station class
   898  * - p2 = (bit 16-23) - custom station id
   894  * - p2 = (bit 16-23) - custom station id
   899  */
   895  */
   900 CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, uint32 p2)
   896 CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, uint32 p2)
   901 {
   897 {
   902 	int w_org, h_org;
       
   903 	CommandCost ret;
       
   904 
       
   905 	/* Does the authority allow this? */
   898 	/* Does the authority allow this? */
   906 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
   899 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
   907 	if (!ValParamRailtype((RailType)(p2 & 0xF))) return CMD_ERROR;
   900 	if (!ValParamRailtype((RailType)(p2 & 0xF))) return CMD_ERROR;
   908 
   901 
   909 	/* unpack parameters */
   902 	/* unpack parameters */
   910 	Axis axis = Extract<Axis, 0>(p1);
   903 	Axis axis = Extract<Axis, 0>(p1);
   911 	uint numtracks = GB(p1,  8, 8);
   904 	uint numtracks = GB(p1,  8, 8);
   912 	uint plat_len  = GB(p1, 16, 8);
   905 	uint plat_len  = GB(p1, 16, 8);
       
   906 
       
   907 	int w_org, h_org;
   913 	if (axis == AXIS_X) {
   908 	if (axis == AXIS_X) {
   914 		w_org = plat_len;
   909 		w_org = plat_len;
   915 		h_org = numtracks;
   910 		h_org = numtracks;
   916 	} else {
   911 	} else {
   917 		h_org = plat_len;
   912 		h_org = plat_len;
   929 	/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
   924 	/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
   930 	StationID est = INVALID_STATION;
   925 	StationID est = INVALID_STATION;
   931 	/* If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
   926 	/* If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
   932 	 * for detail info, see:
   927 	 * for detail info, see:
   933 	 * https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365 */
   928 	 * https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365 */
   934 	ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
   929 	CommandCost ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
   935 	if (CmdFailed(ret)) return ret;
   930 	if (CmdFailed(ret)) return ret;
   936 	CommandCost cost(EXPENSES_CONSTRUCTION, ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
   931 	CommandCost cost(EXPENSES_CONSTRUCTION, ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
   937 
   932 
   938 	Station *st = NULL;
   933 	Station *st = NULL;
   939 	bool check_surrounding = true;
   934 	bool check_surrounding = true;
  1237 
  1232 
  1238 
  1233 
  1239 static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
  1234 static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
  1240 {
  1235 {
  1241 	/* if there is flooding and non-uniform stations are enabled, remove platforms tile by tile */
  1236 	/* if there is flooding and non-uniform stations are enabled, remove platforms tile by tile */
  1242 	if (_current_player == OWNER_WATER && _patches.nonuniform_stations)
  1237 	if (_current_player == OWNER_WATER && _patches.nonuniform_stations) {
  1243 		return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAILROAD_STATION);
  1238 		return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAILROAD_STATION);
       
  1239 	}
  1244 
  1240 
  1245 	/* Current player owns the station? */
  1241 	/* Current player owns the station? */
  1246 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
  1242 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner)) return CMD_ERROR;
  1247 		return CMD_ERROR;
       
  1248 
  1243 
  1249 	/* determine width and height of platforms */
  1244 	/* determine width and height of platforms */
  1250 	tile = st->train_tile;
  1245 	tile = st->train_tile;
  1251 	int w = st->trainst_w;
  1246 	int w = st->trainst_w;
  1252 	int h = st->trainst_h;
  1247 	int h = st->trainst_h;
  1300 /**
  1295 /**
  1301  * @param truck_station Determines whether a stop is ROADSTOP_BUS or ROADSTOP_TRUCK
  1296  * @param truck_station Determines whether a stop is ROADSTOP_BUS or ROADSTOP_TRUCK
  1302  * @param st The Station to do the whole procedure for
  1297  * @param st The Station to do the whole procedure for
  1303  * @return a pointer to where to link a new RoadStop*
  1298  * @return a pointer to where to link a new RoadStop*
  1304  */
  1299  */
  1305 static RoadStop **FindRoadStopSpot(bool truck_station, Station* st)
  1300 static RoadStop **FindRoadStopSpot(bool truck_station, Station *st)
  1306 {
  1301 {
  1307 	RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops;
  1302 	RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops;
  1308 
  1303 
  1309 	if (*primary_stop == NULL) {
  1304 	if (*primary_stop == NULL) {
  1310 		/* we have no roadstop of the type yet, so write a "primary stop" */
  1305 		/* we have no roadstop of the type yet, so write a "primary stop" */
  1346 	/* Road bits in the wrong direction */
  1341 	/* Road bits in the wrong direction */
  1347 	if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
  1342 	if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
  1348 
  1343 
  1349 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
  1344 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
  1350 
  1345 
  1351 	CommandCost cost;
       
  1352 
       
  1353 	/* Not allowed to build over this road */
  1346 	/* Not allowed to build over this road */
  1354 	if (build_over_road) {
  1347 	if (build_over_road) {
  1355 		if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
  1348 		if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
  1356 
  1349 
  1357 		RoadTypes cur_rts = GetRoadTypes(tile);
  1350 		RoadTypes cur_rts = GetRoadTypes(tile);
  1372 		if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
  1365 		if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
  1373 
  1366 
  1374 		/* Do not remove roadtypes! */
  1367 		/* Do not remove roadtypes! */
  1375 		rts |= cur_rts;
  1368 		rts |= cur_rts;
  1376 	}
  1369 	}
  1377 	cost = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL, !build_over_road);
  1370 
       
  1371 	CommandCost cost = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL, !build_over_road);
  1378 	if (CmdFailed(cost)) return cost;
  1372 	if (CmdFailed(cost)) return cost;
  1379 
  1373 
  1380 	Station *st = NULL;
  1374 	Station *st = NULL;
  1381 
  1375 
  1382 	if (!_patches.adjacent_stations || !HasBit(p2, 5)) {
  1376 	if (!_patches.adjacent_stations || !HasBit(p2, 5)) {
  1668 	bool airport_upgrade = true;
  1662 	bool airport_upgrade = true;
  1669 
  1663 
  1670 	/* Check if a valid, buildable airport was chosen for construction */
  1664 	/* Check if a valid, buildable airport was chosen for construction */
  1671 	if (p1 > lengthof(_airport_sections) || !HasBit(GetValidAirports(), p1)) return CMD_ERROR;
  1665 	if (p1 > lengthof(_airport_sections) || !HasBit(GetValidAirports(), p1)) return CMD_ERROR;
  1672 
  1666 
  1673 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
  1667 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) {
  1674 		return CMD_ERROR;
  1668 		return CMD_ERROR;
  1675 
  1669 	}
  1676 	Town *t = ClosestTownFromTile(tile, (uint)-1);
  1670 
       
  1671 	Town *t = ClosestTownFromTile(tile, UINT_MAX);
  1677 
  1672 
  1678 	/* Check if local auth refuses a new airport */
  1673 	/* Check if local auth refuses a new airport */
  1679 	{
  1674 	{
  1680 		uint num = 0;
  1675 		uint num = 0;
  1681 		const Station *st;
  1676 		const Station *st;
  1682 		FOR_ALL_STATIONS(st) {
  1677 		FOR_ALL_STATIONS(st) {
  1683 			if (st->town == t && st->facilities&FACIL_AIRPORT && st->airport_type != AT_OILRIG)
  1678 			if (st->town == t && st->facilities & FACIL_AIRPORT && st->airport_type != AT_OILRIG) num++;
  1684 				num++;
       
  1685 		}
  1679 		}
  1686 		if (num >= 2) {
  1680 		if (num >= 2) {
  1687 			SetDParam(0, t->index);
  1681 			SetDParam(0, t->index);
  1688 			return_cmd_error(STR_2035_LOCAL_AUTHORITY_REFUSES);
  1682 			return_cmd_error(STR_2035_LOCAL_AUTHORITY_REFUSES);
  1689 		}
  1683 		}
  1714 	/* In case of new station if DC_EXEC is NOT set we still need to create the station
  1708 	/* In case of new station if DC_EXEC is NOT set we still need to create the station
  1715 	 * to test if everything is OK. In this case we need to delete it before return. */
  1709 	 * to test if everything is OK. In this case we need to delete it before return. */
  1716 	AutoPtrT<Station> st_auto_delete;
  1710 	AutoPtrT<Station> st_auto_delete;
  1717 
  1711 
  1718 	if (st != NULL) {
  1712 	if (st != NULL) {
  1719 		if (st->owner != _current_player)
  1713 		if (st->owner != _current_player) {
  1720 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
  1714 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
       
  1715 		}
  1721 
  1716 
  1722 		if (!st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TEST)) return CMD_ERROR;
  1717 		if (!st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TEST)) return CMD_ERROR;
  1723 
  1718 
  1724 		if (st->airport_tile != 0)
  1719 		if (st->airport_tile != 0) {
  1725 			return_cmd_error(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT);
  1720 			return_cmd_error(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT);
       
  1721 		}
  1726 	} else {
  1722 	} else {
  1727 		airport_upgrade = false;
  1723 		airport_upgrade = false;
  1728 
  1724 
  1729 		/* allocate and initialize new station */
  1725 		/* allocate and initialize new station */
  1730 		st = new Station(tile);
  1726 		st = new Station(tile);
  1788 	return cost;
  1784 	return cost;
  1789 }
  1785 }
  1790 
  1786 
  1791 static CommandCost RemoveAirport(Station *st, uint32 flags)
  1787 static CommandCost RemoveAirport(Station *st, uint32 flags)
  1792 {
  1788 {
  1793 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
  1789 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner)) {
  1794 		return CMD_ERROR;
  1790 		return CMD_ERROR;
       
  1791 	}
  1795 
  1792 
  1796 	TileIndex tile = st->airport_tile;
  1793 	TileIndex tile = st->airport_tile;
  1797 
  1794 
  1798 	const AirportFTAClass *afc = st->Airport();
  1795 	const AirportFTAClass *afc = st->Airport();
  1799 	int w = afc->size_x;
  1796 	int w = afc->size_x;
  1800 	int h = afc->size_y;
  1797 	int h = afc->size_y;
  1801 
  1798 
  1802 	CommandCost cost(EXPENSES_CONSTRUCTION, w * h * _price.remove_airport);
  1799 	CommandCost cost(EXPENSES_CONSTRUCTION, w * h * _price.remove_airport);
  1803 
  1800 
  1804 	Vehicle *v;
  1801 	const Vehicle *v;
  1805 	FOR_ALL_VEHICLES(v) {
  1802 	FOR_ALL_VEHICLES(v) {
  1806 		if (!(v->type == VEH_AIRCRAFT && IsNormalAircraft(v))) continue;
  1803 		if (!(v->type == VEH_AIRCRAFT && IsNormalAircraft(v))) continue;
  1807 
  1804 
  1808 		if (v->u.air.targetairport == st->index && v->u.air.state != FLYING) return CMD_ERROR;
  1805 		if (v->u.air.targetairport == st->index && v->u.air.state != FLYING) return CMD_ERROR;
  1809 	}
  1806 	}
  1909 }
  1906 }
  1910 
  1907 
  1911 static CommandCost RemoveBuoy(Station *st, uint32 flags)
  1908 static CommandCost RemoveBuoy(Station *st, uint32 flags)
  1912 {
  1909 {
  1913 	/* XXX: strange stuff */
  1910 	/* XXX: strange stuff */
  1914 	if (!IsValidPlayer(_current_player))  return_cmd_error(INVALID_STRING_ID);
  1911 	if (!IsValidPlayer(_current_player)) return_cmd_error(INVALID_STRING_ID);
  1915 
  1912 
  1916 	TileIndex tile = st->dock_tile;
  1913 	TileIndex tile = st->dock_tile;
  1917 
  1914 
  1918 	if (HasStationInUse(st->index, INVALID_PLAYER)) return_cmd_error(STR_BUOY_IS_IN_USE);
  1915 	if (HasStationInUse(st->index, INVALID_PLAYER)) return_cmd_error(STR_BUOY_IS_IN_USE);
  1919 	/* remove the buoy if there is a ship on tile when company goes bankrupt... */
  1916 	/* remove the buoy if there is a ship on tile when company goes bankrupt... */
  1956  * @param p1 (bit 0) - allow docks directly adjacent to other docks.
  1953  * @param p1 (bit 0) - allow docks directly adjacent to other docks.
  1957  * @param p2 unused
  1954  * @param p2 unused
  1958  */
  1955  */
  1959 CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1956 CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1960 {
  1957 {
  1961 	CommandCost cost;
       
  1962 
       
  1963 	DiagDirection direction = GetInclinedSlopeDirection(GetTileSlope(tile, NULL));
  1958 	DiagDirection direction = GetInclinedSlopeDirection(GetTileSlope(tile, NULL));
  1964 	if (direction == INVALID_DIAGDIR) return_cmd_error(STR_304B_SITE_UNSUITABLE);
  1959 	if (direction == INVALID_DIAGDIR) return_cmd_error(STR_304B_SITE_UNSUITABLE);
  1965 	direction = ReverseDiagDir(direction);
  1960 	direction = ReverseDiagDir(direction);
  1966 
  1961 
  1967 	/* Docks cannot be placed on rapids */
  1962 	/* Docks cannot be placed on rapids */
  1969 
  1964 
  1970 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
  1965 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
  1971 
  1966 
  1972 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
  1967 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
  1973 
  1968 
  1974 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  1969 	if (CmdFailed(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR))) return CMD_ERROR;
  1975 	if (CmdFailed(cost)) return CMD_ERROR;
       
  1976 
  1970 
  1977 	TileIndex tile_cur = tile + TileOffsByDiagDir(direction);
  1971 	TileIndex tile_cur = tile + TileOffsByDiagDir(direction);
  1978 
  1972 
  1979 	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
  1973 	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
  1980 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
  1974 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
  1983 	if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
  1977 	if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
  1984 
  1978 
  1985 	/* Get the water class of the water tile before it is cleared.*/
  1979 	/* Get the water class of the water tile before it is cleared.*/
  1986 	WaterClass wc = GetWaterClass(tile_cur);
  1980 	WaterClass wc = GetWaterClass(tile_cur);
  1987 
  1981 
  1988 	cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  1982 	if (CmdFailed(DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR))) return CMD_ERROR;
  1989 	if (CmdFailed(cost)) return CMD_ERROR;
       
  1990 
  1983 
  1991 	tile_cur += TileOffsByDiagDir(direction);
  1984 	tile_cur += TileOffsByDiagDir(direction);
  1992 	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
  1985 	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
  1993 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
  1986 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
  1994 	}
  1987 	}
  2009 	/* In case of new station if DC_EXEC is NOT set we still need to create the station
  2002 	/* In case of new station if DC_EXEC is NOT set we still need to create the station
  2010 	 * to test if everything is OK. In this case we need to delete it before return. */
  2003 	 * to test if everything is OK. In this case we need to delete it before return. */
  2011 	AutoPtrT<Station> st_auto_delete;
  2004 	AutoPtrT<Station> st_auto_delete;
  2012 
  2005 
  2013 	if (st != NULL) {
  2006 	if (st != NULL) {
  2014 		if (st->owner != _current_player)
  2007 		if (st->owner != _current_player) {
  2015 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
  2008 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
       
  2009 		}
  2016 
  2010 
  2017 		if (!st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TEST)) return CMD_ERROR;
  2011 		if (!st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TEST)) return CMD_ERROR;
  2018 
  2012 
  2019 		if (st->dock_tile != 0) return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
  2013 		if (st->dock_tile != 0) return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
  2020 	} else {
  2014 	} else {
  2050 		InvalidateWindow(WC_STATION_LIST, st->owner);
  2044 		InvalidateWindow(WC_STATION_LIST, st->owner);
  2051 		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
  2045 		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
  2052 		/* success, so don't delete the new station */
  2046 		/* success, so don't delete the new station */
  2053 		st_auto_delete.Detach();
  2047 		st_auto_delete.Detach();
  2054 	}
  2048 	}
       
  2049 
  2055 	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_dock);
  2050 	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_dock);
  2056 }
  2051 }
  2057 
  2052 
  2058 static CommandCost RemoveDock(Station *st, uint32 flags)
  2053 static CommandCost RemoveDock(Station *st, uint32 flags)
  2059 {
  2054 {
  2128 
  2123 
  2129 	if (IsCustomStationSpecIndex(ti->tile)) {
  2124 	if (IsCustomStationSpecIndex(ti->tile)) {
  2130 		/* look for customization */
  2125 		/* look for customization */
  2131 		st = GetStationByTile(ti->tile);
  2126 		st = GetStationByTile(ti->tile);
  2132 		statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
  2127 		statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
  2133 
       
  2134 		//debug("Cust-o-mized %p", statspec);
       
  2135 
  2128 
  2136 		if (statspec != NULL) {
  2129 		if (statspec != NULL) {
  2137 			uint tile = GetStationGfx(ti->tile);
  2130 			uint tile = GetStationGfx(ti->tile);
  2138 
  2131 
  2139 			relocation = GetCustomStationRelocation(statspec, st, ti->tile);
  2132 			relocation = GetCustomStationRelocation(statspec, st, ti->tile);
  2482 
  2475 
  2483 	if (st->facilities == 0 && ++st->delete_ctr >= 8) delete st;
  2476 	if (st->facilities == 0 && ++st->delete_ctr >= 8) delete st;
  2484 
  2477 
  2485 }
  2478 }
  2486 
  2479 
  2487 static inline void byte_inc_sat(byte *p) { byte b = *p + 1; if (b != 0) *p = b; }
  2480 static inline void byte_inc_sat(byte *p)
       
  2481 {
       
  2482 	byte b = *p + 1;
       
  2483 	if (b != 0) *p = b;
       
  2484 }
  2488 
  2485 
  2489 static void UpdateStationRating(Station *st)
  2486 static void UpdateStationRating(Station *st)
  2490 {
  2487 {
  2491 	bool waiting_changed = false;
  2488 	bool waiting_changed = false;
  2492 
  2489 
  2620 	FOR_ALL_STATIONS(st) StationHandleSmallTick(st);
  2617 	FOR_ALL_STATIONS(st) StationHandleSmallTick(st);
  2621 }
  2618 }
  2622 
  2619 
  2623 void StationMonthlyLoop()
  2620 void StationMonthlyLoop()
  2624 {
  2621 {
       
  2622 	/* not used */
  2625 }
  2623 }
  2626 
  2624 
  2627 
  2625 
  2628 void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius)
  2626 void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius)
  2629 {
  2627 {
  2631 
  2629 
  2632 	FOR_ALL_STATIONS(st) {
  2630 	FOR_ALL_STATIONS(st) {
  2633 		if (st->owner == owner &&
  2631 		if (st->owner == owner &&
  2634 				DistanceManhattan(tile, st->xy) <= radius) {
  2632 				DistanceManhattan(tile, st->xy) <= radius) {
  2635 			for (CargoID i = 0; i < NUM_CARGO; i++) {
  2633 			for (CargoID i = 0; i < NUM_CARGO; i++) {
  2636 				GoodsEntry* ge = &st->goods[i];
  2634 				GoodsEntry *ge = &st->goods[i];
  2637 
  2635 
  2638 				if (ge->acceptance_pickup != 0) {
  2636 				if (ge->acceptance_pickup != 0) {
  2639 					ge->rating = Clamp(ge->rating + amount, 0, 255);
  2637 					ge->rating = Clamp(ge->rating + amount, 0, 255);
  2640 				}
  2638 				}
  2641 			}
  2639 			}
  2692 
  2690 
  2693 	return CommandCost();
  2691 	return CommandCost();
  2694 }
  2692 }
  2695 
  2693 
  2696 /**
  2694 /**
  2697 * Find all (non-buoy) stations around an industry tile
  2695  * Find all (non-buoy) stations around an industry tile
  2698 *
  2696  *
  2699 * @param tile: Center tile to search from
  2697  * @param tile: Center tile to search from
  2700 * @param w: Width of the center
  2698  * @param w: Width of the center
  2701 * @param h: Height of the center
  2699  * @param h: Height of the center
  2702 *
  2700  *
  2703 * @return: Set of found stations
  2701  * @return: Set of found stations
  2704 */
  2702  */
  2705 StationSet FindStationsAroundIndustryTile(TileIndex tile, int w, int h)
  2703 StationSet FindStationsAroundIndustryTile(TileIndex tile, int w, int h)
  2706 {
  2704 {
  2707 	StationSet station_set;
  2705 	StationSet station_set;
  2708 
  2706 
  2709 	int w_prod; // width and height of the "producer" of the cargo
  2707 	int w_prod; // width and height of the "producer" of the cargo
  2888 	UpdateStationAcceptance(st, false);
  2886 	UpdateStationAcceptance(st, false);
  2889 }
  2887 }
  2890 
  2888 
  2891 void DeleteOilRig(TileIndex tile)
  2889 void DeleteOilRig(TileIndex tile)
  2892 {
  2890 {
  2893 	Station* st = GetStationByTile(tile);
  2891 	Station *st = GetStationByTile(tile);
  2894 
  2892 
  2895 	MakeWater(tile);
  2893 	MakeWater(tile);
  2896 
  2894 
  2897 	st->dock_tile = 0;
  2895 	st->dock_tile = 0;
  2898 	st->airport_tile = 0;
  2896 	st->airport_tile = 0;
  2905 static void ChangeTileOwner_Station(TileIndex tile, PlayerID old_player, PlayerID new_player)
  2903 static void ChangeTileOwner_Station(TileIndex tile, PlayerID old_player, PlayerID new_player)
  2906 {
  2904 {
  2907 	if (!IsTileOwner(tile, old_player)) return;
  2905 	if (!IsTileOwner(tile, old_player)) return;
  2908 
  2906 
  2909 	if (new_player != PLAYER_SPECTATOR) {
  2907 	if (new_player != PLAYER_SPECTATOR) {
  2910 		Station* st = GetStationByTile(tile);
  2908 		Station *st = GetStationByTile(tile);
  2911 
  2909 
  2912 		SetTileOwner(tile, new_player);
  2910 		SetTileOwner(tile, new_player);
  2913 		if (!IsBuoy(tile)) st->owner = new_player; // do not set st->owner for buoys
  2911 		if (!IsBuoy(tile)) st->owner = new_player; // do not set st->owner for buoys
  2914 		RebuildStationLists();
  2912 		RebuildStationLists();
  2915 		InvalidateWindowClasses(WC_STATION_LIST);
  2913 		InvalidateWindowClasses(WC_STATION_LIST);
  2993 	/* Clean the roadstop pool and create 1 block in it */
  2991 	/* Clean the roadstop pool and create 1 block in it */
  2994 	_RoadStop_pool.CleanPool();
  2992 	_RoadStop_pool.CleanPool();
  2995 	_RoadStop_pool.AddBlockToPool();
  2993 	_RoadStop_pool.AddBlockToPool();
  2996 
  2994 
  2997 	_station_tick_ctr = 0;
  2995 	_station_tick_ctr = 0;
  2998 
       
  2999 }
  2996 }
  3000 
  2997 
  3001 
  2998 
  3002 void AfterLoadStations()
  2999 void AfterLoadStations()
  3003 {
  3000 {
  3086 };
  3083 };
  3087 
  3084 
  3088 static const SaveLoad _station_desc[] = {
  3085 static const SaveLoad _station_desc[] = {
  3089 	SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3086 	SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3090 	SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
  3087 	SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
  3091 	SLE_CONDNULL(4, 0, 5), // bus/lorry tile
  3088 	SLE_CONDNULL(4, 0, 5),  ///< bus/lorry tile
  3092 	SLE_CONDVAR(Station, train_tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3089 	SLE_CONDVAR(Station, train_tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3093 	SLE_CONDVAR(Station, train_tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
  3090 	SLE_CONDVAR(Station, train_tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
  3094 	SLE_CONDVAR(Station, airport_tile,               SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3091 	SLE_CONDVAR(Station, airport_tile,               SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3095 	SLE_CONDVAR(Station, airport_tile,               SLE_UINT32,                  6, SL_MAX_VERSION),
  3092 	SLE_CONDVAR(Station, airport_tile,               SLE_UINT32,                  6, SL_MAX_VERSION),
  3096 	SLE_CONDVAR(Station, dock_tile,                  SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3093 	SLE_CONDVAR(Station, dock_tile,                  SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  3097 	SLE_CONDVAR(Station, dock_tile,                  SLE_UINT32,                  6, SL_MAX_VERSION),
  3094 	SLE_CONDVAR(Station, dock_tile,                  SLE_UINT32,                  6, SL_MAX_VERSION),
  3098 	    SLE_REF(Station, town,                       REF_TOWN),
  3095 	    SLE_REF(Station, town,                       REF_TOWN),
  3099 	    SLE_VAR(Station, trainst_w,                  SLE_UINT8),
  3096 	    SLE_VAR(Station, trainst_w,                  SLE_UINT8),
  3100 	SLE_CONDVAR(Station, trainst_h,                  SLE_UINT8,                   2, SL_MAX_VERSION),
  3097 	SLE_CONDVAR(Station, trainst_h,                  SLE_UINT8,                   2, SL_MAX_VERSION),
  3101 
  3098 
  3102 	/* alpha_order was stored here in savegame format 0 - 3 */
  3099 	SLE_CONDNULL(1, 0, 3),  ///< alpha_order
  3103 	SLE_CONDNULL(1, 0, 3),
       
  3104 
  3100 
  3105 	    SLE_VAR(Station, string_id,                  SLE_STRINGID),
  3101 	    SLE_VAR(Station, string_id,                  SLE_STRINGID),
  3106 	SLE_CONDSTR(Station, name,                       SLE_STR, 0,                 84, SL_MAX_VERSION),
  3102 	SLE_CONDSTR(Station, name,                       SLE_STR, 0,                 84, SL_MAX_VERSION),
  3107 	    SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT16),
  3103 	    SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT16),
  3108 
  3104 
  3111 	    SLE_VAR(Station, delete_ctr,                 SLE_UINT8),
  3107 	    SLE_VAR(Station, delete_ctr,                 SLE_UINT8),
  3112 	    SLE_VAR(Station, owner,                      SLE_UINT8),
  3108 	    SLE_VAR(Station, owner,                      SLE_UINT8),
  3113 	    SLE_VAR(Station, facilities,                 SLE_UINT8),
  3109 	    SLE_VAR(Station, facilities,                 SLE_UINT8),
  3114 	    SLE_VAR(Station, airport_type,               SLE_UINT8),
  3110 	    SLE_VAR(Station, airport_type,               SLE_UINT8),
  3115 
  3111 
  3116 	SLE_CONDNULL(2, 0, 5), // Truck/bus stop status
  3112 	SLE_CONDNULL(2, 0, 5),  ///< Truck/bus stop status
  3117 	SLE_CONDNULL(1, 0, 4), // Blocked months
  3113 	SLE_CONDNULL(1, 0, 4),  ///< Blocked months
  3118 
  3114 
  3119 	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U16,  0,  2),
  3115 	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U16,  0,  2),
  3120 	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U32,  3, 45),
  3116 	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U32,  3, 45),
  3121 	SLE_CONDVAR(Station, airport_flags,              SLE_UINT64,                 46, SL_MAX_VERSION),
  3117 	SLE_CONDVAR(Station, airport_flags,              SLE_UINT64,                 46, SL_MAX_VERSION),
  3122 
  3118 
  3123 	SLE_CONDNULL(2, 0, 25), /* Ex last-vehicle */
  3119 	SLE_CONDNULL(2, 0, 25), ///< last-vehicle
  3124 	SLE_CONDVAR(Station, last_vehicle_type,          SLE_UINT8,                  26, SL_MAX_VERSION),
  3120 	SLE_CONDVAR(Station, last_vehicle_type,          SLE_UINT8,                  26, SL_MAX_VERSION),
  3125 
  3121 
  3126 	/* Was custom station class and id */
  3122 	SLE_CONDNULL(2, 3, 25), ///< custom station class and id
  3127 	SLE_CONDNULL(2, 3, 25),
       
  3128 	SLE_CONDVAR(Station, build_date,                 SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
  3123 	SLE_CONDVAR(Station, build_date,                 SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
  3129 	SLE_CONDVAR(Station, build_date,                 SLE_INT32,                  31, SL_MAX_VERSION),
  3124 	SLE_CONDVAR(Station, build_date,                 SLE_INT32,                  31, SL_MAX_VERSION),
  3130 
  3125 
  3131 	SLE_CONDREF(Station, bus_stops,                  REF_ROADSTOPS,               6, SL_MAX_VERSION),
  3126 	SLE_CONDREF(Station, bus_stops,                  REF_ROADSTOPS,               6, SL_MAX_VERSION),
  3132 	SLE_CONDREF(Station, truck_stops,                REF_ROADSTOPS,               6, SL_MAX_VERSION),
  3127 	SLE_CONDREF(Station, truck_stops,                REF_ROADSTOPS,               6, SL_MAX_VERSION),