1715 * @param tile where the house will be built |
1715 * @param tile where the house will be built |
1716 * @return false iff no house can be built at this tile |
1716 * @return false iff no house can be built at this tile |
1717 */ |
1717 */ |
1718 static bool BuildTownHouse(Town *t, TileIndex tile) |
1718 static bool BuildTownHouse(Town *t, TileIndex tile) |
1719 { |
1719 { |
1720 int i; |
|
1721 uint bitmask; |
|
1722 HouseID house; |
|
1723 Slope slope; |
|
1724 uint z; |
|
1725 uint oneof = 0; |
|
1726 HouseSpec *hs; |
|
1727 |
|
1728 /* no house allowed at all, bail out */ |
1720 /* no house allowed at all, bail out */ |
1729 if (!CanBuildHouseHere(tile, false)) return false; |
1721 if (!CanBuildHouseHere(tile, false)) return false; |
1730 |
1722 |
1731 /* Above snow? */ |
1723 uint z; |
1732 slope = GetTileSlope(tile, &z); |
1724 Slope slope = GetTileSlope(tile, &z); |
1733 |
1725 |
1734 /* Get the town zone type of the current tile, as well as the climate. |
1726 /* Get the town zone type of the current tile, as well as the climate. |
1735 * This will allow to easily compare with the specs of the new house to build */ |
1727 * This will allow to easily compare with the specs of the new house to build */ |
1736 { |
1728 HouseZonesBits rad = GetTownRadiusGroup(t, tile); |
1737 HouseZonesBits rad = GetTownRadiusGroup(t, tile); |
1729 |
1738 |
1730 /* Above snow? */ |
1739 int land = _opt.landscape; |
1731 int land = _opt.landscape; |
1740 if (land == LT_ARCTIC && z >= _opt.snow_line) land = -1; |
1732 if (land == LT_ARCTIC && z >= _opt.snow_line) land = -1; |
1741 |
1733 |
1742 bitmask = (1 << rad) + (1 << (land + 12)); |
1734 uint bitmask = (1 << rad) + (1 << (land + 12)); |
1743 } |
|
1744 |
1735 |
1745 /* bits 0-4 are used |
1736 /* bits 0-4 are used |
1746 * bits 11-15 are used |
1737 * bits 11-15 are used |
1747 * bits 5-10 are not used. */ |
1738 * bits 5-10 are not used. */ |
1748 { |
1739 HouseID houses[HOUSE_MAX]; |
1749 HouseID houses[HOUSE_MAX]; |
1740 uint num = 0; |
1750 int num = 0; |
1741 uint probs[HOUSE_MAX]; |
1751 uint probs[HOUSE_MAX]; |
1742 uint probability_max = 0; |
1752 uint probability_max = 0; |
1743 |
1753 |
1744 /* Generate a list of all possible houses that can be built. */ |
1754 /* Generate a list of all possible houses that can be built. */ |
1745 for (uint i = 0; i < HOUSE_MAX; i++) { |
1755 for (i = 0; i < HOUSE_MAX; i++) { |
1746 HouseSpec *hs = GetHouseSpecs(i); |
1756 hs = GetHouseSpecs(i); |
1747 /* Verify that the candidate house spec matches the current tile status */ |
1757 /* Verify that the candidate house spec matches the current tile status */ |
1748 if ((~hs->building_availability & bitmask) == 0 && hs->enabled) { |
1758 if ((~hs->building_availability & bitmask) == 0 && hs->enabled) { |
1749 /* Without NewHouses, all houses have probability '1' */ |
1759 /* Without NewHouses, all houses have probability '1' */ |
1750 uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1); |
1760 uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1); |
1751 probability_max += cur_prob; |
1761 probability_max += cur_prob; |
1752 probs[num] = cur_prob; |
1762 probs[num] = cur_prob; |
1753 houses[num++] = (HouseID)i; |
1763 houses[num++] = (HouseID)i; |
1754 } |
|
1755 } |
|
1756 |
|
1757 uint maxz = GetTileMaxZ(tile); |
|
1758 |
|
1759 while (probability_max > 0) { |
|
1760 uint r = RandomRange(probability_max); |
|
1761 uint i; |
|
1762 for (i = 0; i < num; i++) { |
|
1763 if (probs[i] > r) break; |
|
1764 r -= probs[i]; |
|
1765 } |
|
1766 |
|
1767 HouseID house = houses[i]; |
|
1768 probability_max -= probs[i]; |
|
1769 |
|
1770 /* remove tested house from the set */ |
|
1771 num--; |
|
1772 houses[i] = houses[num]; |
|
1773 probs[i] = probs[num]; |
|
1774 |
|
1775 HouseSpec *hs = GetHouseSpecs(house); |
|
1776 |
|
1777 if (_loaded_newgrf_features.has_newhouses) { |
|
1778 if (hs->override != 0) { |
|
1779 house = hs->override; |
|
1780 hs = GetHouseSpecs(house); |
1764 } |
1781 } |
1765 } |
1782 |
1766 |
1783 if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue; |
1767 uint maxz = GetTileMaxZ(tile); |
1784 |
1768 |
1785 if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { |
1769 while (probability_max > 0) { |
1786 uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile); |
1770 uint r = RandomRange(probability_max); |
1787 if (callback_res != CALLBACK_FAILED && callback_res == 0) continue; |
1771 for (i = 0; i < num; i++) { |
|
1772 if (probs[i] > r) break; |
|
1773 r -= probs[i]; |
|
1774 } |
1788 } |
1775 |
1789 } |
1776 house = houses[i]; |
1790 |
1777 probability_max -= probs[i]; |
1791 if (_cur_year < hs->min_date || _cur_year > hs->max_date) continue; |
1778 |
1792 |
1779 /* remove tested house from the set */ |
1793 /* Special houses that there can be only one of. */ |
1780 num--; |
1794 uint oneof = 0; |
1781 houses[i] = houses[num]; |
1795 |
1782 probs[i] = probs[num]; |
1796 if (hs->building_flags & BUILDING_IS_CHURCH) { |
1783 |
1797 SetBit(oneof, TOWN_HAS_CHURCH); |
1784 hs = GetHouseSpecs(house); |
1798 } else if (hs->building_flags & BUILDING_IS_STADIUM) { |
1785 |
1799 SetBit(oneof, TOWN_HAS_STADIUM); |
1786 if (_loaded_newgrf_features.has_newhouses) { |
1800 } |
1787 if (hs->override != 0) { |
1801 |
1788 house = hs->override; |
1802 if (HASBITS(t->flags12 , oneof)) continue; |
1789 hs = GetHouseSpecs(house); |
1803 |
1790 } |
1804 /* Make sure there is no slope? */ |
1791 |
1805 bool noslope = (hs->building_flags & TILE_NOT_SLOPED) != 0; |
1792 if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue; |
1806 if (noslope && slope != SLOPE_FLAT) continue; |
1793 |
1807 |
1794 if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { |
1808 if (hs->building_flags & TILE_SIZE_2x2) { |
1795 uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile); |
1809 if (!CheckFree2x2Area(tile, maxz, noslope) && |
1796 if (callback_res != CALLBACK_FAILED && callback_res == 0) continue; |
1810 !CheckFree2x2Area(tile += TileDiffXY(-1, 0), maxz, noslope) && |
1797 } |
1811 !CheckFree2x2Area(tile += TileDiffXY( 0, -1), maxz, noslope) && |
|
1812 !CheckFree2x2Area(tile += TileDiffXY( 1, 0), maxz, noslope)) { |
|
1813 /* return to the original tile */ |
|
1814 tile += TileDiffXY(0, 1); |
|
1815 continue; /* continue the while() loop */ |
1798 } |
1816 } |
1799 |
1817 } else if (hs->building_flags & TILE_SIZE_2x1) { |
1800 if (_cur_year < hs->min_date || _cur_year > hs->max_date) continue; |
1818 /* 'tile' is already checked above - CanBuildHouseHere() and slope test */ |
1801 |
1819 if (!CheckBuildHouseSameZ(tile + TileDiffXY(1, 0), maxz, noslope)) { |
1802 /* Special houses that there can be only one of. */ |
1820 if (!CheckBuildHouseSameZ(tile + TileDiffXY(-1, 0), maxz, noslope)) continue; |
1803 if (hs->building_flags & BUILDING_IS_CHURCH) { |
1821 tile += TileDiffXY(-1, 0); |
1804 SetBit(oneof, TOWN_HAS_CHURCH); |
1822 } |
1805 } else if (hs->building_flags & BUILDING_IS_STADIUM) { |
1823 } else if (hs->building_flags & TILE_SIZE_1x2) { |
1806 SetBit(oneof, TOWN_HAS_STADIUM); |
1824 if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, 1), maxz, noslope)) { |
|
1825 if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, -1), maxz, noslope)) continue; |
|
1826 tile += TileDiffXY(0, -1); |
|
1827 } |
|
1828 } |
|
1829 |
|
1830 /* build the house */ |
|
1831 t->num_houses++; |
|
1832 IncreaseBuildingCount(t, house); |
|
1833 |
|
1834 /* Special houses that there can be only one of. */ |
|
1835 t->flags12 |= oneof; |
|
1836 |
|
1837 byte construction_counter = 0; |
|
1838 byte construction_stage = 0; |
|
1839 |
|
1840 if (_generating_world) { |
|
1841 uint32 r = Random(); |
|
1842 |
|
1843 construction_stage = TOWN_HOUSE_COMPLETED; |
|
1844 if (Chance16(1, 7)) construction_stage = GB(r, 0, 2); |
|
1845 |
|
1846 if (construction_stage == TOWN_HOUSE_COMPLETED) { |
|
1847 ChangePopulation(t, hs->population); |
1807 } else { |
1848 } else { |
1808 oneof = 0; |
1849 construction_counter = GB(r, 2, 2); |
1809 } |
1850 } |
1810 |
1851 } |
1811 if (HASBITS(t->flags12 , oneof)) continue; |
1852 |
1812 |
1853 MakeTownHouse(tile, t->index, construction_counter, construction_stage, house, Random()); |
1813 /* Make sure there is no slope? */ |
1854 |
1814 bool noslope = (hs->building_flags & TILE_NOT_SLOPED) != 0; |
1855 return true; |
1815 if (noslope && slope != SLOPE_FLAT) continue; |
|
1816 |
|
1817 if (hs->building_flags & TILE_SIZE_2x2) { |
|
1818 if (!CheckFree2x2Area(tile, maxz, noslope) && |
|
1819 !CheckFree2x2Area(tile += TileDiffXY(-1, 0), maxz, noslope) && |
|
1820 !CheckFree2x2Area(tile += TileDiffXY( 0, -1), maxz, noslope) && |
|
1821 !CheckFree2x2Area(tile += TileDiffXY( 1, 0), maxz, noslope)) { |
|
1822 /* return to the original tile */ |
|
1823 tile += TileDiffXY(0, 1); |
|
1824 continue; /* continue the while() loop */ |
|
1825 } |
|
1826 } else if (hs->building_flags & TILE_SIZE_2x1) { |
|
1827 /* 'tile' is already checked above - CanBuildHouseHere() and slope test */ |
|
1828 if (!CheckBuildHouseSameZ(tile + TileDiffXY(1, 0), maxz, noslope)) { |
|
1829 if (!CheckBuildHouseSameZ(tile + TileDiffXY(-1, 0), maxz, noslope)) continue; |
|
1830 tile += TileDiffXY(-1, 0); |
|
1831 } |
|
1832 } else if (hs->building_flags & TILE_SIZE_1x2) { |
|
1833 if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, 1), maxz, noslope)) { |
|
1834 if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, -1), maxz, noslope)) continue; |
|
1835 tile += TileDiffXY(0, -1); |
|
1836 } |
|
1837 } |
|
1838 |
|
1839 /* build the house */ |
|
1840 t->num_houses++; |
|
1841 IncreaseBuildingCount(t, house); |
|
1842 |
|
1843 /* Special houses that there can be only one of. */ |
|
1844 t->flags12 |= oneof; |
|
1845 |
|
1846 { |
|
1847 byte construction_counter = 0, construction_stage = 0; |
|
1848 |
|
1849 if (_generating_world) { |
|
1850 uint32 r = Random(); |
|
1851 |
|
1852 construction_stage = TOWN_HOUSE_COMPLETED; |
|
1853 if (Chance16(1, 7)) construction_stage = GB(r, 0, 2); |
|
1854 |
|
1855 if (construction_stage == TOWN_HOUSE_COMPLETED) { |
|
1856 ChangePopulation(t, hs->population); |
|
1857 } else { |
|
1858 construction_counter = GB(r, 2, 2); |
|
1859 } |
|
1860 } |
|
1861 MakeTownHouse(tile, t->index, construction_counter, construction_stage, house, Random()); |
|
1862 } |
|
1863 |
|
1864 return true; |
|
1865 } |
|
1866 } |
1856 } |
1867 |
1857 |
1868 return false; |
1858 return false; |
1869 } |
1859 } |
1870 |
1860 |