MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / TryBuildTownHouse

Function TryBuildTownHouse

src/town_cmd.cpp:2814–2936  ·  view source on GitHub ↗

* Tries to build a house at this tile. * @param t The town the house will belong to. * @param tile The tile to try building on. * @return false iff no house can be built on this tile. */

Source from the content-addressed store, hash-verified

2812 * @return false iff no house can be built on this tile.
2813 */
2814static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
2815{
2816 /* forbidden building here by town layout */
2817 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2818
2819 /* no house allowed at all, bail out */
2820 if (!CanBuildHouseHere(tile, false)) return false;
2821
2822 Slope slope = GetTileSlope(tile);
2823 int maxz = GetTileMaxZ(tile);
2824
2825 /* Get the town zone type of the current tile, as well as the climate.
2826 * This will allow to easily compare with the specs of the new house to build */
2827 HouseZones zones = GetTownRadiusGroup(t, tile);
2828
2829 switch (_settings_game.game_creation.landscape) {
2830 case LandscapeType::Temperate: zones.Set(HouseZone::ClimateTemperate); break;
2831 case LandscapeType::Arctic: zones.Set(maxz > HighestSnowLine() ? HouseZone::ClimateSubarcticAboveSnow : HouseZone::ClimateSubarcticBelowSnow); break;
2832 case LandscapeType::Tropic: zones.Set(HouseZone::ClimateSubtropic); break;
2833 case LandscapeType::Toyland: zones.Set(HouseZone::ClimateToyland); break;
2834 }
2835
2836 /* bits 0-4 are used
2837 * bits 11-15 are used
2838 * bits 5-10 are not used. */
2839 static std::vector<std::pair<HouseID, uint>> probs;
2840 probs.clear();
2841
2842 uint probability_max = 0;
2843
2844 /* Generate a list of all possible houses that can be built. */
2845 for (const auto &hs : HouseSpec::Specs()) {
2846 /* Verify that the candidate house spec matches the current tile status */
2847 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2848
2849 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2850 if (hs.class_id != HOUSE_NO_CLASS) {
2851 /* id_count is always <= class_count, so it doesn't need to be checked */
2852 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2853 } else {
2854 /* If the house has no class, check id_count instead */
2855 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2856 }
2857
2858 uint cur_prob = hs.probability;
2859 probability_max += cur_prob;
2860 probs.emplace_back(hs.Index(), cur_prob);
2861 }
2862
2863 TileIndex base_tile = tile;
2864
2865 while (probability_max > 0) {
2866 /* Building a multitile building can change the location of tile.
2867 * The building would still be built partially on that tile, but
2868 * its northern tile would be elsewhere. However, if the callback
2869 * fails we would be basing further work from the changed tile.
2870 * So a next 1x1 tile building could be built on the wrong tile. */
2871 tile = base_tile;

Callers 3

TileLoop_TownFunction · 0.85
GrowTownWithExtraHouseFunction · 0.85
GrowTownInTileFunction · 0.85

Calls 15

CanBuildHouseHereFunction · 0.85
GetTileSlopeFunction · 0.85
GetTileMaxZFunction · 0.85
GetTownRadiusGroupFunction · 0.85
HighestSnowLineFunction · 0.85
RandomRangeFunction · 0.85
CheckTownBuild2x2HouseFunction · 0.85
CheckTownBuild2HouseFunction · 0.85
GetHouseCallbackFunction · 0.85
BuildTownHouseFunction · 0.85

Tested by

no test coverage detected