* Add all new houses to the house array. House properties can be set at any * time in the GRF file, so we can only add a house spec to the house array * after the file has finished loading. We also need to check the dates, due to * the TTDPatch behaviour described below that we need to emulate. */
| 1036 | * the TTDPatch behaviour described below that we need to emulate. |
| 1037 | */ |
| 1038 | static void FinaliseHouseArray() |
| 1039 | { |
| 1040 | /* If there are no houses with start dates before 1930, then all houses |
| 1041 | * with start dates of 1930 have them reset to 0. This is in order to be |
| 1042 | * compatible with TTDPatch, where if no houses have start dates before |
| 1043 | * 1930 and the date is before 1930, the game pretends that this is 1930. |
| 1044 | * If there have been any houses defined with start dates before 1930 then |
| 1045 | * the dates are left alone. |
| 1046 | * On the other hand, why 1930? Just 'fix' the houses with the lowest |
| 1047 | * minimum introduction date to 0. |
| 1048 | */ |
| 1049 | for (auto &file : _grf_files) { |
| 1050 | if (file.housespec.empty()) continue; |
| 1051 | |
| 1052 | size_t num_houses = file.housespec.size(); |
| 1053 | for (size_t i = 0; i < num_houses; i++) { |
| 1054 | auto &hs = file.housespec[i]; |
| 1055 | |
| 1056 | if (hs == nullptr) continue; |
| 1057 | |
| 1058 | const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr); |
| 1059 | const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr); |
| 1060 | const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr); |
| 1061 | |
| 1062 | if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue; |
| 1063 | |
| 1064 | _house_mngr.SetEntitySpec(std::move(*hs)); |
| 1065 | } |
| 1066 | |
| 1067 | /* Won't be used again */ |
| 1068 | file.housespec.clear(); |
| 1069 | file.housespec.shrink_to_fit(); |
| 1070 | } |
| 1071 | |
| 1072 | for (size_t i = 0; i < HouseSpec::Specs().size(); i++) { |
| 1073 | HouseSpec *hs = HouseSpec::Get(i); |
| 1074 | const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr); |
| 1075 | const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr); |
| 1076 | const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr); |
| 1077 | |
| 1078 | /* We need to check all houses again to we are sure that multitile houses |
| 1079 | * did get consecutive IDs and none of the parts are missing. */ |
| 1080 | if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) { |
| 1081 | /* GetHouseNorthPart checks 3 houses that are directly before |
| 1082 | * it in the house pool. If any of those houses have multi-tile |
| 1083 | * flags set it assumes it's part of a multitile house. Since |
| 1084 | * we can have invalid houses in the pool marked as disabled, we |
| 1085 | * don't want to have them influencing valid tiles. As such set |
| 1086 | * building_flags to zero here to make sure any house following |
| 1087 | * this one in the pool is properly handled as 1x1 house. */ |
| 1088 | hs->building_flags = {}; |
| 1089 | } |
| 1090 | |
| 1091 | /* Apply default cargo translation map for unset cargo slots */ |
| 1092 | for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) { |
| 1093 | if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]); |
| 1094 | /* Disable acceptance if cargo type is invalid. */ |
| 1095 | if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0; |
no test coverage detected