* Place an Airport. * @param flags operation to perform * @param tile tile where airport will be built * @param airport_type airport type, @see airport.h * @param layout airport layout * @param station_to_join station ID to join (NEW_STATION if build new one) * @param allow_adjacent allow airports directly adjacent to other airports. * @return the cost of this operation or an error */
| 2625 | * @return the cost of this operation or an error |
| 2626 | */ |
| 2627 | CommandCost CmdBuildAirport(DoCommandFlags flags, TileIndex tile, uint8_t airport_type, uint8_t layout, StationID station_to_join, bool allow_adjacent) |
| 2628 | { |
| 2629 | bool reuse = (station_to_join != NEW_STATION); |
| 2630 | if (!reuse) station_to_join = StationID::Invalid(); |
| 2631 | bool distant_join = (station_to_join != StationID::Invalid()); |
| 2632 | |
| 2633 | if (distant_join && (!_settings_game.station.distant_join_stations || !Station::IsValidID(station_to_join))) return CMD_ERROR; |
| 2634 | |
| 2635 | if (airport_type >= NUM_AIRPORTS) return CMD_ERROR; |
| 2636 | |
| 2637 | CommandCost ret = CheckIfAuthorityAllowsNewStation(tile, flags); |
| 2638 | if (ret.Failed()) return ret; |
| 2639 | |
| 2640 | /* Check if a valid, buildable airport was chosen for construction */ |
| 2641 | const AirportSpec *as = AirportSpec::Get(airport_type); |
| 2642 | if (!as->IsAvailable() || layout >= as->layouts.size()) return CMD_ERROR; |
| 2643 | if (!as->IsWithinMapBounds(layout, tile)) return CMD_ERROR; |
| 2644 | |
| 2645 | Direction rotation = as->layouts[layout].rotation; |
| 2646 | int w = as->size_x; |
| 2647 | int h = as->size_y; |
| 2648 | if (rotation == DIR_E || rotation == DIR_W) std::swap(w, h); |
| 2649 | TileArea airport_area = TileArea(tile, w, h); |
| 2650 | |
| 2651 | if (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread) { |
| 2652 | return CommandCost(STR_ERROR_STATION_TOO_SPREAD_OUT); |
| 2653 | } |
| 2654 | |
| 2655 | AirportTileTableIterator tile_iter(as->layouts[layout].tiles, tile); |
| 2656 | CommandCost cost = CheckFlatLandAirport(tile_iter, flags); |
| 2657 | if (cost.Failed()) return cost; |
| 2658 | |
| 2659 | /* The noise level is the noise from the airport and reduce it to account for the distance to the town center. */ |
| 2660 | uint dist; |
| 2661 | Town *nearest = AirportGetNearestTown(as, rotation, tile, std::move(tile_iter), dist); |
| 2662 | uint newnoise_level = GetAirportNoiseLevelForDistance(as, dist); |
| 2663 | |
| 2664 | /* Check if local auth would allow a new airport */ |
| 2665 | StringID authority_refuse_message = STR_NULL; |
| 2666 | Town *authority_refuse_town = nullptr; |
| 2667 | |
| 2668 | if (_settings_game.economy.station_noise_level) { |
| 2669 | /* do not allow to build a new airport if this raise the town noise over the maximum allowed by town */ |
| 2670 | if ((nearest->noise_reached + newnoise_level) > nearest->MaxTownNoise()) { |
| 2671 | authority_refuse_message = STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE; |
| 2672 | authority_refuse_town = nearest; |
| 2673 | } |
| 2674 | } else if (_settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) { |
| 2675 | Town *t = ClosestTownFromTile(tile, UINT_MAX); |
| 2676 | uint num = 0; |
| 2677 | for (const Station *st : Station::Iterate()) { |
| 2678 | if (st->town == t && st->facilities.Test(StationFacility::Airport) && st->airport.type != AT_OILRIG) num++; |
| 2679 | } |
| 2680 | if (num >= 2) { |
| 2681 | authority_refuse_message = STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT; |
| 2682 | authority_refuse_town = t; |
| 2683 | } |
| 2684 | } |
nothing calls this directly
no test coverage detected