diff --git a/src/genworld.cpp b/src/genworld.cpp index d16a017c1f..081a7d65a7 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -37,6 +37,8 @@ #include "error.h" #include "game/game.hpp" #include "game/game_instance.hpp" +#include "newgrf_railtype.h" +#include "newgrf_roadtype.h" #include "string_func.h" #include "thread.h" #include "tgp.h" @@ -320,6 +322,8 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti /* Load the right landscape stuff, and the NewGRFs! */ GfxLoadSprites(); + SetCurrentRailTypeLabelList(); + SetCurrentRoadTypeLabelList(); InitializeBuildingCounts(); LoadStringWidthTable(); diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 2c1d0cc216..72708dd470 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -329,4 +329,11 @@ struct GRFFileProps : GRFFilePropsBase<1> { uint16_t override; ///< id of the entity been replaced by }; +/** Container for a label for rail or road type conversion. */ +template +struct LabelObject { + T label = {}; ///< Label of rail or road type. + uint8_t subtype = 0; ///< Subtype of type (road or tram). +}; + #endif /* NEWGRF_COMMONS_H */ diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index f6ca99148d..20865e33be 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -14,6 +14,7 @@ #include "timer/timer_game_calendar.h" #include "depot_base.h" #include "town.h" +#include "tunnelbridge_map.h" #include "safeguards.h" @@ -174,3 +175,73 @@ uint8_t GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile) /* If not found, return as invalid */ return 0xFF; } + +std::vector> _railtype_list; + +/** + * Test if any saved rail type labels are different to the currently loaded + * rail types. Rail types stored in the map will be converted if necessary. + */ +void ConvertRailTypes() +{ + std::vector railtype_conversion_map; + bool needs_conversion = false; + + for (auto it = std::begin(_railtype_list); it != std::end(_railtype_list); ++it) { + RailType rt = GetRailTypeByLabel(it->label); + if (rt == INVALID_RAILTYPE) { + rt = RAILTYPE_RAIL; + } + + railtype_conversion_map.push_back(rt); + + /* Conversion is needed if the rail type is in a different position than the list. */ + if (it->label != 0 && rt != std::distance(std::begin(_railtype_list), it)) needs_conversion = true; + } + + if (!needs_conversion) return; + + for (const auto t : Map::Iterate()) { + switch (GetTileType(t)) { + case MP_RAILWAY: + SetRailType(t, railtype_conversion_map[GetRailType(t)]); + break; + + case MP_ROAD: + if (IsLevelCrossing(t)) { + SetRailType(t, railtype_conversion_map[GetRailType(t)]); + } + break; + + case MP_STATION: + if (HasStationRail(t)) { + SetRailType(t, railtype_conversion_map[GetRailType(t)]); + } + break; + + case MP_TUNNELBRIDGE: + if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { + SetRailType(t, railtype_conversion_map[GetRailType(t)]); + } + break; + + default: + break; + } + } +} + +/** Populate railtype label list with current values. */ +void SetCurrentRailTypeLabelList() +{ + _railtype_list.clear(); + + for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + _railtype_list.push_back({GetRailTypeInfo(rt)->label, 0}); + } +} + +void ClearRailTypeLabelList() +{ + _railtype_list.clear(); +} diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h index ca48a40c8d..e0d36349ca 100644 --- a/src/newgrf_railtype.h +++ b/src/newgrf_railtype.h @@ -59,4 +59,8 @@ SpriteID GetCustomSignalSprite(const RailTypeInfo *rti, TileIndex tile, SignalTy RailType GetRailTypeTranslation(uint8_t railtype, const GRFFile *grffile); uint8_t GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile); +void ConvertRailTypes(); +void SetCurrentRailTypeLabelList(); +void ClearRailTypeLabelList(); + #endif /* NEWGRF_RAILTYPE_H */ diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index 11aaa8ffde..01e40f3e76 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -14,6 +14,7 @@ #include "timer/timer_game_calendar.h" #include "depot_base.h" #include "town.h" +#include "tunnelbridge_map.h" #include "safeguards.h" @@ -167,3 +168,67 @@ uint8_t GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile) /* If not found, return as invalid */ return 0xFF; } + +std::vector> _roadtype_list; + +/** + * Test if any saved road type labels are different to the currently loaded + * road types. Road types stored in the map will be converted if necessary. + */ +void ConvertRoadTypes() +{ + std::vector roadtype_conversion_map; + bool needs_conversion = false; + for (auto it = std::begin(_roadtype_list); it != std::end(_roadtype_list); ++it) { + RoadType rt = GetRoadTypeByLabel(it->label); + if (rt == INVALID_ROADTYPE || GetRoadTramType(rt) != it->subtype) { + rt = it->subtype ? ROADTYPE_TRAM : ROADTYPE_ROAD; + } + + roadtype_conversion_map.push_back(rt); + + /* Conversion is needed if the road type is in a different position than the list. */ + if (it->label != 0 && rt != std::distance(std::begin(_roadtype_list), it)) needs_conversion = true; + } + if (!needs_conversion) return; + + for (TileIndex t : Map::Iterate()) { + switch (GetTileType(t)) { + case MP_ROAD: + if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); + break; + + case MP_STATION: + if (IsStationRoadStop(t) || IsRoadWaypoint(t)) { + if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); + } + break; + + case MP_TUNNELBRIDGE: + if (GetTunnelBridgeTransportType(t) == TRANSPORT_ROAD) { + if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); + } + break; + + default: + break; + } + } +} + +/** Populate road type label list with current values. */ +void SetCurrentRoadTypeLabelList() +{ + _roadtype_list.clear(); + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + _roadtype_list.push_back({GetRoadTypeInfo(rt)->label, GetRoadTramType(rt)}); + } +} + +void ClearRoadTypeLabelList() +{ + _roadtype_list.clear(); +} diff --git a/src/newgrf_roadtype.h b/src/newgrf_roadtype.h index 9f0566837a..3fef3bd112 100644 --- a/src/newgrf_roadtype.h +++ b/src/newgrf_roadtype.h @@ -59,4 +59,8 @@ SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSp RoadType GetRoadTypeTranslation(RoadTramType rtt, uint8_t tracktype, const GRFFile *grffile); uint8_t GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile); +void ConvertRoadTypes(); +void SetCurrentRoadTypeLabelList(); +void ClearRoadTypeLabelList(); + #endif /* NEWGRF_ROADTYPE_H */ diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 03789db56f..6875cd9ca4 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -15,134 +15,13 @@ #include "saveload_internal.h" #include "../rail.h" #include "../road.h" -#include "../station_map.h" -#include "../tunnelbridge_map.h" +#include "../newgrf_railtype.h" +#include "../newgrf_roadtype.h" #include "../safeguards.h" -/** Container for a label for rail or road type conversion. */ -template -struct LabelObject { - T label = {}; ///< Label of rail or road type. - uint8_t subtype = 0; ///< Subtype of type (road or tram). -}; - -static std::vector> _railtype_list; -static std::vector> _roadtype_list; - -/** - * Test if any saved rail type labels are different to the currently loaded - * rail types. Rail types stored in the map will be converted if necessary. - */ -static void ConvertRailTypes() -{ - std::vector railtype_conversion_map; - bool needs_conversion = false; - - for (auto it = std::begin(_railtype_list); it != std::end(_railtype_list); ++it) { - RailType rt = GetRailTypeByLabel(it->label); - if (rt == INVALID_RAILTYPE) { - rt = RAILTYPE_RAIL; - } - - railtype_conversion_map.push_back(rt); - - /* Conversion is needed if the rail type is in a different position than the list. */ - if (it->label != 0 && rt != std::distance(std::begin(_railtype_list), it)) needs_conversion = true; - } - if (!needs_conversion) return; - - for (const auto t : Map::Iterate()) { - switch (GetTileType(t)) { - case MP_RAILWAY: - SetRailType(t, railtype_conversion_map[GetRailType(t)]); - break; - - case MP_ROAD: - if (IsLevelCrossing(t)) { - SetRailType(t, railtype_conversion_map[GetRailType(t)]); - } - break; - - case MP_STATION: - if (HasStationRail(t)) { - SetRailType(t, railtype_conversion_map[GetRailType(t)]); - } - break; - - case MP_TUNNELBRIDGE: - if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { - SetRailType(t, railtype_conversion_map[GetRailType(t)]); - } - break; - - default: - break; - } - } -} - -/** - * Test if any saved road type labels are different to the currently loaded - * road types. Road types stored in the map will be converted if necessary. - */ -static void ConvertRoadTypes() -{ - std::vector roadtype_conversion_map; - bool needs_conversion = false; - for (auto it = std::begin(_roadtype_list); it != std::end(_roadtype_list); ++it) { - RoadType rt = GetRoadTypeByLabel(it->label); - if (rt == INVALID_ROADTYPE || GetRoadTramType(rt) != it->subtype) { - rt = it->subtype ? ROADTYPE_TRAM : ROADTYPE_ROAD; - } - - roadtype_conversion_map.push_back(rt); - - /* Conversion is needed if the road type is in a different position than the list. */ - if (it->label != 0 && rt != std::distance(std::begin(_roadtype_list), it)) needs_conversion = true; - } - if (!needs_conversion) return; - - for (TileIndex t : Map::Iterate()) { - switch (GetTileType(t)) { - case MP_ROAD: - if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); - if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); - break; - - case MP_STATION: - if (IsStationRoadStop(t) || IsRoadWaypoint(t)) { - if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); - if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); - } - break; - - case MP_TUNNELBRIDGE: - if (GetTunnelBridgeTransportType(t) == TRANSPORT_ROAD) { - if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); - if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); - } - break; - - default: - break; - } - } -} - -/** Populate label lists with current values. */ -static void SetCurrentLabelLists() -{ - _railtype_list.clear(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - _railtype_list.push_back({GetRailTypeInfo(rt)->label, 0}); - } - - _roadtype_list.clear(); - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - _roadtype_list.push_back({GetRoadTypeInfo(rt)->label, GetRoadTramType(rt)}); - } -} +extern std::vector> _railtype_list; +extern std::vector> _roadtype_list; /** Perform rail type and road type conversion if necessary. */ void AfterLoadLabelMaps() @@ -150,13 +29,8 @@ void AfterLoadLabelMaps() ConvertRailTypes(); ConvertRoadTypes(); - SetCurrentLabelLists(); -} - -void ResetLabelMaps() -{ - _railtype_list.clear(); - _roadtype_list.clear(); + SetCurrentRailTypeLabelList(); + SetCurrentRoadTypeLabelList(); } struct RAILChunkHandler : ChunkHandler { diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 59a8f14490..fdbafb9e24 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -42,6 +42,9 @@ #include "../string_func.h" #include "../fios.h" #include "../error.h" +#include "../newgrf_railtype.h" +#include "../newgrf_roadtype.h" + #include #ifdef __EMSCRIPTEN__ # include @@ -2789,7 +2792,8 @@ extern bool LoadOldSaveGame(const std::string &file); static void ResetSaveloadData() { ResetTempEngineData(); - ResetLabelMaps(); + ClearRailTypeLabelList(); + ClearRoadTypeLabelList(); ResetOldWaypoints(); } diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h index 7e35000c7f..2f35751951 100644 --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.h @@ -29,7 +29,6 @@ void AfterLoadVehiclesPhase2(bool part_of_load); void FixupTrainLengths(); void AfterLoadStations(); void AfterLoadRoadStops(); -void ResetLabelMaps(); void AfterLoadLabelMaps(); void AfterLoadStoryBook(); void AfterLoadLinkGraphs();