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.
master
Peter Nelson 4 weeks ago committed by GitHub
parent 65c9df49d9
commit cf96d49ced
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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);

@ -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();
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;
size = k + 1;
copy_from = att;
break;
}
uint8_t num_layouts = buf->ReadByte();
buf->ReadDWord(); // Total size of definition, unneeded.
uint8_t size_x = 0;
uint8_t size_y = 0;
att[k].gfx = buf->ReadByte();
std::vector<AirportTileLayout> layouts;
layouts.reserve(num_layouts);
if (att[k].gfx == 0xFE) {
/* Use a new tile from this GRF */
int local_tile_id = buf->ReadWord();
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.
/* Read the ID from the _airporttile_mngr. */
uint16_t tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
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;
}
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);
}
tile.gfx = buf->ReadByte();
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);
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 {
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);
/* 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();
}

@ -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();

@ -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

@ -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)

@ -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();

@ -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);
}

@ -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

Loading…
Cancel
Save