diff --git a/src/lang/english.txt b/src/lang/english.txt index c903daa949..61b5525691 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1943,8 +1943,14 @@ STR_CONFIG_SETTING_ENABLE_RAIL_CUSTOM_BRIDGE_HEADS_HELPTEXT :Allow rail brid STR_CONFIG_SETTING_ALLOW_GRF_OBJECTS_UNDER_BRIDGES :Allow all NewGRF objects under bridges: {STRING2} STR_CONFIG_SETTING_ALLOW_GRF_OBJECTS_UNDER_BRIDGES_HELPTEXT :Allow all NewGRF objects to be built under bridges, even where not otherwise enabled by the GRF.{}This may result in graphical issues. -STR_CONFIG_SETTING_ALLOW_STATIONS_UNDER_BRIDGES :Allow stations under bridges: {STRING2} -STR_CONFIG_SETTING_ALLOW_STATIONS_UNDER_BRIDGES_HELPTEXT :Allow stations to be built under bridges (excluding airports, and rail stations/waypoints where the required bridge clearance is set by the GRF).{}This may result in graphical issues. +STR_CONFIG_SETTING_ALLOW_GRF_STATIONS_UNDER_BRIDGES :Allow NewGRF rail stations/waypoints under bridges: {STRING2} +STR_CONFIG_SETTING_ALLOW_GRF_STATIONS_UNDER_BRIDGES_HELPTEXT :If enabled, NewGRF rail stations/waypoints which do not specify whether they may be built under bridges will be allowed under bridges with no restrictions.{}This may result in graphical issues. + +STR_CONFIG_SETTING_ALLOW_ROAD_STATIONS_UNDER_BRIDGES :Allow road/tram stops under bridges: {STRING2} +STR_CONFIG_SETTING_ALLOW_ROAD_STATIONS_UNDER_BRIDGES_HELPTEXT :Allow road/tram stops under bridges. Drive through stops require 1 height level of clearance, drive in bays require 2 height levels of clearance. + +STR_CONFIG_SETTING_ALLOW_DOCKS_UNDER_BRIDGES :Allow docks under bridges: {STRING2} +STR_CONFIG_SETTING_ALLOW_DOCKS_UNDER_BRIDGES_HELPTEXT :Allow docks under bridges. Docks require 2 height levels of clearance.{}This may result in graphical issues. STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED :Permit purchasing land: {STRING2} STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED_HELPTEXT :Set whether companies are permitted to purchase tiles of land, and in what quantity diff --git a/src/lang/korean.txt b/src/lang/korean.txt index e4b8e2f1ff..2da9333b27 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -1943,9 +1943,6 @@ STR_CONFIG_SETTING_ENABLE_RAIL_CUSTOM_BRIDGE_HEADS_HELPTEXT :철교의 입 STR_CONFIG_SETTING_ALLOW_GRF_OBJECTS_UNDER_BRIDGES :모든 NewGRF 오브젝트를 다리 밑에 설치하는 것을 허용: {STRING} STR_CONFIG_SETTING_ALLOW_GRF_OBJECTS_UNDER_BRIDGES_HELPTEXT :NewGRF의 설정과 관계 없이 모든 NewGRF 오브젝트가 다리 밑에 설치될 수 있도록 허용합니다.{}그래픽 오류가 발생할 수 있습니다. -STR_CONFIG_SETTING_ALLOW_STATIONS_UNDER_BRIDGES :다리 밑에 역을 짓는 것을 허용: {STRING} -STR_CONFIG_SETTING_ALLOW_STATIONS_UNDER_BRIDGES_HELPTEXT :다리 밑에 공항을 제외한 역을 짓는 것을 허용합니다.{}그래픽 오류가 발생할 수 있습니다. - STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED :토지 소유권 구매 허용: {STRING} STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED_HELPTEXT :회사가 토지 소유권을 구매할 수 있을지와 어떤 방식으로 구매할지를 설정합니다. diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index c4224aa47d..1e7a9fcd9a 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1842,6 +1842,8 @@ static SettingsContainer &GetSettingsTree() limitations->Add(new SettingEntry("construction.rail_custom_bridge_heads")); limitations->Add(new SettingEntry("construction.allow_grf_objects_under_bridges")); limitations->Add(new SettingEntry("construction.allow_stations_under_bridges")); + limitations->Add(new SettingEntry("construction.allow_road_stops_under_bridges")); + limitations->Add(new SettingEntry("construction.allow_docks_under_bridges")); limitations->Add(new SettingEntry("construction.purchase_land_permitted")); } diff --git a/src/settings_type.h b/src/settings_type.h index e59030cf1f..fe2bf1c190 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -376,7 +376,9 @@ struct ConstructionSettings { bool chunnel; ///< allow construction of tunnels under water uint8 rail_custom_bridge_heads; ///< allow construction of rail custom bridge heads bool allow_grf_objects_under_bridges; ///< allow all NewGRF objects under bridges - bool allow_stations_under_bridges; ///< allow all station tiles under bridges + bool allow_stations_under_bridges; ///< allow NewGRF rail station/waypoint tiles that do not specify clearance under bridges + bool allow_road_stops_under_bridges; ///< allow road/tram stops under bridges + bool allow_docks_under_bridges; ///< allow docks under bridges byte purchase_land_permitted; ///< whether and how purchasing land is permitted uint32 terraform_per_64k_frames; ///< how many tile heights may, over a long period, be terraformed per 65536 frames? diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index fde85056f3..a69fb01f77 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -883,6 +883,29 @@ CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statsp GetBridgeType(southern_bridge_end), GetTunnelBridgeTransportType(southern_bridge_end)); } +CommandCost IsRoadStopBridgeAboveOK(TileIndex tile, bool drive_through, DiagDirection entrance, + TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height, + BridgeType bridge_type, TransportType bridge_transport_type) +{ + if (!_settings_game.construction.allow_road_stops_under_bridges) return CommandCost(INVALID_STRING_ID); + + if (GetTileMaxZ(tile) + (drive_through ? 1 : 2) > bridge_height) { + return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION); + } + + BridgePiecePillarFlags disallowed_pillar_flags = (BridgePiecePillarFlags) 0; + if (drive_through) { + disallowed_pillar_flags = (BridgePiecePillarFlags) (DiagDirToAxis(entrance) == AXIS_X ? 0x50 : 0xA0); + } else { + SetBit(disallowed_pillar_flags, 4 + entrance); + } + if ((GetBridgeTilePillarFlags(tile, northern_bridge_end, southern_bridge_end, bridge_type, bridge_transport_type) & disallowed_pillar_flags) == 0) { + return CommandCost(); + } else { + return CommandCost(STR_ERROR_BRIDGE_PILLARS_OBSTRUCT_STATION); + } +} + /** * Checks if a rail station can be built at the given area. * @param tile_area Area to check. @@ -989,10 +1012,19 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags int allowed_z = -1; TILE_AREA_LOOP(cur_tile, tile_area) { - CommandCost ret = CheckBuildableTile(cur_tile, invalid_dirs, allowed_z, !is_drive_through, !_settings_game.construction.allow_stations_under_bridges); + CommandCost ret = CheckBuildableTile(cur_tile, invalid_dirs, allowed_z, !is_drive_through, !_settings_game.construction.allow_road_stops_under_bridges); if (ret.Failed()) return ret; cost.AddCost(ret); + if (_settings_game.construction.allow_road_stops_under_bridges && IsBridgeAbove(cur_tile)) { + TileIndex southern_bridge_end = GetSouthernBridgeEnd(cur_tile); + TileIndex northern_bridge_end = GetNorthernBridgeEnd(cur_tile); + CommandCost bridge_ret = IsRoadStopBridgeAboveOK(cur_tile, is_drive_through, (DiagDirection) FindFirstBit(invalid_dirs), + northern_bridge_end, southern_bridge_end, GetBridgeHeight(southern_bridge_end), + GetBridgeType(southern_bridge_end), GetTunnelBridgeTransportType(southern_bridge_end)); + if (bridge_ret.Failed()) return bridge_ret; + } + /* If station is set, then we have special handling to allow building on top of already existing stations. * Station points to INVALID_STATION if we can build on any station. * Or it points to a station if we're only allowed to build on exactly that station. */ @@ -2733,7 +2765,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 CommandCost ret = CheckIfAuthorityAllowsNewStation(slope_tile, flags); if (ret.Failed()) return ret; - if (IsBridgeAbove(slope_tile) && !_settings_game.construction.allow_stations_under_bridges) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); + if (IsBridgeAbove(slope_tile) && !_settings_game.construction.allow_docks_under_bridges) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); ret = DoCommand(slope_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; @@ -2742,7 +2774,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } - if (IsBridgeAbove(flat_tile) && !_settings_game.construction.allow_stations_under_bridges) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); + if (IsBridgeAbove(flat_tile) && !_settings_game.construction.allow_docks_under_bridges) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); /* Get the water class of the water tile before it is cleared.*/ WaterClass wc = GetWaterClass(flat_tile); diff --git a/src/table/settings.ini b/src/table/settings.ini index 5462b19f92..3f0cb9d25a 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -1701,10 +1701,28 @@ base = GameSettings var = construction.allow_stations_under_bridges def = false cat = SC_ADVANCED -str = STR_CONFIG_SETTING_ALLOW_STATIONS_UNDER_BRIDGES -strhelp = STR_CONFIG_SETTING_ALLOW_STATIONS_UNDER_BRIDGES_HELPTEXT +str = STR_CONFIG_SETTING_ALLOW_GRF_STATIONS_UNDER_BRIDGES +strhelp = STR_CONFIG_SETTING_ALLOW_GRF_STATIONS_UNDER_BRIDGES_HELPTEXT patxname = ""allow_stations_under_bridges.construction.allow_stations_under_bridges"" +[SDT_BOOL] +base = GameSettings +var = construction.allow_road_stops_under_bridges +def = true +cat = SC_ADVANCED +str = STR_CONFIG_SETTING_ALLOW_ROAD_STATIONS_UNDER_BRIDGES +strhelp = STR_CONFIG_SETTING_ALLOW_ROAD_STATIONS_UNDER_BRIDGES_HELPTEXT +patxname = ""allow_stations_under_bridges.construction.allow_road_stops_under_bridges"" + +[SDT_BOOL] +base = GameSettings +var = construction.allow_docks_under_bridges +def = false +cat = SC_ADVANCED +str = STR_CONFIG_SETTING_ALLOW_DOCKS_UNDER_BRIDGES +strhelp = STR_CONFIG_SETTING_ALLOW_DOCKS_UNDER_BRIDGES_HELPTEXT +patxname = ""allow_stations_under_bridges.construction.allow_docks_under_bridges"" + [SDT_VAR] base = GameSettings var = construction.purchase_land_permitted diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 50be95b0b7..4f27b944fc 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -68,6 +68,10 @@ extern const RoadBits _invalid_tileh_slopes_road[2][15]; extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, byte layout, TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height, BridgeType bridge_type, TransportType bridge_transport_type); +extern CommandCost IsRoadStopBridgeAboveOK(TileIndex tile, bool drive_through, DiagDirection entrance, + TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height, + BridgeType bridge_type, TransportType bridge_transport_type); + /** * Mark bridge tiles dirty. * Note: The bridge does not need to exist, everything is passed via parameters. @@ -435,12 +439,24 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u break; } + case STATION_BUS: + case STATION_TRUCK: { + CommandCost ret = IsRoadStopBridgeAboveOK(tile, IsDriveThroughStopTile(tile), GetRoadStopDir(tile), + tile_start, tile_end, z_start + 1, bridge_type, transport_type); + if (ret.Failed()) { + if (ret.GetErrorMessage() != INVALID_STRING_ID) return ret; + ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + if (ret.Failed()) return ret; + } + break; + } + case STATION_BUOY: /* Buoys are always allowed */ break; default: - if (!_settings_game.construction.allow_stations_under_bridges) { + if (!(GetStationType(tile) == STATION_DOCK && _settings_game.construction.allow_docks_under_bridges)) { CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; } @@ -546,12 +562,23 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u break; } + case STATION_BUS: + case STATION_TRUCK: { + CommandCost ret = IsRoadStopBridgeAboveOK(tile, IsDriveThroughStopTile(tile), GetRoadStopDir(tile), + tile_start, tile_end, z_start + 1, bridge_type, transport_type); + if (ret.Failed()) { + if (ret.GetErrorMessage() != INVALID_STRING_ID) return ret; + goto not_valid_below; + } + break; + } + case STATION_BUOY: /* Buoys are always allowed */ break; default: - if (!_settings_game.construction.allow_stations_under_bridges) goto not_valid_below; + if (!(GetStationType(tile) == STATION_DOCK && _settings_game.construction.allow_docks_under_bridges)) goto not_valid_below; break; } break;