* Check if a given housespec is valid and disable it if it's not. * The housespecs that follow it are used to check the validity of * multitile houses. * @param hs The housespec to check. * @param next1 The housespec that follows \c hs. * @param next2 The housespec that follows \c next1. * @param next3 The housespec that follows \c next2. * @param filename The filename of the newgrf this ho
| 965 | * @return Whether the given housespec is valid. |
| 966 | */ |
| 967 | static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename) |
| 968 | { |
| 969 | if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && |
| 970 | (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) || |
| 971 | (hs.building_flags.Any(BUILDING_HAS_4_TILES) && |
| 972 | (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) || |
| 973 | next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) { |
| 974 | hs.enabled = false; |
| 975 | if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id); |
| 976 | return false; |
| 977 | } |
| 978 | |
| 979 | /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs. |
| 980 | * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house. |
| 981 | * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */ |
| 982 | if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) || |
| 983 | (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) { |
| 984 | hs.enabled = false; |
| 985 | if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs.grf_prop.local_id); |
| 986 | return false; |
| 987 | } |
| 988 | |
| 989 | /* Substitute type is also used for override, and having an override with a different size causes crashes. |
| 990 | * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/ |
| 991 | if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) { |
| 992 | hs.enabled = false; |
| 993 | Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id); |
| 994 | return false; |
| 995 | } |
| 996 | |
| 997 | /* Make sure that additional parts of multitile houses are not available. */ |
| 998 | if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) { |
| 999 | hs.enabled = false; |
| 1000 | if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs.grf_prop.local_id); |
| 1001 | return false; |
| 1002 | } |
| 1003 | |
| 1004 | return true; |
| 1005 | } |
| 1006 | |
| 1007 | /** |
| 1008 | * Make sure there is at least one house available in the year 0 for the given |
no test coverage detected