mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-07-15 16:45:08 +01:00
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:
parent
65c9df49d9
commit
cf96d49ced
@ -277,7 +277,7 @@ public:
|
|||||||
const AirportSpec *as = ac->GetSpec(_selected_airport_index);
|
const AirportSpec *as = ac->GetSpec(_selected_airport_index);
|
||||||
if (as->IsAvailable()) {
|
if (as->IsAvailable()) {
|
||||||
/* Ensure the airport layout is valid. */
|
/* 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;
|
selectFirstAirport = false;
|
||||||
this->UpdateSelectSize();
|
this->UpdateSelectSize();
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ public:
|
|||||||
StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_LAYOUT_NAME);
|
StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_LAYOUT_NAME);
|
||||||
if (string != STR_UNDEFINED) {
|
if (string != STR_UNDEFINED) {
|
||||||
SetDParam(0, string);
|
SetDParam(0, string);
|
||||||
} else if (as->num_table > 1) {
|
} else if (as->layouts.size() > 1) {
|
||||||
SetDParam(0, STR_STATION_BUILD_AIRPORT_LAYOUT_NAME);
|
SetDParam(0, STR_STATION_BUILD_AIRPORT_LAYOUT_NAME);
|
||||||
SetDParam(1, _selected_airport_layout + 1);
|
SetDParam(1, _selected_airport_layout + 1);
|
||||||
}
|
}
|
||||||
@ -348,7 +348,7 @@ public:
|
|||||||
for (int i = 0; i < NUM_AIRPORTS; i++) {
|
for (int i = 0; i < NUM_AIRPORTS; i++) {
|
||||||
const AirportSpec *as = AirportSpec::Get(i);
|
const AirportSpec *as = AirportSpec::Get(i);
|
||||||
if (!as->enabled) continue;
|
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);
|
SpriteID sprite = GetCustomAirportSprite(as, layout);
|
||||||
if (sprite != 0) {
|
if (sprite != 0) {
|
||||||
Dimension d = GetSpriteSize(sprite);
|
Dimension d = GetSpriteSize(sprite);
|
||||||
@ -364,7 +364,7 @@ public:
|
|||||||
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
|
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
|
||||||
const AirportSpec *as = AirportSpec::Get(i);
|
const AirportSpec *as = AirportSpec::Get(i);
|
||||||
if (!as->enabled) continue;
|
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);
|
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
|
||||||
if (string == STR_UNDEFINED) continue;
|
if (string == STR_UNDEFINED) continue;
|
||||||
|
|
||||||
@ -474,14 +474,14 @@ public:
|
|||||||
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
|
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
|
||||||
int w = as->size_x;
|
int w = as->size_x;
|
||||||
int h = as->size_y;
|
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);
|
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
|
||||||
SetTileSelectSize(w, h);
|
SetTileSelectSize(w, h);
|
||||||
|
|
||||||
this->preview_sprite = GetCustomAirportSprite(as, _selected_airport_layout);
|
this->preview_sprite = GetCustomAirportSprite(as, _selected_airport_layout);
|
||||||
|
|
||||||
this->SetWidgetDisabledState(WID_AP_LAYOUT_DECREASE, _selected_airport_layout == 0);
|
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;
|
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);
|
if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
|
||||||
|
127
src/newgrf.cpp
127
src/newgrf.cpp
@ -3861,32 +3861,6 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
|
|||||||
return ret;
|
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
|
* Define properties for airports
|
||||||
* @param airport Local ID of the airport.
|
* @param airport Local ID of the airport.
|
||||||
@ -3942,44 +3916,38 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
|
|||||||
as->grf_prop.grffile = _cur.grffile;
|
as->grf_prop.grffile = _cur.grffile;
|
||||||
/* override the default airport */
|
/* override the default airport */
|
||||||
_airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
|
_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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x0A: { // Set airport layout
|
case 0x0A: { // Set airport layout
|
||||||
uint8_t old_num_table = as->num_table;
|
uint8_t num_layouts = buf->ReadByte();
|
||||||
free(as->rotation);
|
buf->ReadDWord(); // Total size of definition, unneeded.
|
||||||
as->num_table = buf->ReadByte(); // Number of layaouts
|
uint8_t size_x = 0;
|
||||||
as->rotation = MallocT<Direction>(as->num_table);
|
uint8_t size_y = 0;
|
||||||
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) {
|
std::vector<AirportTileLayout> layouts;
|
||||||
/* Not the same terminator. The one we are using is rather
|
layouts.reserve(num_layouts);
|
||||||
* x = -80, y = 0 . So, adjust it. */
|
|
||||||
att[k].ti.x = -0x80;
|
|
||||||
att[k].ti.y = 0;
|
|
||||||
att[k].gfx = 0;
|
|
||||||
|
|
||||||
size = k + 1;
|
for (uint8_t j = 0; j != num_layouts; ++j) {
|
||||||
copy_from = att;
|
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.
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
att[k].gfx = buf->ReadByte();
|
tile.gfx = buf->ReadByte();
|
||||||
|
|
||||||
if (att[k].gfx == 0xFE) {
|
if (tile.gfx == 0xFE) {
|
||||||
/* Use a new tile from this GRF */
|
/* Use a new tile from this GRF */
|
||||||
int local_tile_id = buf->ReadWord();
|
int local_tile_id = buf->ReadWord();
|
||||||
|
|
||||||
@ -3990,41 +3958,26 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
|
|||||||
GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i);
|
GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i);
|
||||||
} else {
|
} else {
|
||||||
/* Declared as been valid, can be used */
|
/* Declared as been valid, can be used */
|
||||||
att[k].gfx = tempid;
|
tile.gfx = tempid;
|
||||||
}
|
}
|
||||||
} else if (att[k].gfx == 0xFF) {
|
} else if (tile.gfx == 0xFF) {
|
||||||
att[k].ti.x = (int8_t)GB(att[k].ti.x, 0, 8);
|
tile.ti.x = static_cast<int8_t>(GB(tile.ti.x, 0, 8));
|
||||||
att[k].ti.y = (int8_t)GB(att[k].ti.y, 0, 8);
|
tile.ti.y = static_cast<int8_t>(GB(tile.ti.y, 0, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
|
/* Determine largest size. */
|
||||||
as->size_x = std::max<uint8_t>(as->size_x, att[k].ti.y + 1);
|
if (layout.rotation == DIR_E || layout.rotation == DIR_W) {
|
||||||
as->size_y = std::max<uint8_t>(as->size_y, att[k].ti.x + 1);
|
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 {
|
} else {
|
||||||
as->size_x = std::max<uint8_t>(as->size_x, att[k].ti.x + 1);
|
size_x = std::max<uint8_t>(size_x, tile.ti.x + 1);
|
||||||
as->size_y = std::max<uint8_t>(as->size_y, att[k].ti.y + 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8726,18 +8679,6 @@ static void ResetCustomHouses()
|
|||||||
static void ResetCustomAirports()
|
static void ResetCustomAirports()
|
||||||
{
|
{
|
||||||
for (GRFFile * const file : _grf_files) {
|
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->airportspec.clear();
|
||||||
file->airtspec.clear();
|
file->airtspec.clear();
|
||||||
}
|
}
|
||||||
|
@ -95,11 +95,11 @@ bool AirportSpec::IsAvailable() const
|
|||||||
*/
|
*/
|
||||||
bool AirportSpec::IsWithinMapBounds(uint8_t table, TileIndex tile) 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 w = this->size_x;
|
||||||
uint8_t h = this->size_y;
|
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() &&
|
return TileX(tile) + w < Map::SizeX() &&
|
||||||
TileY(tile) + h < Map::SizeY();
|
TileY(tile) + h < Map::SizeY();
|
||||||
|
@ -94,16 +94,18 @@ struct HangarTileTable {
|
|||||||
uint8_t hangar_num; ///< The hangar to which this tile belongs.
|
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.
|
* Defines the data structure for an airport.
|
||||||
*/
|
*/
|
||||||
struct AirportSpec {
|
struct AirportSpec {
|
||||||
const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports
|
const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports
|
||||||
const AirportTileTable * const *table; ///< list of the tiles composing the airport
|
std::vector<AirportTileLayout> layouts; ///< List of layouts composing the airport.
|
||||||
const Direction *rotation; ///< the rotation of each tiletable
|
std::span<const HangarTileTable> depots; ///< Position of the depots on the airports.
|
||||||
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
|
|
||||||
uint8_t size_x; ///< size of airport in x direction
|
uint8_t size_x; ///< size of airport in x direction
|
||||||
uint8_t size_y; ///< size of airport in y direction
|
uint8_t size_y; ///< size of airport in y direction
|
||||||
uint8_t noise_level; ///< noise that this airport generates
|
uint8_t noise_level; ///< noise that this airport generates
|
||||||
|
@ -138,7 +138,8 @@
|
|||||||
|
|
||||||
if (_settings_game.economy.station_noise_level) {
|
if (_settings_game.economy.station_noise_level) {
|
||||||
uint dist;
|
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);
|
return GetAirportNoiseLevelForDistance(as, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +155,8 @@
|
|||||||
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
|
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
|
||||||
|
|
||||||
uint dist;
|
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)
|
/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
||||||
|
@ -322,7 +322,7 @@ struct Airport : public TileArea {
|
|||||||
/** Check if this airport has at least one hangar. */
|
/** Check if this airport has at least one hangar. */
|
||||||
inline bool HasHangar() const
|
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
|
inline TileIndex GetHangarTile(uint hangar_num) const
|
||||||
{
|
{
|
||||||
const AirportSpec *as = this->GetSpec();
|
for (const auto &depot : this->GetSpec()->depots) {
|
||||||
for (uint i = 0; i < as->nof_depots; i++) {
|
if (depot.hangar_num == hangar_num) {
|
||||||
if (as->depot_table[i].hangar_num == hangar_num) {
|
return this->GetRotatedTileFromOffset(depot.ti);
|
||||||
return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
@ -376,7 +375,7 @@ struct Airport : public TileArea {
|
|||||||
{
|
{
|
||||||
const AirportSpec *as = this->GetSpec();
|
const AirportSpec *as = this->GetSpec();
|
||||||
const HangarTileTable *htt = GetHangarDataByTile(tile);
|
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 num = 0;
|
||||||
uint counted = 0;
|
uint counted = 0;
|
||||||
const AirportSpec *as = this->GetSpec();
|
for (const auto &depot : this->GetSpec()->depots) {
|
||||||
for (uint i = 0; i < as->nof_depots; i++) {
|
if (!HasBit(counted, depot.hangar_num)) {
|
||||||
if (!HasBit(counted, as->depot_table[i].hangar_num)) {
|
|
||||||
num++;
|
num++;
|
||||||
SetBit(counted, as->depot_table[i].hangar_num);
|
SetBit(counted, depot.hangar_num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
@ -415,10 +413,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
|
inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
|
||||||
{
|
{
|
||||||
const AirportSpec *as = this->GetSpec();
|
for (const auto &depot : this->GetSpec()->depots) {
|
||||||
for (uint i = 0; i < as->nof_depots; i++) {
|
if (this->GetRotatedTileFromOffset(depot.ti) == tile) {
|
||||||
if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
|
return &depot;
|
||||||
return as->depot_table + i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
|
@ -98,8 +98,8 @@ bool IsHangar(Tile t)
|
|||||||
const Station *st = Station::GetByTile(t);
|
const Station *st = Station::GetByTile(t);
|
||||||
const AirportSpec *as = st->airport.GetSpec();
|
const AirportSpec *as = st->airport.GetSpec();
|
||||||
|
|
||||||
for (uint i = 0; i < as->nof_depots; i++) {
|
for (const auto &depot : as->depots) {
|
||||||
if (st->airport.GetHangarTile(i) == TileIndex(t)) return true;
|
if (st->airport.GetRotatedTileFromOffset(depot.ti) == TileIndex(t)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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 */
|
/* Check if a valid, buildable airport was chosen for construction */
|
||||||
const AirportSpec *as = AirportSpec::Get(airport_type);
|
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;
|
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 w = as->size_x;
|
||||||
int h = as->size_y;
|
int h = as->size_y;
|
||||||
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
|
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);
|
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);
|
CommandCost cost = CheckFlatLandAirport(tile_iter, flags);
|
||||||
if (cost.Failed()) return cost;
|
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);
|
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]);
|
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);
|
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);
|
Tile t(iter);
|
||||||
MakeAirport(t, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID);
|
MakeAirport(t, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID);
|
||||||
SetStationTileRandomBits(t, GB(Random(), 0, 4));
|
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 */
|
/* 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);
|
AirportTileAnimationTrigger(st, iter, AAT_BUILT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define MKEND {{-0x80, 0}, 0}
|
#define MKEND {{-0x80, 0}, 0}
|
||||||
|
|
||||||
/** Tiles for Country Airfield (small) */
|
/** 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(0, 0, APT_SMALL_BUILDING_1),
|
||||||
MK(1, 0, APT_SMALL_BUILDING_2),
|
MK(1, 0, APT_SMALL_BUILDING_2),
|
||||||
MK(2, 0, APT_SMALL_BUILDING_3),
|
MK(2, 0, APT_SMALL_BUILDING_3),
|
||||||
@ -44,12 +44,12 @@ static const AirportTileTable _tile_table_country_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_country[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_country = {
|
||||||
_tile_table_country_0,
|
{ _tile_table_country_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for Commuter Airfield (small) */
|
/** 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(0, 0, APT_TOWER),
|
||||||
MK(1, 0, APT_BUILDING_3),
|
MK(1, 0, APT_BUILDING_3),
|
||||||
MK(2, 0, APT_HELIPAD_2_FENCE_NW),
|
MK(2, 0, APT_HELIPAD_2_FENCE_NW),
|
||||||
@ -73,12 +73,12 @@ static const AirportTileTable _tile_table_commuter_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_commuter[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_commuter = {
|
||||||
_tile_table_commuter_0,
|
{ _tile_table_commuter_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for City Airport (large) */
|
/** 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(0, 0, APT_BUILDING_1),
|
||||||
MK(1, 0, APT_APRON_FENCE_NW),
|
MK(1, 0, APT_APRON_FENCE_NW),
|
||||||
MK(2, 0, APT_STAND_1),
|
MK(2, 0, APT_STAND_1),
|
||||||
@ -118,12 +118,12 @@ static const AirportTileTable _tile_table_city_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_city[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_city = {
|
||||||
_tile_table_city_0,
|
{ _tile_table_city_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for Metropolitain Airport (large) - 2 runways */
|
/** 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(0, 0, APT_BUILDING_1),
|
||||||
MK(1, 0, APT_APRON_FENCE_NW),
|
MK(1, 0, APT_APRON_FENCE_NW),
|
||||||
MK(2, 0, APT_STAND_1),
|
MK(2, 0, APT_STAND_1),
|
||||||
@ -163,12 +163,12 @@ static const AirportTileTable _tile_table_metropolitan_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_metropolitan[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_metropolitan = {
|
||||||
_tile_table_metropolitan_0,
|
{ _tile_table_metropolitan_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for International Airport (large) - 2 runways */
|
/** 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(0, 0, APT_RUNWAY_END_FENCE_NW),
|
||||||
MK(1, 0, APT_RUNWAY_FENCE_NW),
|
MK(1, 0, APT_RUNWAY_FENCE_NW),
|
||||||
MK(2, 0, APT_RUNWAY_FENCE_NW),
|
MK(2, 0, APT_RUNWAY_FENCE_NW),
|
||||||
@ -221,12 +221,12 @@ static const AirportTileTable _tile_table_international_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_international[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_international = {
|
||||||
_tile_table_international_0,
|
{ _tile_table_international_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for International Airport (large) - 2 runways */
|
/** 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(0, 0, APT_RADAR_FENCE_NE),
|
||||||
MK(1, 0, APT_RUNWAY_END_FENCE_NE_NW),
|
MK(1, 0, APT_RUNWAY_END_FENCE_NE_NW),
|
||||||
MK(2, 0, APT_RUNWAY_FENCE_NW),
|
MK(2, 0, APT_RUNWAY_FENCE_NW),
|
||||||
@ -329,22 +329,22 @@ static const AirportTileTable _tile_table_intercontinental_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_intercontinental[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_intercontinental = {
|
||||||
_tile_table_intercontinental_0,
|
{ _tile_table_intercontinental_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for Heliport */
|
/** 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),
|
MK(0, 0, APT_HELIPORT),
|
||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_heliport[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_heliport = {
|
||||||
_tile_table_heliport_0,
|
{ _tile_table_heliport_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for Helidepot */
|
/** 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(0, 0, APT_LOW_BUILDING_FENCE_N),
|
||||||
MK(1, 0, APT_DEPOT_SE),
|
MK(1, 0, APT_DEPOT_SE),
|
||||||
MK(0, 1, APT_HELIPAD_2_FENCE_NE_SE),
|
MK(0, 1, APT_HELIPAD_2_FENCE_NE_SE),
|
||||||
@ -352,12 +352,12 @@ static const AirportTileTable _tile_table_helidepot_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_helidepot[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_helidepot = {
|
||||||
_tile_table_helidepot_0,
|
{ _tile_table_helidepot_0, DIR_N },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tiles for Helistation */
|
/** 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(0, 0, APT_DEPOT_SE),
|
||||||
MK(1, 0, APT_LOW_BUILDING_FENCE_NW),
|
MK(1, 0, APT_LOW_BUILDING_FENCE_NW),
|
||||||
MK(2, 0, APT_HELIPAD_3_FENCE_NW),
|
MK(2, 0, APT_HELIPAD_3_FENCE_NW),
|
||||||
@ -369,29 +369,25 @@ static const AirportTileTable _tile_table_helistation_0[] = {
|
|||||||
MKEND
|
MKEND
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AirportTileTable * const _tile_table_helistation[] = {
|
static const std::initializer_list<AirportTileLayout> _tile_table_helistation = {
|
||||||
_tile_table_helistation_0,
|
{ _tile_table_helistation_0, DIR_N },
|
||||||
};
|
|
||||||
|
|
||||||
static const Direction _default_airports_rotation[] = {
|
|
||||||
DIR_N,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef MK
|
#undef MK
|
||||||
#undef MKEND
|
#undef MKEND
|
||||||
|
|
||||||
/** General AirportSpec definition. */
|
/** 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) \
|
#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, 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)}
|
{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. */
|
/** 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) \
|
#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)
|
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. */
|
/** 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) \
|
#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)
|
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 */
|
/* 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(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(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(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));
|
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
|
||||||
#undef AS_ND
|
#undef AS_ND
|
||||||
|
Loading…
Reference in New Issue
Block a user