Check for invalid engines */
| 852 | |
| 853 | /** Check for invalid engines */ |
| 854 | static void FinaliseEngineArray() |
| 855 | { |
| 856 | for (Engine *e : Engine::Iterate()) { |
| 857 | if (e->GetGRF() == nullptr) { |
| 858 | auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine); |
| 859 | if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) { |
| 860 | e->info.string_id = STR_NEWGRF_INVALID_ENGINE; |
| 861 | } |
| 862 | } |
| 863 | |
| 864 | /* Do final mapping on variant engine ID. */ |
| 865 | if (e->info.variant_id != EngineID::Invalid()) { |
| 866 | e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base()); |
| 867 | } |
| 868 | |
| 869 | if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue; |
| 870 | |
| 871 | switch (e->type) { |
| 872 | case VEH_TRAIN: |
| 873 | for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) { |
| 874 | AppendCopyableBadgeList(e->badges, GetRailTypeInfo(rt)->badges, GSF_TRAINS); |
| 875 | } |
| 876 | break; |
| 877 | case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->VehInfo<RoadVehicleInfo>().roadtype)->badges, GSF_ROADVEHICLES); break; |
| 878 | default: break; |
| 879 | } |
| 880 | |
| 881 | /* Skip wagons, there livery is defined via the engine */ |
| 882 | if (e->type != VEH_TRAIN || e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON) { |
| 883 | LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr); |
| 884 | SetBit(_loaded_newgrf_features.used_liveries, ls); |
| 885 | /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */ |
| 886 | |
| 887 | if (e->type == VEH_TRAIN) { |
| 888 | SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON); |
| 889 | switch (ls) { |
| 890 | case LS_STEAM: |
| 891 | case LS_DIESEL: |
| 892 | case LS_ELECTRIC: |
| 893 | case LS_MONORAIL: |
| 894 | case LS_MAGLEV: |
| 895 | SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM); |
| 896 | break; |
| 897 | |
| 898 | case LS_DMU: |
| 899 | case LS_EMU: |
| 900 | SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU); |
| 901 | break; |
| 902 | |
| 903 | default: NOT_REACHED(); |
| 904 | } |
| 905 | } |
| 906 | } |
| 907 | } |
| 908 | |
| 909 | /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags |
| 910 | * on variant engine. This is performed separately as all variant engines need to have been resolved. |
| 911 | * Use Floyd's cycle-detection algorithm to handle the case where a cycle is present but does |
no test coverage detected