Codechange: Use vector for airport tile layouts. (#12607)

Simplify AirportSpec data by storing layout information together in a vector, instead of separate arrays.

This removes manual memory management and separate count members.

The default layouts will be copied instead of always referring to the originals.
This commit is contained in:
Peter Nelson 2024-05-02 12:37:54 +01:00 committed by GitHub
parent 65c9df49d9
commit cf96d49ced
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 122 additions and 184 deletions

View File

@ -277,7 +277,7 @@ public:
const AirportSpec *as = ac->GetSpec(_selected_airport_index);
if (as->IsAvailable()) {
/* Ensure the airport layout is valid. */
_selected_airport_layout = Clamp(_selected_airport_layout, 0, as->num_table - 1);
_selected_airport_layout = Clamp(_selected_airport_layout, 0, static_cast<uint8_t>(as->layouts.size() - 1));
selectFirstAirport = false;
this->UpdateSelectSize();
}
@ -306,7 +306,7 @@ public:
StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_LAYOUT_NAME);
if (string != STR_UNDEFINED) {
SetDParam(0, string);
} else if (as->num_table > 1) {
} else if (as->layouts.size() > 1) {
SetDParam(0, STR_STATION_BUILD_AIRPORT_LAYOUT_NAME);
SetDParam(1, _selected_airport_layout + 1);
}
@ -348,7 +348,7 @@ public:
for (int i = 0; i < NUM_AIRPORTS; i++) {
const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue;
for (uint8_t layout = 0; layout < as->num_table; layout++) {
for (uint8_t layout = 0; layout < static_cast<uint8_t>(as->layouts.size()); layout++) {
SpriteID sprite = GetCustomAirportSprite(as, layout);
if (sprite != 0) {
Dimension d = GetSpriteSize(sprite);
@ -364,7 +364,7 @@ public:
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue;
for (uint8_t layout = 0; layout < as->num_table; layout++) {
for (uint8_t layout = 0; layout < static_cast<uint8_t>(as->layouts.size()); layout++) {
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
if (string == STR_UNDEFINED) continue;
@ -474,14 +474,14 @@ public:
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
int w = as->size_x;
int h = as->size_y;
Direction rotation = as->rotation[_selected_airport_layout];
Direction rotation = as->layouts[_selected_airport_layout].rotation;
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
SetTileSelectSize(w, h);
this->preview_sprite = GetCustomAirportSprite(as, _selected_airport_layout);
this->SetWidgetDisabledState(WID_AP_LAYOUT_DECREASE, _selected_airport_layout == 0);
this->SetWidgetDisabledState(WID_AP_LAYOUT_INCREASE, _selected_airport_layout + 1 >= as->num_table);
this->SetWidgetDisabledState(WID_AP_LAYOUT_INCREASE, _selected_airport_layout + 1U >= as->layouts.size());
int rad = _settings_game.station.modified_catchment ? as->catchment : (uint)CA_UNMODIFIED;
if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);

View File

@ -3861,32 +3861,6 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
return ret;
}
/**
* Create a copy of the tile table so it can be freed later
* without problems.
* @param as The AirportSpec to copy the arrays of.
*/
static void DuplicateTileTable(AirportSpec *as)
{
AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
for (int i = 0; i < as->num_table; i++) {
uint num_tiles = 1;
const AirportTileTable *it = as->table[0];
do {
num_tiles++;
} while ((++it)->ti.x != -0x80);
table_list[i] = MallocT<AirportTileTable>(num_tiles);
MemCpyT(table_list[i], as->table[i], num_tiles);
}
as->table = table_list;
HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
MemCpyT(depot_table, as->depot_table, as->nof_depots);
as->depot_table = depot_table;
Direction *rotation = MallocT<Direction>(as->num_table);
MemCpyT(rotation, as->rotation, as->num_table);
as->rotation = rotation;
}
/**
* Define properties for airports
* @param airport Local ID of the airport.
@ -3942,89 +3916,68 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
as->grf_prop.grffile = _cur.grffile;
/* override the default airport */
_airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
/* Create a copy of the original tiletable so it can be freed later. */
DuplicateTileTable(as);
}
break;
}
case 0x0A: { // Set airport layout
uint8_t old_num_table = as->num_table;
free(as->rotation);
as->num_table = buf->ReadByte(); // Number of layaouts
as->rotation = MallocT<Direction>(as->num_table);
uint32_t defsize = buf->ReadDWord(); // Total size of the definition
AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
int size;
const AirportTileTable *copy_from;
try {
for (uint8_t j = 0; j < as->num_table; j++) {
const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
for (int k = 0;; k++) {
att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
att[k].ti.y = buf->ReadByte();
uint8_t num_layouts = buf->ReadByte();
buf->ReadDWord(); // Total size of definition, unneeded.
uint8_t size_x = 0;
uint8_t size_y = 0;
if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
/* Not the same terminator. The one we are using is rather
* x = -80, y = 0 . So, adjust it. */
att[k].ti.x = -0x80;
att[k].ti.y = 0;
att[k].gfx = 0;
std::vector<AirportTileLayout> layouts;
layouts.reserve(num_layouts);
size = k + 1;
copy_from = att;
break;
}
for (uint8_t j = 0; j != num_layouts; ++j) {
auto &layout = layouts.emplace_back();
layout.rotation = static_cast<Direction>(buf->ReadByte() & 6); // Rotation can only be DIR_NORTH, DIR_EAST, DIR_SOUTH or DIR_WEST.
att[k].gfx = buf->ReadByte();
if (att[k].gfx == 0xFE) {
/* Use a new tile from this GRF */
int local_tile_id = buf->ReadWord();
/* Read the ID from the _airporttile_mngr. */
uint16_t tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
if (tempid == INVALID_AIRPORTTILE) {
GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i);
} else {
/* Declared as been valid, can be used */
att[k].gfx = tempid;
}
} else if (att[k].gfx == 0xFF) {
att[k].ti.x = (int8_t)GB(att[k].ti.x, 0, 8);
att[k].ti.y = (int8_t)GB(att[k].ti.y, 0, 8);
}
if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
as->size_x = std::max<uint8_t>(as->size_x, att[k].ti.y + 1);
as->size_y = std::max<uint8_t>(as->size_y, att[k].ti.x + 1);
} else {
as->size_x = std::max<uint8_t>(as->size_x, att[k].ti.x + 1);
as->size_y = std::max<uint8_t>(as->size_y, att[k].ti.y + 1);
}
for (;;) {
auto &tile = layout.tiles.emplace_back();
tile.ti.x = buf->ReadByte();
tile.ti.y = buf->ReadByte();
if (tile.ti.x == 0 && tile.ti.y == 0x80) {
/* Convert terminator to our own. */
tile.ti.x = -0x80;
tile.ti.y = 0;
tile.gfx = 0;
break;
}
tile.gfx = buf->ReadByte();
if (tile.gfx == 0xFE) {
/* Use a new tile from this GRF */
int local_tile_id = buf->ReadWord();
/* Read the ID from the _airporttile_mngr. */
uint16_t tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
if (tempid == INVALID_AIRPORTTILE) {
GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i);
} else {
/* Declared as been valid, can be used */
tile.gfx = tempid;
}
} else if (tile.gfx == 0xFF) {
tile.ti.x = static_cast<int8_t>(GB(tile.ti.x, 0, 8));
tile.ti.y = static_cast<int8_t>(GB(tile.ti.y, 0, 8));
}
/* Determine largest size. */
if (layout.rotation == DIR_E || layout.rotation == DIR_W) {
size_x = std::max<uint8_t>(size_x, tile.ti.y + 1);
size_y = std::max<uint8_t>(size_y, tile.ti.x + 1);
} else {
size_x = std::max<uint8_t>(size_x, tile.ti.x + 1);
size_y = std::max<uint8_t>(size_y, tile.ti.y + 1);
}
tile_table[j] = CallocT<AirportTileTable>(size);
memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
}
/* Free old layouts in the airport spec */
for (int j = 0; j < old_num_table; j++) {
/* remove the individual layouts */
free(as->table[j]);
}
free(as->table);
/* Install final layout construction in the airport spec */
as->table = tile_table;
free(att);
} catch (...) {
for (int i = 0; i < as->num_table; i++) {
free(tile_table[i]);
}
free(tile_table);
free(att);
throw;
}
as->layouts = std::move(layouts);
as->size_x = size_x;
as->size_y = size_y;
break;
}
@ -8726,18 +8679,6 @@ static void ResetCustomHouses()
static void ResetCustomAirports()
{
for (GRFFile * const file : _grf_files) {
for (auto &as : file->airportspec) {
if (as != nullptr) {
/* We need to remove the tiles layouts */
for (int j = 0; j < as->num_table; j++) {
/* remove the individual layouts */
free(as->table[j]);
}
free(as->table);
free(as->depot_table);
free(as->rotation);
}
}
file->airportspec.clear();
file->airtspec.clear();
}

View File

@ -95,11 +95,11 @@ bool AirportSpec::IsAvailable() const
*/
bool AirportSpec::IsWithinMapBounds(uint8_t table, TileIndex tile) const
{
if (table >= this->num_table) return false;
if (table >= this->layouts.size()) return false;
uint8_t w = this->size_x;
uint8_t h = this->size_y;
if (this->rotation[table] == DIR_E || this->rotation[table] == DIR_W) Swap(w, h);
if (this->layouts[table].rotation == DIR_E || this->layouts[table].rotation == DIR_W) Swap(w, h);
return TileX(tile) + w < Map::SizeX() &&
TileY(tile) + h < Map::SizeY();

View File

@ -94,16 +94,18 @@ struct HangarTileTable {
uint8_t hangar_num; ///< The hangar to which this tile belongs.
};
struct AirportTileLayout {
std::vector<AirportTileTable> tiles; ///< List of all tiles in this layout.
Direction rotation; ///< The rotation of this layout.
};
/**
* Defines the data structure for an airport.
*/
struct AirportSpec {
const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports
const AirportTileTable * const *table; ///< list of the tiles composing the airport
const Direction *rotation; ///< the rotation of each tiletable
uint8_t num_table; ///< number of elements in the table
const HangarTileTable *depot_table; ///< gives the position of the depots on the airports
uint8_t nof_depots; ///< the number of hangar tiles in this airport
std::vector<AirportTileLayout> layouts; ///< List of layouts composing the airport.
std::span<const HangarTileTable> depots; ///< Position of the depots on the airports.
uint8_t size_x; ///< size of airport in x direction
uint8_t size_y; ///< size of airport in y direction
uint8_t noise_level; ///< noise that this airport generates

View File

@ -138,7 +138,8 @@
if (_settings_game.economy.station_noise_level) {
uint dist;
AirportGetNearestTown(as, as->rotation[0], tile, AirportTileTableIterator(as->table[0], tile), dist);
const auto &layout = as->layouts[0];
AirportGetNearestTown(as, layout.rotation, tile, AirportTileTableIterator(layout.tiles.data(), tile), dist);
return GetAirportNoiseLevelForDistance(as, dist);
}
@ -154,7 +155,8 @@
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
uint dist;
return AirportGetNearestTown(as, as->rotation[0], tile, AirportTileTableIterator(as->table[0], tile), dist)->index;
const auto &layout = as->layouts[0];
return AirportGetNearestTown(as, layout.rotation, tile, AirportTileTableIterator(layout.tiles.data(), tile), dist)->index;
}
/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type)

View File

@ -322,7 +322,7 @@ struct Airport : public TileArea {
/** Check if this airport has at least one hangar. */
inline bool HasHangar() const
{
return this->GetSpec()->nof_depots > 0;
return !this->GetSpec()->depots.empty();
}
/**
@ -357,10 +357,9 @@ struct Airport : public TileArea {
*/
inline TileIndex GetHangarTile(uint hangar_num) const
{
const AirportSpec *as = this->GetSpec();
for (uint i = 0; i < as->nof_depots; i++) {
if (as->depot_table[i].hangar_num == hangar_num) {
return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
for (const auto &depot : this->GetSpec()->depots) {
if (depot.hangar_num == hangar_num) {
return this->GetRotatedTileFromOffset(depot.ti);
}
}
NOT_REACHED();
@ -376,7 +375,7 @@ struct Airport : public TileArea {
{
const AirportSpec *as = this->GetSpec();
const HangarTileTable *htt = GetHangarDataByTile(tile);
return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
return ChangeDir(htt->dir, DirDifference(this->rotation, as->layouts[0].rotation));
}
/**
@ -396,11 +395,10 @@ struct Airport : public TileArea {
{
uint num = 0;
uint counted = 0;
const AirportSpec *as = this->GetSpec();
for (uint i = 0; i < as->nof_depots; i++) {
if (!HasBit(counted, as->depot_table[i].hangar_num)) {
for (const auto &depot : this->GetSpec()->depots) {
if (!HasBit(counted, depot.hangar_num)) {
num++;
SetBit(counted, as->depot_table[i].hangar_num);
SetBit(counted, depot.hangar_num);
}
}
return num;
@ -415,10 +413,9 @@ private:
*/
inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
{
const AirportSpec *as = this->GetSpec();
for (uint i = 0; i < as->nof_depots; i++) {
if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
return as->depot_table + i;
for (const auto &depot : this->GetSpec()->depots) {
if (this->GetRotatedTileFromOffset(depot.ti) == tile) {
return &depot;
}
}
NOT_REACHED();

View File

@ -98,8 +98,8 @@ bool IsHangar(Tile t)
const Station *st = Station::GetByTile(t);
const AirportSpec *as = st->airport.GetSpec();
for (uint i = 0; i < as->nof_depots; i++) {
if (st->airport.GetHangarTile(i) == TileIndex(t)) return true;
for (const auto &depot : as->depots) {
if (st->airport.GetRotatedTileFromOffset(depot.ti) == TileIndex(t)) return true;
}
return false;
@ -2414,10 +2414,10 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
/* Check if a valid, buildable airport was chosen for construction */
const AirportSpec *as = AirportSpec::Get(airport_type);
if (!as->IsAvailable() || layout >= as->num_table) return CMD_ERROR;
if (!as->IsAvailable() || layout >= as->layouts.size()) return CMD_ERROR;
if (!as->IsWithinMapBounds(layout, tile)) return CMD_ERROR;
Direction rotation = as->rotation[layout];
Direction rotation = as->layouts[layout].rotation;
int w = as->size_x;
int h = as->size_y;
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
@ -2427,7 +2427,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
}
AirportTileTableIterator tile_iter(as->table[layout], tile);
AirportTileTableIterator tile_iter(as->layouts[layout].tiles.data(), tile);
CommandCost cost = CheckFlatLandAirport(tile_iter, flags);
if (cost.Failed()) return cost;
@ -2477,7 +2477,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT);
}
for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) {
for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) {
cost.AddCost(_price[PR_BUILD_STATION_AIRPORT]);
}
@ -2493,7 +2493,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) {
for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) {
Tile t(iter);
MakeAirport(t, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID);
SetStationTileRandomBits(t, GB(Random(), 0, 4));
@ -2503,7 +2503,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
}
/* Only call the animation trigger after all tiles have been built */
for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) {
for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) {
AirportTileAnimationTrigger(st, iter, AAT_BUILT);
}

View File

@ -28,7 +28,7 @@
#define MKEND {{-0x80, 0}, 0}
/** Tiles for Country Airfield (small) */
static const AirportTileTable _tile_table_country_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_country_0 = {
MK(0, 0, APT_SMALL_BUILDING_1),
MK(1, 0, APT_SMALL_BUILDING_2),
MK(2, 0, APT_SMALL_BUILDING_3),
@ -44,12 +44,12 @@ static const AirportTileTable _tile_table_country_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_country[] = {
_tile_table_country_0,
static const std::initializer_list<AirportTileLayout> _tile_table_country = {
{ _tile_table_country_0, DIR_N },
};
/** Tiles for Commuter Airfield (small) */
static const AirportTileTable _tile_table_commuter_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_commuter_0 = {
MK(0, 0, APT_TOWER),
MK(1, 0, APT_BUILDING_3),
MK(2, 0, APT_HELIPAD_2_FENCE_NW),
@ -73,12 +73,12 @@ static const AirportTileTable _tile_table_commuter_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_commuter[] = {
_tile_table_commuter_0,
static const std::initializer_list<AirportTileLayout> _tile_table_commuter = {
{ _tile_table_commuter_0, DIR_N },
};
/** Tiles for City Airport (large) */
static const AirportTileTable _tile_table_city_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_city_0 = {
MK(0, 0, APT_BUILDING_1),
MK(1, 0, APT_APRON_FENCE_NW),
MK(2, 0, APT_STAND_1),
@ -118,12 +118,12 @@ static const AirportTileTable _tile_table_city_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_city[] = {
_tile_table_city_0,
static const std::initializer_list<AirportTileLayout> _tile_table_city = {
{ _tile_table_city_0, DIR_N },
};
/** Tiles for Metropolitain Airport (large) - 2 runways */
static const AirportTileTable _tile_table_metropolitan_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_metropolitan_0 = {
MK(0, 0, APT_BUILDING_1),
MK(1, 0, APT_APRON_FENCE_NW),
MK(2, 0, APT_STAND_1),
@ -163,12 +163,12 @@ static const AirportTileTable _tile_table_metropolitan_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_metropolitan[] = {
_tile_table_metropolitan_0,
static const std::initializer_list<AirportTileLayout> _tile_table_metropolitan = {
{ _tile_table_metropolitan_0, DIR_N },
};
/** Tiles for International Airport (large) - 2 runways */
static const AirportTileTable _tile_table_international_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_international_0 = {
MK(0, 0, APT_RUNWAY_END_FENCE_NW),
MK(1, 0, APT_RUNWAY_FENCE_NW),
MK(2, 0, APT_RUNWAY_FENCE_NW),
@ -221,12 +221,12 @@ static const AirportTileTable _tile_table_international_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_international[] = {
_tile_table_international_0,
static const std::initializer_list<AirportTileLayout> _tile_table_international = {
{ _tile_table_international_0, DIR_N },
};
/** Tiles for International Airport (large) - 2 runways */
static const AirportTileTable _tile_table_intercontinental_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_intercontinental_0 = {
MK(0, 0, APT_RADAR_FENCE_NE),
MK(1, 0, APT_RUNWAY_END_FENCE_NE_NW),
MK(2, 0, APT_RUNWAY_FENCE_NW),
@ -329,22 +329,22 @@ static const AirportTileTable _tile_table_intercontinental_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_intercontinental[] = {
_tile_table_intercontinental_0,
static const std::initializer_list<AirportTileLayout> _tile_table_intercontinental = {
{ _tile_table_intercontinental_0, DIR_N },
};
/** Tiles for Heliport */
static const AirportTileTable _tile_table_heliport_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_heliport_0 = {
MK(0, 0, APT_HELIPORT),
MKEND
};
static const AirportTileTable * const _tile_table_heliport[] = {
_tile_table_heliport_0,
static const std::initializer_list<AirportTileLayout> _tile_table_heliport = {
{ _tile_table_heliport_0, DIR_N },
};
/** Tiles for Helidepot */
static const AirportTileTable _tile_table_helidepot_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_helidepot_0 = {
MK(0, 0, APT_LOW_BUILDING_FENCE_N),
MK(1, 0, APT_DEPOT_SE),
MK(0, 1, APT_HELIPAD_2_FENCE_NE_SE),
@ -352,12 +352,12 @@ static const AirportTileTable _tile_table_helidepot_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_helidepot[] = {
_tile_table_helidepot_0,
static const std::initializer_list<AirportTileLayout> _tile_table_helidepot = {
{ _tile_table_helidepot_0, DIR_N },
};
/** Tiles for Helistation */
static const AirportTileTable _tile_table_helistation_0[] = {
static const std::initializer_list<AirportTileTable> _tile_table_helistation_0 = {
MK(0, 0, APT_DEPOT_SE),
MK(1, 0, APT_LOW_BUILDING_FENCE_NW),
MK(2, 0, APT_HELIPAD_3_FENCE_NW),
@ -369,29 +369,25 @@ static const AirportTileTable _tile_table_helistation_0[] = {
MKEND
};
static const AirportTileTable * const _tile_table_helistation[] = {
_tile_table_helistation_0,
};
static const Direction _default_airports_rotation[] = {
DIR_N,
static const std::initializer_list<AirportTileLayout> _tile_table_helistation = {
{ _tile_table_helistation_0, DIR_N },
};
#undef MK
#undef MKEND
/** General AirportSpec definition. */
#define AS_GENERIC(fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \
{fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)}
#define AS_GENERIC(fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \
{fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)}
/** AirportSpec definition for airports without any depot. */
#define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), nullptr, 0, \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, {}, \
size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true)
/** AirportSpec definition for airports with at least one depot. */
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), _airport_depots_##ap_name, lengthof(_airport_depots_##ap_name), \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _airport_depots_##ap_name, \
size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true)
/* The helidepot and helistation have ATP_TTDP_SMALL because they are at ground level */
@ -405,12 +401,12 @@ extern const AirportSpec _origin_airport_specs[] = {
AS(helidepot, 2, 2, 1976, CalendarTime::MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT),
AS(intercontinental, 9, 11, 2002, CalendarTime::MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL),
AS(helistation, 4, 2, 1980, CalendarTime::MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION),
AS_GENERIC(&_airportfta_oilrig, nullptr, _default_airports_rotation, 0, nullptr, 0, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false),
AS_GENERIC(&_airportfta_oilrig, {}, {}, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false),
};
static_assert(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs));
const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, nullptr, _default_airports_rotation, 0, nullptr, 0, 0, 0, 0, 0, CalendarTime::MIN_YEAR, CalendarTime::MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false);
const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, {}, {}, 0, 0, 0, 0, CalendarTime::MIN_YEAR, CalendarTime::MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false);
#undef AS
#undef AS_ND