From 03a16fa9591847b37ea95162b030a58d5b936883 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Thu, 9 Apr 2020 19:32:24 -0400 Subject: [PATCH] Fix: huge airports broke the appearance of airports in old savegames --- src/airport.h | 4 +++- src/newgrf.cpp | 4 ++-- src/newgrf_airporttiles.cpp | 3 ++- src/saveload/afterload.cpp | 15 +++++++++++++++ src/saveload/extended_ver_sl.cpp | 2 +- src/station_cmd.cpp | 4 +++- src/table/airporttile_ids.h | 2 +- src/table/airporttiles.h | 3 +++ src/table/station_land.h | 16 +++++++++++++++- 9 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/airport.h b/src/airport.h index cc220502eb..a73ccc1c5c 100644 --- a/src/airport.h +++ b/src/airport.h @@ -21,7 +21,9 @@ static const uint MAX_ELEMENTS = 767; ///< maximum number static const uint NUM_AIRPORTTILES_PER_GRF = 255; ///< Number of airport tiles per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on. static const uint NUM_AIRPORTTILES = 256; ///< Total number of airport tiles. -static const uint NEW_AIRPORTTILE_OFFSET = 96; ///< offset of first newgrf airport tile +static const uint NEW_AIRPORTTILE_OFFSET = 74; ///< offset of first newgrf airport tile +static const uint HUGE_AIRPORTTILE_OFFSET = 223; ///< offset of first huge airport tile + static const uint INVALID_AIRPORTTILE = NUM_AIRPORTTILES; ///< id for an invalid airport tile /** Airport types */ diff --git a/src/newgrf.cpp b/src/newgrf.cpp index b263006a8b..ed7983684f 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4687,7 +4687,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i]; byte subs_id = buf->ReadByte(); - if (subs_id >= NEW_AIRPORTTILE_OFFSET) { + if (subs_id >= NEW_AIRPORTTILE_OFFSET && subs_id < HUGE_AIRPORTTILE_OFFSET) { /* The substitute id must be one of the original airport tiles. */ grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i); continue; @@ -4715,7 +4715,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro byte override = buf->ReadByte(); /* The airport tile being overridden must be an original airport tile. */ - if (override >= NEW_AIRPORTTILE_OFFSET) { + if (override >= NEW_AIRPORTTILE_OFFSET && override < HUGE_AIRPORTTILE_OFFSET) { grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i); continue; } diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 3059174a86..e40b4bcfa7 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -58,6 +58,7 @@ void AirportTileSpec::ResetAirportTiles() { memset(&AirportTileSpec::tiles, 0, sizeof(AirportTileSpec::tiles)); memcpy(&AirportTileSpec::tiles, &_origin_airporttile_specs, sizeof(_origin_airporttile_specs)); + memcpy(&AirportTileSpec::tiles[HUGE_AIRPORTTILE_OFFSET], &_huge_airporttile_specs, sizeof(_huge_airporttile_specs)); /* Reset any overrides that have been set. */ _airporttile_mngr.ResetOverride(); @@ -132,7 +133,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 StationGfx gfx = GetAirportGfx(tile); const AirportTileSpec *ats = AirportTileSpec::Get(gfx); - if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type? + if (gfx < NEW_AIRPORTTILE_OFFSET || gfx >= HUGE_AIRPORTTILE_OFFSET) { // Does it belongs to an old type? /* It is an old tile. We have to see if it's been overridden */ if (ats->grf_prop.override == INVALID_AIRPORTTILE) { // has it been overridden? return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 88d9c8d555..b08da25620 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -893,6 +893,21 @@ bool AfterLoadGame() st->airport.type = AT_CIRCLE; } } + if(SlXvIsFeaturePresent(XSLFI_HUGE_AIRPORTS, 1, 2)) { + for (Station *st : Station::Iterate()) { + if (st->airport.tile == INVALID_TILE) continue; + if (st->airport.type != AT_INTERCONTINENTAL2 && st->airport.type != AT_CIRCLE) continue; + const AirportSpec *as = AirportSpec::Get(st->airport.type); + /* Move airport sprites */ + for (AirportTileTableIterator iter(as->table[st->airport.layout], st->airport.tile); iter != INVALID_TILE; ++iter) { + StationGfx gfx = GetStationGfx(iter); + if(gfx >= 74 && gfx < 96) { + SetStationGfx(iter, iter.GetStationGfx()); + } + } + } + } + if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) { /* * Reject huge airports diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 1db3c109f3..90f686dc60 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -113,7 +113,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_FLOW_STAT_FLAGS, XSCF_NULL, 1, 1, "flow_stat_flags", nullptr, nullptr, nullptr }, { XSLFI_SPEED_RESTRICTION, XSCF_NULL, 1, 1, "speed_restriction", nullptr, nullptr, "VESR" }, { XSLFI_STATION_GOODS_EXTRA, XSCF_NULL, 1, 1, "station_goods_extra", nullptr, nullptr, nullptr }, - { XSLFI_HUGE_AIRPORTS, XSCF_NULL, 2, 2, "huge_airports", nullptr, nullptr, nullptr }, + { XSLFI_HUGE_AIRPORTS, XSCF_NULL, 3, 3, "huge_airports", nullptr, nullptr, nullptr }, { XSLFI_TRIP_HISTORY, XSCF_NULL, 1, 1, "trip_history", nullptr, nullptr, nullptr }, { XSLFI_PLANE_TAXI_SPEED, XSCF_NULL, 1, 1, "plane_taxi_speed", nullptr, nullptr, nullptr }, { XSLFI_INDUSTRY_PRODUCTION_HISTORY, XSCF_NULL, 1, 1, "ind_prod_history", nullptr, nullptr, nullptr }, diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 968e2ff9f1..8b1bf5f954 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2988,6 +2988,8 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags) const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx) { + if(st == STATION_AIRPORT && gfx >= HUGE_AIRPORTTILE_OFFSET) + return &_station_display_datas_huge_airport[gfx-HUGE_AIRPORTTILE_OFFSET]; return &_station_display_datas[st][gfx]; } @@ -3103,7 +3105,7 @@ static void DrawTile_Station(TileInfo *ti, DrawTileProcParams params) StationGfx gfx = GetStationGfx(ti->tile); if (IsAirport(ti->tile)) { gfx = GetAirportGfx(ti->tile); - if (gfx >= NEW_AIRPORTTILE_OFFSET) { + if (gfx >= NEW_AIRPORTTILE_OFFSET && gfx < HUGE_AIRPORTTILE_OFFSET) { const AirportTileSpec *ats = AirportTileSpec::Get(gfx); if (ats->grf_prop.spritegroup[0] != nullptr && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats)) { return; diff --git a/src/table/airporttile_ids.h b/src/table/airporttile_ids.h index 9cd396e59d..3892a27f49 100644 --- a/src/table/airporttile_ids.h +++ b/src/table/airporttile_ids.h @@ -85,7 +85,7 @@ enum AirportTiles { APT_APRON_HALF_EAST, APT_APRON_HALF_WEST, APT_GRASS_FENCE_NE_FLAG_2, - APT_NSRUNWAY_4, + APT_NSRUNWAY_4 = HUGE_AIRPORTTILE_OFFSET, APT_NSRUNWAY_4_SW, APT_NSRUNWAY_4_NE, APT_NSRUNWAY_END_FENCE_SW, diff --git a/src/table/airporttiles.h b/src/table/airporttiles.h index df8e7525a6..b6a095117d 100644 --- a/src/table/airporttiles.h +++ b/src/table/airporttiles.h @@ -102,6 +102,9 @@ static const AirportTileSpec _origin_airporttile_specs[] = { AT_NOANIM, AT_NOANIM, AT(3, 1), // APT_GRASS_FENCE_NE_FLAG_2 +}; + +static const AirportTileSpec _huge_airporttile_specs[] = { AT_NOANIM, AT_NOANIM, AT_NOANIM, diff --git a/src/table/station_land.h b/src/table/station_land.h index e4aabef39c..710fb19244 100644 --- a/src/table/station_land.h +++ b/src/table/station_land.h @@ -915,7 +915,10 @@ static const DrawTileSprites _station_display_datas_airport[] = { TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_grass_west) // APT_APRON_HALF_EAST TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_grass_east) // APT_APRON_HALF_WEST TILE_SPRITE_NULL() // APT_GRASS_FENCE_NE_FLAG_2, - TILE_SPRITE_LINE(SPR_NSRUNWAY4, _station_display_nothing) // APT_NSRUNWAY_4 +}; + +static const DrawTileSprites _station_display_datas_huge_airport[] = { + TILE_SPRITE_LINE(SPR_NSRUNWAY4, _station_display_nothing) // APT_NSRUNWAY_4 TILE_SPRITE_LINE(SPR_NSRUNWAY4, _station_display_fence_sw) // APT_NSRUNWAY_4_SW TILE_SPRITE_LINE(SPR_NSRUNWAY4, _station_display_fence_ne) // APT_NSRUNWAY_4_NE TILE_SPRITE_LINE(SPR_NSRUNWAY_END, _station_display_fence_sw) // APT_NSRUNWAY_END_FENCE_SW @@ -937,6 +940,17 @@ static const DrawTileSprites _station_display_datas_airport[] = { TILE_SPRITE_LINE(SPR_NSRUNWAY_END, _station_display_fence_ne_nw) // APT_NSRUNWAY_END_NE_NW TILE_SPRITE_LINE(SPR_NSRUNWAY_END, _station_display_fence_se_sw) // APT_NSRUNWAY_END_SE_SW TILE_SPRITE_LINE(SPR_NSRUNWAY_END, _station_display_fence_nw_sw) // APT_NSRUNWAY_END_NW_SW + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() }; static const DrawTileSprites _station_display_datas_airport_radar_grass_fence_sw[] = {