station_cmd.c
changeset 2639 eeaefdabfdfd
parent 2631 2ed0eb408229
child 2640 86da958243fd
equal deleted inserted replaced
2638:0811adaec525 2639:eeaefdabfdfd
    42  */
    42  */
    43 static void StationPoolNewBlock(uint start_item)
    43 static void StationPoolNewBlock(uint start_item)
    44 {
    44 {
    45 	Station *st;
    45 	Station *st;
    46 
    46 
    47 	FOR_ALL_STATIONS_FROM(st, start_item)
    47 	FOR_ALL_STATIONS_FROM(st, start_item) st->index = start_item++;
    48 		st->index = start_item++;
       
    49 }
    48 }
    50 
    49 
    51 /**
    50 /**
    52  * Called if a new block is added to the roadstop-pool
    51  * Called if a new block is added to the roadstop-pool
    53  */
    52  */
    54 static void RoadStopPoolNewBlock(uint start_item)
    53 static void RoadStopPoolNewBlock(uint start_item)
    55 {
    54 {
    56 	RoadStop *rs;
    55 	RoadStop *rs;
    57 
    56 
    58 	FOR_ALL_ROADSTOPS_FROM(rs, start_item)
    57 	FOR_ALL_ROADSTOPS_FROM(rs, start_item) rs->index = start_item++;
    59 		rs->index = start_item++;
       
    60 }
    58 }
    61 
    59 
    62 /* Initialize the station-pool and roadstop-pool */
    60 /* Initialize the station-pool and roadstop-pool */
    63 MemoryPool _station_pool = { "Stations", STATION_POOL_MAX_BLOCKS, STATION_POOL_BLOCK_SIZE_BITS, sizeof(Station), &StationPoolNewBlock, 0, 0, NULL };
    61 MemoryPool _station_pool = { "Stations", STATION_POOL_MAX_BLOCKS, STATION_POOL_BLOCK_SIZE_BITS, sizeof(Station), &StationPoolNewBlock, 0, 0, NULL };
    64 MemoryPool _roadstop_pool = { "RoadStop", ROADSTOP_POOL_MAX_BLOCKS, ROADSTOP_POOL_BLOCK_SIZE_BITS, sizeof(RoadStop), &RoadStopPoolNewBlock, 0, 0, NULL };
    62 MemoryPool _roadstop_pool = { "RoadStop", ROADSTOP_POOL_MAX_BLOCKS, ROADSTOP_POOL_BLOCK_SIZE_BITS, sizeof(RoadStop), &RoadStopPoolNewBlock, 0, 0, NULL };
    94 	road_stop->next = NULL;
    92 	road_stop->next = NULL;
    95 	road_stop->prev = previous;
    93 	road_stop->prev = previous;
    96 	road_stop->station = index;
    94 	road_stop->station = index;
    97 }
    95 }
    98 
    96 
    99 RoadStop * GetPrimaryRoadStop(const Station *st, RoadStopType type)
    97 RoadStop* GetPrimaryRoadStop(const Station* st, RoadStopType type)
   100 {
    98 {
   101 	switch (type) {
    99 	switch (type) {
   102 		case RS_BUS:   return st->bus_stops;
   100 		case RS_BUS:   return st->bus_stops;
   103 		case RS_TRUCK: return st->truck_stops;
   101 		case RS_TRUCK: return st->truck_stops;
   104 		default: NOT_REACHED();
   102 		default: NOT_REACHED();
   105 	}
   103 	}
   106 
   104 
   107 	return NULL;
   105 	return NULL;
   108 }
   106 }
   109 
   107 
   110 RoadStop * GetRoadStopByTile(TileIndex tile, RoadStopType type)
   108 RoadStop* GetRoadStopByTile(TileIndex tile, RoadStopType type)
   111 {
   109 {
   112 	const Station *st = GetStation(_m[tile].m2);
   110 	const Station* st = GetStation(_m[tile].m2);
   113 	RoadStop *rs;
   111 	RoadStop* rs;
   114 
   112 
   115 	for ( rs = GetPrimaryRoadStop(st, type); rs->xy != tile; rs = rs->next)
   113 	for (rs = GetPrimaryRoadStop(st, type); rs->xy != tile; rs = rs->next) {
   116 		assert(rs->next != NULL);
   114 		assert(rs->next != NULL);
       
   115 	}
   117 
   116 
   118 	return rs;
   117 	return rs;
   119 }
   118 }
   120 
   119 
   121 uint GetNumRoadStops(const Station *st, RoadStopType type)
   120 uint GetNumRoadStops(const Station *st, RoadStopType type)
   143 			return rs;
   142 			return rs;
   144 		}
   143 		}
   145 	}
   144 	}
   146 
   145 
   147 	/* Check if we can add a block to the pool */
   146 	/* Check if we can add a block to the pool */
   148 	if (AddBlockToPool(&_roadstop_pool))
   147 	if (AddBlockToPool(&_roadstop_pool)) return AllocateRoadStop();
   149 		return AllocateRoadStop();
       
   150 
   148 
   151 	return NULL;
   149 	return NULL;
   152 }
   150 }
   153 
   151 
   154 /* Calculate the radius of the station. Basicly it is the biggest
   152 /* Calculate the radius of the station. Basicly it is the biggest
   264 			return st;
   262 			return st;
   265 		}
   263 		}
   266 	}
   264 	}
   267 
   265 
   268 	/* Check if we can add a block to the pool */
   266 	/* Check if we can add a block to the pool */
   269 	if (AddBlockToPool(&_station_pool))
   267 	if (AddBlockToPool(&_station_pool)) return AllocateStation();
   270 		return AllocateStation();
       
   271 
   268 
   272 	_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
   269 	_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
   273 	return NULL;
   270 	return NULL;
   274 }
   271 }
   275 
   272 
   478 }
   475 }
   479 
   476 
   480 // Update the virtual coords needed to draw the station sign for all stations.
   477 // Update the virtual coords needed to draw the station sign for all stations.
   481 void UpdateAllStationVirtCoord(void)
   478 void UpdateAllStationVirtCoord(void)
   482 {
   479 {
   483 	Station *st;
   480 	Station* st;
       
   481 
   484 	FOR_ALL_STATIONS(st) {
   482 	FOR_ALL_STATIONS(st) {
   485 		if (st->xy != 0)
   483 		if (st->xy != 0) UpdateStationVirtCoord(st);
   486 			UpdateStationVirtCoord(st);
       
   487 	}
   484 	}
   488 }
   485 }
   489 
   486 
   490 // Update the station virt coords while making the modified parts dirty.
   487 // Update the station virt coords while making the modified parts dirty.
   491 static void UpdateStationVirtCoordDirty(Station *st)
   488 static void UpdateStationVirtCoordDirty(Station *st)
   600 			if (!IsTileType(tile, MP_STATION)) {
   597 			if (!IsTileType(tile, MP_STATION)) {
   601 				AcceptedCargo ac;
   598 				AcceptedCargo ac;
   602 				uint i;
   599 				uint i;
   603 
   600 
   604 				GetAcceptedCargo(tile, ac);
   601 				GetAcceptedCargo(tile, ac);
   605 				for (i = 0; i < lengthof(ac); ++i)
   602 				for (i = 0; i < lengthof(ac); ++i) accepts[i] += ac[i];
   606 					accepts[i] += ac[i];
       
   607 			}
   603 			}
   608 		}
   604 		}
   609 	}
   605 	}
   610 }
   606 }
   611 
   607 
   640 
   636 
   641 	rect.min_x = MapSizeX();
   637 	rect.min_x = MapSizeX();
   642 	rect.min_y = MapSizeY();
   638 	rect.min_y = MapSizeY();
   643 	rect.max_x = rect.max_y = 0;
   639 	rect.max_x = rect.max_y = 0;
   644 	// Don't update acceptance for a buoy
   640 	// Don't update acceptance for a buoy
   645 	if (IsBuoy(st))
   641 	if (IsBuoy(st)) return;
   646 		return;
       
   647 
   642 
   648 	/* old accepted goods types */
   643 	/* old accepted goods types */
   649 	old_acc = GetAcceptanceMask(st);
   644 	old_acc = GetAcceptanceMask(st);
   650 
   645 
   651 	// Put all the tiles that span an area in the table.
   646 	// Put all the tiles that span an area in the table.
   730 }
   725 }
   731 
   726 
   732 // This is called right after a station was deleted.
   727 // This is called right after a station was deleted.
   733 // It checks if the whole station is free of substations, and if so, the station will be
   728 // It checks if the whole station is free of substations, and if so, the station will be
   734 // deleted after a little while.
   729 // deleted after a little while.
   735 static void DeleteStationIfEmpty(Station *st) {
   730 static void DeleteStationIfEmpty(Station* st)
       
   731 {
   736 	if (st->facilities == 0) {
   732 	if (st->facilities == 0) {
   737 		st->delete_ctr = 0;
   733 		st->delete_ctr = 0;
   738 		InvalidateWindow(WC_STATION_LIST, st->owner);
   734 		InvalidateWindow(WC_STATION_LIST, st->owner);
   739 	}
   735 	}
   740 }
   736 }
   751 	uint z;
   747 	uint z;
   752 	int allowed_z = -1;
   748 	int allowed_z = -1;
   753 	int flat_z;
   749 	int flat_z;
   754 
   750 
   755 	BEGIN_TILE_LOOP(tile_cur, w, h, tile)
   751 	BEGIN_TILE_LOOP(tile_cur, w, h, tile)
   756 		if (!EnsureNoVehicle(tile_cur))
   752 		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
   757 			return CMD_ERROR;
       
   758 
   753 
   759 		tileh = GetTileSlope(tile_cur, &z);
   754 		tileh = GetTileSlope(tile_cur, &z);
   760 
   755 
   761 		/* Prohibit building if
   756 		/* Prohibit building if
   762 			1) The tile is "steep" (i.e. stretches two height levels)
   757 			1) The tile is "steep" (i.e. stretches two height levels)
   765 				a) the player building is an "old-school" AI
   760 				a) the player building is an "old-school" AI
   766 				-OR-
   761 				-OR-
   767 				b) the build_on_slopes switch is disabled
   762 				b) the build_on_slopes switch is disabled
   768 		*/
   763 		*/
   769 		if (IsSteepTileh(tileh) ||
   764 		if (IsSteepTileh(tileh) ||
   770 			((_is_old_ai_player || !_patches.build_on_slopes)
   765 				((_is_old_ai_player || !_patches.build_on_slopes) && tileh != 0)) {
   771 			&& tileh != 0)) {
       
   772 
       
   773 			_error_message = STR_0007_FLAT_LAND_REQUIRED;
   766 			_error_message = STR_0007_FLAT_LAND_REQUIRED;
   774 			return CMD_ERROR;
   767 			return CMD_ERROR;
   775 		}
   768 		}
   776 
   769 
   777 		flat_z = z;
   770 		flat_z = z;
   895 		layout[n-1-n] = 0;
   888 		layout[n-1-n] = 0;
   896 	}
   889 	}
   897 	return layout;
   890 	return layout;
   898 }
   891 }
   899 
   892 
   900 // stolen from TTDPatch
       
   901 static void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *spec)
   893 static void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *spec)
   902 {
   894 {
   903 	if (spec != NULL && spec->lengths >= plat_len &&
   895 	if (spec != NULL && spec->lengths >= plat_len &&
   904 			spec->platforms[plat_len - 1] >= numtracks &&
   896 			spec->platforms[plat_len - 1] >= numtracks &&
   905 			spec->layouts[plat_len - 1][numtracks - 1]) {
   897 			spec->layouts[plat_len - 1][numtracks - 1]) {
   910 	}
   902 	}
   911 
   903 
   912 	if (plat_len == 1) {
   904 	if (plat_len == 1) {
   913 		CreateSingle(layout, numtracks);
   905 		CreateSingle(layout, numtracks);
   914 	} else {
   906 	} else {
   915 		if (numtracks & 1)
   907 		if (numtracks & 1) layout = CreateSingle(layout, plat_len);
   916 			layout = CreateSingle(layout, plat_len);
   908 		numtracks >>= 1;
   917 		numtracks>>=1;
       
   918 
   909 
   919 		while (--numtracks >= 0) {
   910 		while (--numtracks >= 0) {
   920 			layout = CreateMulti(layout, plat_len, 4);
   911 			layout = CreateMulti(layout, plat_len, 4);
   921 			layout = CreateMulti(layout, plat_len, 6);
   912 			layout = CreateMulti(layout, plat_len, 6);
   922 		}
   913 		}
  1002 			if (!CanExpandRailroadStation(st, finalvalues, direction))
   993 			if (!CanExpandRailroadStation(st, finalvalues, direction))
  1003 				return CMD_ERROR;
   994 				return CMD_ERROR;
  1004 		}
   995 		}
  1005 
   996 
  1006 		//XXX can't we pack this in the "else" part of the if above?
   997 		//XXX can't we pack this in the "else" part of the if above?
  1007 		if (!CheckStationSpreadOut(st, tile_org, w_org, h_org))
   998 		if (!CheckStationSpreadOut(st, tile_org, w_org, h_org)) return CMD_ERROR;
  1008 			return CMD_ERROR;
       
  1009 
       
  1010 	}	else {
   999 	}	else {
  1011 		// Create a new station
  1000 		// Create a new station
  1012 		st = AllocateStation();
  1001 		st = AllocateStation();
  1013 		if (st == NULL)
  1002 		if (st == NULL) return CMD_ERROR;
  1014 			return CMD_ERROR;
       
  1015 
  1003 
  1016 		st->town = ClosestTownFromTile(tile_org, (uint)-1);
  1004 		st->town = ClosestTownFromTile(tile_org, (uint)-1);
  1017 		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
  1005 		if (_current_player < MAX_PLAYERS && flags & DC_EXEC)
  1018 			SETBIT(st->town->have_ratings, _current_player);
  1006 			SETBIT(st->town->have_ratings, _current_player);
  1019 
  1007 
  1020 		if (!GenerateStationName(st, tile_org, 0))
  1008 		if (!GenerateStationName(st, tile_org, 0)) return CMD_ERROR;
  1021 			return CMD_ERROR;
  1009 
  1022 
  1010 		if (flags & DC_EXEC) StationInitialize(st, tile_org);
  1023 		if (flags & DC_EXEC)
       
  1024 			StationInitialize(st, tile_org);
       
  1025 	}
  1011 	}
  1026 
  1012 
  1027 	if (flags & DC_EXEC) {
  1013 	if (flags & DC_EXEC) {
  1028 		TileIndexDiff tile_delta;
  1014 		TileIndexDiff tile_delta;
  1029 		byte *layout_ptr;
  1015 		byte *layout_ptr;
  1174 uint GetStationPlatforms(const Station *st, TileIndex tile)
  1160 uint GetStationPlatforms(const Station *st, TileIndex tile)
  1175 {
  1161 {
  1176 	TileIndex t;
  1162 	TileIndex t;
  1177 	TileIndexDiff delta;
  1163 	TileIndexDiff delta;
  1178 	int dir;
  1164 	int dir;
  1179 	int len;
  1165 	uint len;
  1180 	assert(TileBelongsToRailStation(st, tile));
  1166 	assert(TileBelongsToRailStation(st, tile));
  1181 
  1167 
  1182 	len = 0;
  1168 	len = 0;
  1183 	dir = _m[tile].m5&1;
  1169 	dir = _m[tile].m5 & 1;
  1184 	delta = dir ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
  1170 	delta = dir ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
  1185 
  1171 
  1186 	// find starting tile..
  1172 	// find starting tile..
  1187 	t = tile;
  1173 	t = tile;
  1188 	do { t -= delta; len++; } while (TileBelongsToRailStation(st, t) && (_m[t].m5&1) == dir);
  1174 	do {
       
  1175 		t -= delta;
       
  1176 		len++;
       
  1177 	} while (TileBelongsToRailStation(st, t) && (_m[t].m5 & 1) == dir);
  1189 
  1178 
  1190 	// find ending tile
  1179 	// find ending tile
  1191 	t = tile;
  1180 	t = tile;
  1192 	do { t += delta; len++; }while (TileBelongsToRailStation(st, t) && (_m[t].m5&1) == dir);
  1181 	do {
       
  1182 		t += delta;
       
  1183 		len++;
       
  1184 	} while (TileBelongsToRailStation(st, t) && (_m[t].m5 & 1) == dir);
  1193 
  1185 
  1194 	return len - 1;
  1186 	return len - 1;
  1195 }
  1187 }
  1196 
  1188 
  1197 static const RealSpriteGroup *ResolveStationSpriteGroup(const SpriteGroup *spg, const Station *st)
  1189 static const RealSpriteGroup *ResolveStationSpriteGroup(const SpriteGroup *spg, const Station *st)
  1394 
  1386 
  1395 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
  1387 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
  1396 		return CMD_ERROR;
  1388 		return CMD_ERROR;
  1397 
  1389 
  1398 	cost = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL);
  1390 	cost = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL);
  1399 	if (cost == CMD_ERROR)
  1391 	if (cost == CMD_ERROR) return CMD_ERROR;
  1400 		return CMD_ERROR;
       
  1401 
  1392 
  1402 	st = GetStationAround(tile, 1, 1, -1);
  1393 	st = GetStationAround(tile, 1, 1, -1);
  1403 	if (st == CHECK_STATIONS_ERR)
  1394 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
  1404 		return CMD_ERROR;
       
  1405 
  1395 
  1406 	/* Find a station close to us */
  1396 	/* Find a station close to us */
  1407 	if (st == NULL) {
  1397 	if (st == NULL) {
  1408 		st = GetClosestStationFromTile(tile, 8, _current_player);
  1398 		st = GetClosestStationFromTile(tile, 8, _current_player);
  1409 		if (st!=NULL && st->facilities) st = NULL;
  1399 		if (st != NULL && st->facilities) st = NULL;
  1410 	}
  1400 	}
  1411 
  1401 
  1412 	//give us a road stop in the list, and check if something went wrong
  1402 	//give us a road stop in the list, and check if something went wrong
  1413 	road_stop = AllocateRoadStop();
  1403 	road_stop = AllocateRoadStop();
  1414 	if (road_stop == NULL)
  1404 	if (road_stop == NULL)
  1427 		FindRoadStationSpot(type, st, &currstop, &prev);
  1417 		FindRoadStationSpot(type, st, &currstop, &prev);
  1428 	} else {
  1418 	} else {
  1429 		Town *t;
  1419 		Town *t;
  1430 
  1420 
  1431 		st = AllocateStation();
  1421 		st = AllocateStation();
  1432 		if (st == NULL)
  1422 		if (st == NULL) return CMD_ERROR;
  1433 			return CMD_ERROR;
       
  1434 
  1423 
  1435 		st->town = t = ClosestTownFromTile(tile, (uint)-1);
  1424 		st->town = t = ClosestTownFromTile(tile, (uint)-1);
  1436 
  1425 
  1437 		FindRoadStationSpot(type, st, &currstop, &prev);
  1426 		FindRoadStationSpot(type, st, &currstop, &prev);
  1438 
  1427 
  1439 		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
  1428 		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
  1440 			SETBIT(t->have_ratings, _current_player);
  1429 			SETBIT(t->have_ratings, _current_player);
  1441 
  1430 
  1442 		st->sign.width_1 = 0;
  1431 		st->sign.width_1 = 0;
  1443 
  1432 
  1444 		if (!GenerateStationName(st, tile, 0))
  1433 		if (!GenerateStationName(st, tile, 0)) return CMD_ERROR;
  1445 			return CMD_ERROR;
  1434 
  1446 
  1435 		if (flags & DC_EXEC) StationInitialize(st, tile);
  1447 		if (flags & DC_EXEC)
       
  1448 			StationInitialize(st, tile);
       
  1449 	}
  1436 	}
  1450 
  1437 
  1451 	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
  1438 	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
  1452 
  1439 
  1453 	if (flags & DC_EXEC) {
  1440 	if (flags & DC_EXEC) {
  1487 	bool is_truck = _m[tile].m5 < 0x47;
  1474 	bool is_truck = _m[tile].m5 < 0x47;
  1488 
  1475 
  1489 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
  1476 	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
  1490 		return CMD_ERROR;
  1477 		return CMD_ERROR;
  1491 
  1478 
  1492 	if (is_truck) {	//truck stop
  1479 	if (is_truck) { // truck stop
  1493 		primary_stop = &st->truck_stops;
  1480 		primary_stop = &st->truck_stops;
  1494 		cur_stop = GetRoadStopByTile(tile, RS_TRUCK);
  1481 		cur_stop = GetRoadStopByTile(tile, RS_TRUCK);
  1495 	} else {
  1482 	} else {
  1496 		primary_stop = &st->bus_stops;
  1483 		primary_stop = &st->bus_stops;
  1497 		cur_stop = GetRoadStopByTile(tile, RS_BUS);
  1484 		cur_stop = GetRoadStopByTile(tile, RS_BUS);
  1501 
  1488 
  1502 	if (!EnsureNoVehicle(tile))
  1489 	if (!EnsureNoVehicle(tile))
  1503 		return CMD_ERROR;
  1490 		return CMD_ERROR;
  1504 
  1491 
  1505 	if (flags & DC_EXEC) {
  1492 	if (flags & DC_EXEC) {
  1506 		int i;
  1493 		uint i;
  1507 		DoClearSquare(tile);
  1494 		DoClearSquare(tile);
  1508 
  1495 
  1509 		/* Clear all vehicles destined for this station */
  1496 		/* Clear all vehicles destined for this station */
  1510 		for (i = 0; i != NUM_SLOTS; i++) {
  1497 		for (i = 0; i != NUM_SLOTS; i++) {
  1511 			if (cur_stop->slot[i] != INVALID_SLOT) {
  1498 			if (cur_stop->slot[i] != INVALID_SLOT) {
  1513 				ClearSlot(v, v->u.road.slot);
  1500 				ClearSlot(v, v->u.road.slot);
  1514 			}
  1501 			}
  1515 		}
  1502 		}
  1516 
  1503 
  1517 		cur_stop->used = false;
  1504 		cur_stop->used = false;
  1518 		if (cur_stop->prev != NULL)	//alter previous stop
  1505 		if (cur_stop->prev != NULL) cur_stop->prev->next = cur_stop->next;
  1519 			cur_stop->prev->next = cur_stop->next;
  1506 		if (cur_stop->next != NULL) cur_stop->next->prev = cur_stop->prev;
  1520 
       
  1521 		if (cur_stop->next != NULL)	//alter next stop
       
  1522 			cur_stop->next->prev = cur_stop->prev;
       
  1523 
  1507 
  1524 		//we only had one stop left
  1508 		//we only had one stop left
  1525 		if (cur_stop->next == NULL && cur_stop->prev == NULL) {
  1509 		if (cur_stop->next == NULL && cur_stop->prev == NULL) {
  1526 
       
  1527 			//so we remove ALL stops
  1510 			//so we remove ALL stops
  1528 			*primary_stop = NULL;
  1511 			*primary_stop = NULL;
  1529 			st->facilities &= (is_truck) ? ~FACIL_TRUCK_STOP : ~FACIL_BUS_STOP;
  1512 			st->facilities &= (is_truck) ? ~FACIL_TRUCK_STOP : ~FACIL_BUS_STOP;
  1530 
       
  1531 		} else if (cur_stop == *primary_stop) {
  1513 		} else if (cur_stop == *primary_stop) {
  1532 			//removed the first stop in the list
  1514 			//removed the first stop in the list
  1533 			//need to set the primary element to the next stop
  1515 			//need to set the primary element to the next stop
  1534 			*primary_stop = (*primary_stop)->next;
  1516 			*primary_stop = (*primary_stop)->next;
  1535 		}
  1517 		}
  1664 		st = AllocateStation();
  1646 		st = AllocateStation();
  1665 		if (st == NULL) return CMD_ERROR;
  1647 		if (st == NULL) return CMD_ERROR;
  1666 
  1648 
  1667 		st->town = t;
  1649 		st->town = t;
  1668 
  1650 
  1669 		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
  1651 		if (_current_player < MAX_PLAYERS && flags & DC_EXEC)
  1670 			SETBIT(t->have_ratings, _current_player);
  1652 			SETBIT(t->have_ratings, _current_player);
  1671 
  1653 
  1672 		st->sign.width_1 = 0;
  1654 		st->sign.width_1 = 0;
  1673 
  1655 
  1674 		// if airport type equals Heliport then generate
  1656 		// if airport type equals Heliport then generate
  1695 		st->airport_type = (byte)p1;
  1677 		st->airport_type = (byte)p1;
  1696 		st->airport_flags = 0;
  1678 		st->airport_flags = 0;
  1697 
  1679 
  1698 		st->build_date = _date;
  1680 		st->build_date = _date;
  1699 
  1681 
  1700 		/*	if airport was demolished while planes were en-route to it, the positions can no longer
  1682 		/* if airport was demolished while planes were en-route to it, the
  1701 				be the same (v->u.air.pos), since different airports have different indexes. So update
  1683 		 * positions can no longer be the same (v->u.air.pos), since different
  1702 				all planes en-route to this airport. Only update if
  1684 		 * airports have different indexes. So update all planes en-route to this
  1703 				1. airport is upgraded
  1685 		 * airport. Only update if
  1704 				2. airport is added to existing station (unfortunately unavoideable)
  1686 		 * 1. airport is upgraded
  1705 		*/
  1687 		 * 2. airport is added to existing station (unfortunately unavoideable)
       
  1688 		 */
  1706 		if (airport_upgrade) UpdateAirplanesOnNewStation(st);
  1689 		if (airport_upgrade) UpdateAirplanesOnNewStation(st);
  1707 
  1690 
  1708 		{
  1691 		{
  1709 			const byte *b = _airport_map5_tiles[p1];
  1692 			const byte *b = _airport_map5_tiles[p1];
  1710 
  1693 
  1848 		return_cmd_error(INVALID_STRING_ID);
  1831 		return_cmd_error(INVALID_STRING_ID);
  1849 	}
  1832 	}
  1850 
  1833 
  1851 	tile = st->dock_tile;
  1834 	tile = st->dock_tile;
  1852 
  1835 
  1853 	if (CheckShipsOnBuoy(st))
  1836 	if (CheckShipsOnBuoy(st))   return_cmd_error(STR_BUOY_IS_IN_USE);
  1854 		return_cmd_error(STR_BUOY_IS_IN_USE);
  1837 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
  1855 
       
  1856 	if (!EnsureNoVehicle(tile))
       
  1857 		return CMD_ERROR;
       
  1858 
  1838 
  1859 	if (flags & DC_EXEC) {
  1839 	if (flags & DC_EXEC) {
  1860 		st->dock_tile = 0;
  1840 		st->dock_tile = 0;
  1861 		/* Buoys are marked in the Station struct by this flag. Yes, it is this
  1841 		/* Buoys are marked in the Station struct by this flag. Yes, it is this
  1862 		 * braindead.. */
  1842 		 * braindead.. */
  1961 
  1941 
  1962 		st->sign.width_1 = 0;
  1942 		st->sign.width_1 = 0;
  1963 
  1943 
  1964 		if (!GenerateStationName(st, tile, 3)) return CMD_ERROR;
  1944 		if (!GenerateStationName(st, tile, 3)) return CMD_ERROR;
  1965 
  1945 
  1966 		if (flags & DC_EXEC)
  1946 		if (flags & DC_EXEC) StationInitialize(st, tile);
  1967 			StationInitialize(st, tile);
       
  1968 	}
  1947 	}
  1969 
  1948 
  1970 	if (flags & DC_EXEC) {
  1949 	if (flags & DC_EXEC) {
  1971 		st->dock_tile = tile;
  1950 		st->dock_tile = tile;
  1972 		if (!st->facilities) st->xy = tile;
  1951 		if (!st->facilities) st->xy = tile;
  1999 static int32 RemoveDock(Station *st, uint32 flags)
  1978 static int32 RemoveDock(Station *st, uint32 flags)
  2000 {
  1979 {
  2001 	TileIndex tile1;
  1980 	TileIndex tile1;
  2002 	TileIndex tile2;
  1981 	TileIndex tile2;
  2003 
  1982 
  2004 	if (!CheckOwnership(st->owner))
  1983 	if (!CheckOwnership(st->owner)) return CMD_ERROR;
  2005 		return CMD_ERROR;
       
  2006 
  1984 
  2007 	tile1 = st->dock_tile;
  1985 	tile1 = st->dock_tile;
  2008 	tile2 = tile1 + TileOffsByDir(_m[tile1].m5 - 0x4C);
  1986 	tile2 = tile1 + TileOffsByDir(_m[tile1].m5 - 0x4C);
  2009 
  1987 
  2010 	if (!EnsureNoVehicle(tile1))
  1988 	if (!EnsureNoVehicle(tile1)) return CMD_ERROR;
  2011 		return CMD_ERROR;
  1989 	if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
  2012 
       
  2013 	if (!EnsureNoVehicle(tile2))
       
  2014 		return CMD_ERROR;
       
  2015 
  1990 
  2016 	if (flags & DC_EXEC) {
  1991 	if (flags & DC_EXEC) {
  2017 		DoClearSquare(tile1);
  1992 		DoClearSquare(tile1);
  2018 
  1993 
  2019 		// convert the water tile to water.
  1994 		// convert the water tile to water.
  2046 	uint32 relocation = 0;
  2021 	uint32 relocation = 0;
  2047 
  2022 
  2048 	{
  2023 	{
  2049 		PlayerID owner = GetTileOwner(ti->tile);
  2024 		PlayerID owner = GetTileOwner(ti->tile);
  2050 		image_or_modificator = PALETTE_TO_GREY; /* NOTE: possible bug in ttd here? */
  2025 		image_or_modificator = PALETTE_TO_GREY; /* NOTE: possible bug in ttd here? */
  2051 		if (owner < MAX_PLAYERS)
  2026 		if (owner < MAX_PLAYERS) image_or_modificator = PLAYER_SPRITE_COLOR(owner);
  2052 			image_or_modificator = PLAYER_SPRITE_COLOR(owner);
       
  2053 	}
  2027 	}
  2054 
  2028 
  2055 	// don't show foundation for docks (docks are between 76 (0x4C) and 81 (0x51))
  2029 	// don't show foundation for docks (docks are between 76 (0x4C) and 81 (0x51))
  2056 	if (ti->tileh != 0 && (ti->map5 < 0x4C || ti->map5 > 0x51))
  2030 	if (ti->tileh != 0 && (ti->map5 < 0x4C || ti->map5 > 0x51))
  2057 		DrawFoundation(ti, ti->tileh);
  2031 		DrawFoundation(ti, ti->tileh);
  2072 	}
  2046 	}
  2073 
  2047 
  2074 	if (t == NULL) t = &_station_display_datas[ti->map5];
  2048 	if (t == NULL) t = &_station_display_datas[ti->map5];
  2075 
  2049 
  2076 	image = t->ground_sprite;
  2050 	image = t->ground_sprite;
  2077 	if (image & PALETTE_MODIFIER_COLOR)
  2051 	if (image & PALETTE_MODIFIER_COLOR) image |= image_or_modificator;
  2078 		image |= image_or_modificator;
       
  2079 
  2052 
  2080 	// For custom sprites, there's no railtype-based pitching.
  2053 	// For custom sprites, there's no railtype-based pitching.
  2081 	offset = (image & SPRITE_MASK) < _custom_sprites_base ? rti->total_offset : railtype;
  2054 	offset = (image & SPRITE_MASK) < _custom_sprites_base ? rti->total_offset : railtype;
  2082 	image += offset;
  2055 	image += offset;
  2083 
  2056 
  2122 	ormod = PLAYER_SPRITE_COLOR(_local_player);
  2095 	ormod = PLAYER_SPRITE_COLOR(_local_player);
  2123 
  2096 
  2124 	t = &_station_display_datas[image];
  2097 	t = &_station_display_datas[image];
  2125 
  2098 
  2126 	img = t->ground_sprite;
  2099 	img = t->ground_sprite;
  2127 	if (img & PALETTE_MODIFIER_COLOR)
  2100 	if (img & PALETTE_MODIFIER_COLOR) img |= ormod;
  2128 		img |= ormod;
       
  2129 	DrawSprite(img + rti->total_offset, x, y);
  2101 	DrawSprite(img + rti->total_offset, x, y);
  2130 
  2102 
  2131 	foreach_draw_tile_seq(dtss, t->seq) {
  2103 	foreach_draw_tile_seq(dtss, t->seq) {
  2132 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
  2104 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
  2133 		DrawSprite((dtss->image | ormod) + rti->total_offset, x + pt.x, y + pt.y);
  2105 		DrawSprite((dtss->image | ormod) + rti->total_offset, x + pt.x, y + pt.y);
  2278 
  2250 
  2279 static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
  2251 static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
  2280 {
  2252 {
  2281 	StationID station_id;
  2253 	StationID station_id;
  2282 	byte dir;
  2254 	byte dir;
  2283 	uint16 spd;
       
  2284 
  2255 
  2285 	if (v->type == VEH_Train) {
  2256 	if (v->type == VEH_Train) {
  2286 		if (IS_BYTE_INSIDE(_m[tile].m5, 0, 8) && v->subtype == TS_Front_Engine &&
  2257 		if (IS_BYTE_INSIDE(_m[tile].m5, 0, 8) && v->subtype == TS_Front_Engine &&
  2287 				!IsCompatibleTrainStationTile(tile + TileOffsByDir(v->direction >> 1), tile)) {
  2258 				!IsCompatibleTrainStationTile(tile + TileOffsByDir(v->direction >> 1), tile)) {
  2288 
  2259 
  2289 			station_id = _m[tile].m2;
  2260 			station_id = _m[tile].m2;
  2290 			if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) ||
  2261 			if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) ||
  2291 					(v->current_order.type == OT_GOTO_STATION && v->current_order.station == station_id)) {
  2262 					(v->current_order.type == OT_GOTO_STATION && v->current_order.station == station_id)) {
  2292 
       
  2293 				if (!(_patches.new_nonstop && v->current_order.flags & OF_NON_STOP) &&
  2263 				if (!(_patches.new_nonstop && v->current_order.flags & OF_NON_STOP) &&
  2294 						v->current_order.type != OT_LEAVESTATION &&
  2264 						v->current_order.type != OT_LEAVESTATION &&
  2295 						v->last_station_visited != station_id) {
  2265 						v->last_station_visited != station_id) {
  2296 					x &= 0xF;
  2266 					x &= 0xF;
  2297 					y &= 0xF;
  2267 					y &= 0xF;
  2298 
  2268 
  2299 					dir = v->direction & 6;
  2269 					dir = v->direction & 6;
  2300 					if (dir & 2) intswap(x,y);
  2270 					if (dir & 2) intswap(x,y);
  2301 					if (y == 8) {
  2271 					if (y == 8) {
  2302 						if (dir != 2 && dir != 4) {
  2272 						if (dir != 2 && dir != 4) x = ~x & 0xF;
  2303 							x = (~x)&0xF;
       
  2304 						}
       
  2305 						if (x == 12) return 2 | (station_id << 8); /* enter station */
  2273 						if (x == 12) return 2 | (station_id << 8); /* enter station */
  2306 						if (x < 12) {
  2274 						if (x < 12) {
       
  2275 							uint16 spd;
       
  2276 
  2307 							v->vehstatus |= VS_TRAIN_SLOWING;
  2277 							v->vehstatus |= VS_TRAIN_SLOWING;
  2308 							spd = _enter_station_speedtable[x];
  2278 							spd = _enter_station_speedtable[x];
  2309 							if (spd < v->cur_speed)
  2279 							if (spd < v->cur_speed) v->cur_speed = spd;
  2310 								v->cur_speed = spd;
       
  2311 						}
  2280 						}
  2312 					}
  2281 					}
  2313 				}
  2282 				}
  2314 			}
  2283 			}
  2315 		}
  2284 		}
  2389 					invalidate = true;
  2358 					invalidate = true;
  2390 				}
  2359 				}
  2391 			}
  2360 			}
  2392 		}
  2361 		}
  2393 		//Orders for the vehicle have been changed, invalidate the window
  2362 		//Orders for the vehicle have been changed, invalidate the window
  2394 		if (invalidate)
  2363 		if (invalidate) InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
  2395 			InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
       
  2396 	}
  2364 	}
  2397 
  2365 
  2398 	//Subsidies need removal as well
  2366 	//Subsidies need removal as well
  2399 	DeleteSubsidyWithStation(index);
  2367 	DeleteSubsidyWithStation(index);
  2400 }
  2368 }
  2402 void DeleteAllPlayerStations(void)
  2370 void DeleteAllPlayerStations(void)
  2403 {
  2371 {
  2404 	Station *st;
  2372 	Station *st;
  2405 
  2373 
  2406 	FOR_ALL_STATIONS(st) {
  2374 	FOR_ALL_STATIONS(st) {
  2407 		if (st->xy && st->owner < MAX_PLAYERS)
  2375 		if (st->xy != 0 && st->owner < MAX_PLAYERS) DeleteStation(st);
  2408 			DeleteStation(st);
       
  2409 	}
  2376 	}
  2410 }
  2377 }
  2411 
  2378 
  2412 static void CheckOrphanedSlots(const Station *st, RoadStopType rst)
  2379 static void CheckOrphanedSlots(const Station *st, RoadStopType rst)
  2413 {
  2380 {
  2433 /* this function is called for one station each tick */
  2400 /* this function is called for one station each tick */
  2434 static void StationHandleBigTick(Station *st)
  2401 static void StationHandleBigTick(Station *st)
  2435 {
  2402 {
  2436 	UpdateStationAcceptance(st, true);
  2403 	UpdateStationAcceptance(st, true);
  2437 
  2404 
  2438 	if (st->facilities == 0) {
  2405 	if (st->facilities == 0 && ++st->delete_ctr >= 8) DeleteStation(st);
  2439 		if (++st->delete_ctr >= 8)
       
  2440 			DeleteStation(st);
       
  2441 	}
       
  2442 
  2406 
  2443 	// Here we saveguard against orphaned slots
  2407 	// Here we saveguard against orphaned slots
  2444 	CheckOrphanedSlots(st, RS_BUS);
  2408 	CheckOrphanedSlots(st, RS_BUS);
  2445 	CheckOrphanedSlots(st, RS_TRUCK);
  2409 	CheckOrphanedSlots(st, RS_TRUCK);
  2446 }
  2410 }
  2544 /* called for every station each tick */
  2508 /* called for every station each tick */
  2545 static void StationHandleSmallTick(Station *st)
  2509 static void StationHandleSmallTick(Station *st)
  2546 {
  2510 {
  2547 	byte b;
  2511 	byte b;
  2548 
  2512 
  2549 	if (st->facilities == 0)
  2513 	if (st->facilities == 0) return;
  2550 		return;
       
  2551 
  2514 
  2552 	b = st->delete_ctr + 1;
  2515 	b = st->delete_ctr + 1;
  2553 	if (b >= 185) b = 0;
  2516 	if (b >= 185) b = 0;
  2554 	st->delete_ctr = b;
  2517 	st->delete_ctr = b;
  2555 
  2518 
  2556 	if (b == 0)
  2519 	if (b == 0) UpdateStationRating(st);
  2557 		UpdateStationRating(st);
       
  2558 }
  2520 }
  2559 
  2521 
  2560 void OnTick_Station(void)
  2522 void OnTick_Station(void)
  2561 {
  2523 {
  2562 	uint i;
  2524 	uint i;
  2563 	Station *st;
  2525 	Station *st;
  2564 
  2526 
  2565 	if (_game_mode == GM_EDITOR)
  2527 	if (_game_mode == GM_EDITOR) return;
  2566 		return;
       
  2567 
  2528 
  2568 	i = _station_tick_ctr;
  2529 	i = _station_tick_ctr;
  2569 	if (++_station_tick_ctr == GetStationPoolSize())
  2530 	if (++_station_tick_ctr == GetStationPoolSize()) _station_tick_ctr = 0;
  2570 		_station_tick_ctr = 0;
       
  2571 
  2531 
  2572 	st = GetStation(i);
  2532 	st = GetStation(i);
  2573 	if (st->xy != 0)
  2533 	if (st->xy != 0) StationHandleBigTick(st);
  2574 		StationHandleBigTick(st);
       
  2575 
  2534 
  2576 	FOR_ALL_STATIONS(st) {
  2535 	FOR_ALL_STATIONS(st) {
  2577 		if (st->xy != 0)
  2536 		if (st->xy != INVALID_TILE) StationHandleSmallTick(st);
  2578 			StationHandleSmallTick(st);
  2537 	}
  2579 	}
       
  2580 
       
  2581 }
  2538 }
  2582 
  2539 
  2583 void StationMonthlyLoop(void)
  2540 void StationMonthlyLoop(void)
  2584 {
  2541 {
  2585 }
  2542 }
  2621  * @param p1 station ID that is to be renamed
  2578  * @param p1 station ID that is to be renamed
  2622  * @param p2 unused
  2579  * @param p2 unused
  2623  */
  2580  */
  2624 int32 CmdRenameStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  2581 int32 CmdRenameStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  2625 {
  2582 {
  2626 	StringID str,old_str;
  2583 	StringID str;
  2627 	Station *st;
  2584 	Station *st;
  2628 
  2585 
  2629 	if (!IsStationIndex(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
  2586 	if (!IsStationIndex(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
  2630 	st = GetStation(p1);
  2587 	st = GetStation(p1);
  2631 
  2588 
  2633 
  2590 
  2634 	str = AllocateNameUnique(_cmd_text, 6);
  2591 	str = AllocateNameUnique(_cmd_text, 6);
  2635 	if (str == 0) return CMD_ERROR;
  2592 	if (str == 0) return CMD_ERROR;
  2636 
  2593 
  2637 	if (flags & DC_EXEC) {
  2594 	if (flags & DC_EXEC) {
  2638 		old_str = st->string_id;
  2595 		StringID old_str = st->string_id;
       
  2596 
  2639 		st->string_id = str;
  2597 		st->string_id = str;
  2640 		UpdateStationVirtCoord(st);
  2598 		UpdateStationVirtCoord(st);
  2641 		DeleteName(old_str);
  2599 		DeleteName(old_str);
  2642 		_station_sort_dirty[st->owner] = true; // rename a station
  2600 		_station_sort_dirty[st->owner] = true; // rename a station
  2643 		MarkWholeScreenDirty();
  2601 		MarkWholeScreenDirty();
  2684 
  2642 
  2685 	BEGIN_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad))
  2643 	BEGIN_TILE_LOOP(cur_tile, w, h, tile - TileDiffXY(max_rad, max_rad))
  2686 		cur_tile = TILE_MASK(cur_tile);
  2644 		cur_tile = TILE_MASK(cur_tile);
  2687 		if (IsTileType(cur_tile, MP_STATION)) {
  2645 		if (IsTileType(cur_tile, MP_STATION)) {
  2688 			st_index = _m[cur_tile].m2;
  2646 			st_index = _m[cur_tile].m2;
  2689 			for(i=0; i!=8; i++)	{
  2647 			for (i = 0; i != 8; i++) {
  2690 				if (around[i] == INVALID_STATION) {
  2648 				if (around[i] == INVALID_STATION) {
  2691 					st = GetStation(st_index);
  2649 					st = GetStation(st_index);
  2692 					if (!IsBuoy(st) &&
  2650 					if (!IsBuoy(st) &&
  2693 							( !st->town->exclusive_counter || (st->town->exclusivity == st->owner) ) && // check exclusive transport rights
  2651 							( !st->town->exclusive_counter || (st->town->exclusivity == st->owner) ) && // check exclusive transport rights
  2694 							st->goods[type].rating != 0 &&
  2652 							st->goods[type].rating != 0 &&
  2786 	return moved;
  2744 	return moved;
  2787 }
  2745 }
  2788 
  2746 
  2789 void BuildOilRig(TileIndex tile)
  2747 void BuildOilRig(TileIndex tile)
  2790 {
  2748 {
  2791 	int j;
  2749 	uint j;
  2792 	Station *st = AllocateStation();
  2750 	Station *st = AllocateStation();
  2793 
  2751 
  2794 	if (st == NULL) {
  2752 	if (st == NULL) {
  2795 		DEBUG(misc, 0) ("Couldn't allocate station for oilrig at %#X, reverting to oilrig only...", tile);
  2753 		DEBUG(misc, 0) ("Couldn't allocate station for oilrig at %#X, reverting to oilrig only...", tile);
  2796 		return;
  2754 		return;
  2802 
  2760 
  2803 	st->town = ClosestTownFromTile(tile, (uint)-1);
  2761 	st->town = ClosestTownFromTile(tile, (uint)-1);
  2804 	st->sign.width_1 = 0;
  2762 	st->sign.width_1 = 0;
  2805 
  2763 
  2806 	SetTileType(tile, MP_STATION);
  2764 	SetTileType(tile, MP_STATION);
  2807 	_m[tile].m5 = 0x4B;
       
  2808 	SetTileOwner(tile, OWNER_NONE);
  2765 	SetTileOwner(tile, OWNER_NONE);
       
  2766 	_m[tile].m2 = st->index;
  2809 	_m[tile].m3 = 0;
  2767 	_m[tile].m3 = 0;
  2810 	_m[tile].m4 = 0;
  2768 	_m[tile].m4 = 0;
  2811 	_m[tile].m2 = st->index;
  2769 	_m[tile].m5 = 0x4B;
  2812 
  2770 
  2813 	st->owner = OWNER_NONE;
  2771 	st->owner = OWNER_NONE;
  2814 	st->airport_flags = 0;
  2772 	st->airport_flags = 0;
  2815 	st->airport_type = AT_OILRIG;
  2773 	st->airport_type = AT_OILRIG;
  2816 	st->xy = tile;
  2774 	st->xy = tile;
  2885 		return_cmd_error(STR_4800_IN_THE_WAY);
  2843 		return_cmd_error(STR_4800_IN_THE_WAY);
  2886 	}
  2844 	}
  2887 
  2845 
  2888 	st = GetStation(_m[tile].m2);
  2846 	st = GetStation(_m[tile].m2);
  2889 
  2847 
  2890 	if (m5 < 8)
  2848 	if (m5 < 8) return RemoveRailroadStation(st, tile, flags);
  2891 		return RemoveRailroadStation(st, tile, flags);
       
  2892 
       
  2893 	// original airports < 67, new airports between 83 - 114
  2849 	// original airports < 67, new airports between 83 - 114
  2894 	if (m5 < 0x43 || ( m5 >= 83 && m5 <= 114) )
  2850 	if (m5 < 0x43 || (m5 >= 83 && m5 <= 114)) return RemoveAirport(st, flags);
  2895 		return RemoveAirport(st, flags);
  2851 	if (m5 < 0x4B) return RemoveRoadStop(st, flags, tile);
  2896 
  2852 	if (m5 == 0x52) return RemoveBuoy(st, flags);
  2897 	if (m5 < 0x4B)
  2853 	if (m5 != 0x4B && m5 < 0x53) return RemoveDock(st, flags);
  2898 		return RemoveRoadStop(st, flags, tile);
       
  2899 
       
  2900 	if (m5 == 0x52)
       
  2901 		return RemoveBuoy(st, flags);
       
  2902 
       
  2903 	if (m5 != 0x4B && m5 < 0x53)
       
  2904 		return RemoveDock(st, flags);
       
  2905 
  2854 
  2906 	return CMD_ERROR;
  2855 	return CMD_ERROR;
  2907 
       
  2908 }
  2856 }
  2909 
  2857 
  2910 void InitializeStations(void)
  2858 void InitializeStations(void)
  2911 {
  2859 {
  2912 	/* Clean the station pool and create 1 block in it */
  2860 	/* Clean the station pool and create 1 block in it */
  3034 	SlObject(st, _station_desc);
  2982 	SlObject(st, _station_desc);
  3035 	for (i = 0; i != NUM_CARGO; i++) {
  2983 	for (i = 0; i != NUM_CARGO; i++) {
  3036 		SlObject(&st->goods[i], _goods_desc);
  2984 		SlObject(&st->goods[i], _goods_desc);
  3037 
  2985 
  3038 		/* In older versions, enroute_from had 0xFF as INVALID_STATION, is now 0xFFFF */
  2986 		/* In older versions, enroute_from had 0xFF as INVALID_STATION, is now 0xFFFF */
  3039 		if (_sl_full_version < 0x700 && st->goods[i].enroute_from == 0xFF)
  2987 		if (_sl_full_version < 0x700 && st->goods[i].enroute_from == 0xFF) {
  3040 			st->goods[i].enroute_from = INVALID_STATION;
  2988 			st->goods[i].enroute_from = INVALID_STATION;
       
  2989 		}
  3041 	}
  2990 	}
  3042 }
  2991 }
  3043 
  2992 
  3044 static void Save_STNS(void)
  2993 static void Save_STNS(void)
  3045 {
  2994 {
  3064 
  3013 
  3065 		st = GetStation(index);
  3014 		st = GetStation(index);
  3066 		SaveLoad_STNS(st);
  3015 		SaveLoad_STNS(st);
  3067 
  3016 
  3068 		// this means it's an oldstyle savegame without support for nonuniform stations
  3017 		// this means it's an oldstyle savegame without support for nonuniform stations
  3069 		if (st->train_tile && st->trainst_h == 0) {
  3018 		if (st->train_tile != 0 && st->trainst_h == 0) {
  3070 			int w = st->trainst_w >> 4;
  3019 			int w = st->trainst_w >> 4;
  3071 			int h = st->trainst_w & 0xF;
  3020 			int h = st->trainst_w & 0xF;
  3072 			if (_m[st->train_tile].m5&1) intswap(w,h);
  3021 
       
  3022 			if (_m[st->train_tile].m5 & 1) intswap(w, h);
  3073 			st->trainst_w = w;
  3023 			st->trainst_w = w;
  3074 			st->trainst_h = h;
  3024 			st->trainst_h = h;
  3075 		}
  3025 		}
  3076 
  3026 
  3077 		if (_sl_full_version < 0x600) {
  3027 		if (_sl_full_version < 0x600) {
  3092 			}
  3042 			}
  3093 		}
  3043 		}
  3094 	}
  3044 	}
  3095 
  3045 
  3096 	/* This is to ensure all pointers are within the limits of _stations_size */
  3046 	/* This is to ensure all pointers are within the limits of _stations_size */
  3097 	if (_station_tick_ctr > GetStationPoolSize())
  3047 	if (_station_tick_ctr > GetStationPoolSize()) _station_tick_ctr = 0;
  3098 		_station_tick_ctr = 0;
       
  3099 }
  3048 }
  3100 
  3049 
  3101 static void Save_ROADSTOP(void)
  3050 static void Save_ROADSTOP(void)
  3102 {
  3051 {
  3103 	RoadStop *rs;
  3052 	RoadStop *rs;