/**
* Ensure there is no ship on the neighbouring tiles coming into or going
* away from the specified tile.
* @param tile the specified tile.
* @param diag_dir_mask mask containing the diagonal directions to the
* neighbouring tiles.
* @return Succeeded command (no neighbouring ship) or failed command (a
* neighbouring ship is found)
*/
CommandCost EnsureNoShipFromDiagDirMask(TileIndex tile, byte diag_dir_mask)
{
/* Get track bits of the specified tile */
TrackBits tile_tb = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
if ((tile_tb & TRACK_BIT_ALL) != TRACK_BIT_NONE) {
/* Ships can walk on main tile, so ensure from which provided diagonal directions a neightbouring ship can't be found */
for (DiagDirection diag_dir = DIAGDIR_BEGIN; diag_dir != DIAGDIR_END; diag_dir++) {
if (diag_dir_mask & 1 << diag_dir) {
/* Make checks on this diagonal direction */
TileIndex tc = TileAddByDiagDir(tile, diag_dir); // Move into the neighbouring tile
/* Get track bits of the neighbouring tile that can be reached from the main tile */
TrackBits tc_tb = TrackStatusToTrackBits(GetTileTrackStatus(tc, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(DiagdirBetweenTiles(tile, tc));
/* Then also check if there are track bits on the main tile that can be reached from the neighbouring tile */
if (tc_tb && DiagdirReachesTracks(DiagdirBetweenTiles(tc, tile)) & tile_tb) {
/* We don't check for a ship in the neighbouring ship depots, locks or aqueducts,
* because we only care about 1-tile depth, and those structures are more than 1-tile wide. */
if (!IsShipDepotTile(tc) && !(IsTileType(tc, MP_WATER) && IsLock(tc)) &&
!(IsTileType(tc, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tc) == TRANSPORT_WATER)) {
/* Check if there are no ships on the track bits of the neighbouring tile */
if (HasVehicleOnPos(tc, &tc_tb, EnsureNoShipOnTrackProc)) {
return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY);
}
}
}
}
}
}
return CommandCost();
}