src/industry_cmd.cpp
branchnoai
changeset 9703 d2a6acdbd665
parent 9701 d1ac22c62f64
child 9704 197cb8c6ae17
equal deleted inserted replaced
9702:e782b59f1f6a 9703:d2a6acdbd665
    29 #include "genworld.h"
    29 #include "genworld.h"
    30 #include "date.h"
    30 #include "date.h"
    31 #include "water_map.h"
    31 #include "water_map.h"
    32 #include "tree_map.h"
    32 #include "tree_map.h"
    33 #include "cargotype.h"
    33 #include "cargotype.h"
       
    34 #include "newgrf.h"
    34 #include "newgrf_commons.h"
    35 #include "newgrf_commons.h"
    35 #include "newgrf_industries.h"
    36 #include "newgrf_industries.h"
    36 #include "newgrf_industrytiles.h"
    37 #include "newgrf_industrytiles.h"
    37 #include "newgrf_callbacks.h"
    38 #include "newgrf_callbacks.h"
    38 #include "misc/autoptr.hpp"
    39 #include "misc/autoptr.hpp"
       
    40 #include "autoslope.h"
    39 
    41 
    40 void ShowIndustryViewWindow(int industry);
    42 void ShowIndustryViewWindow(int industry);
    41 void BuildOilRig(TileIndex tile);
    43 void BuildOilRig(TileIndex tile);
    42 
    44 
    43 static byte _industry_sound_ctr;
    45 static byte _industry_sound_ctr;
   297 	if (image != 0) {
   299 	if (image != 0) {
   298 		AddSortableSpriteToDraw(image,
   300 		AddSortableSpriteToDraw(image,
   299 			(HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal,
   301 			(HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal,
   300 			ti->x + dits->subtile_x,
   302 			ti->x + dits->subtile_x,
   301 			ti->y + dits->subtile_y,
   303 			ti->y + dits->subtile_y,
   302 			dits->width  + 1,
   304 			dits->width,
   303 			dits->height + 1,
   305 			dits->height,
   304 			dits->dz,
   306 			dits->dz,
   305 			ti->z,
   307 			ti->z,
   306 			HASBIT(_transparent_opt, TO_INDUSTRIES));
   308 			HASBIT(_transparent_opt, TO_INDUSTRIES));
   307 
   309 
   308 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
   310 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
  1194 			}
  1196 			}
  1195 		} else {
  1197 		} else {
  1196 			if (!EnsureNoVehicle(cur_tile)) return false;
  1198 			if (!EnsureNoVehicle(cur_tile)) return false;
  1197 			if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false;
  1199 			if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false;
  1198 
  1200 
  1199 			const IndustryTileSpec *its = GetIndustryTileSpec(it->gfx);
  1201 			const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
       
  1202 
  1200 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1203 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1201 
  1204 
  1202 			if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
  1205 			if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
  1203 				if (custom_shape_check != NULL) *custom_shape_check = true;
  1206 				if (custom_shape_check != NULL) *custom_shape_check = true;
  1204 				if (!PerformIndustryTileSlopeCheck(cur_tile, its, type, gfx)) return false;
  1207 				if (!PerformIndustryTileSlopeCheck(cur_tile, its, type, gfx)) return false;
  1690 			}
  1693 			}
  1691 		}
  1694 		}
  1692 	}
  1695 	}
  1693 }
  1696 }
  1694 
  1697 
  1695 /** Change industry production or do closure
       
  1696  * @param i Industry for which changes are performed
       
  1697  */
       
  1698 static void ExtChangeIndustryProduction(Industry *i)
       
  1699 {
       
  1700 	bool closeit = true;
       
  1701 	int j;
       
  1702 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
       
  1703 
       
  1704 	if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
       
  1705 
       
  1706 	if ((indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0) {
       
  1707 		for (j = 0; j < 2 && indspec->produced_cargo[j] != CT_INVALID; j++){
       
  1708 			uint32 r = Random();
       
  1709 			int old_prod, new_prod, percent;
       
  1710 			int mag;
       
  1711 
       
  1712 			new_prod = old_prod = i->production_rate[j];
       
  1713 
       
  1714 			if (CHANCE16I(20, 1024, r)) new_prod -= max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
       
  1715 			/* Chance of increasing becomes better when more is transported */
       
  1716 			if (CHANCE16I(20 + (i->last_month_pct_transported[j] * 20 >> 8), 1024, r >> 16) &&
       
  1717 					((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) == 0 || _opt.landscape != LT_TEMPERATE)) {
       
  1718 				new_prod += max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
       
  1719 			}
       
  1720 
       
  1721 			new_prod = clamp(new_prod, 1, 255);
       
  1722 			/* Do not stop closing the industry when it has the lowest possible production rate */
       
  1723 			if (new_prod == old_prod && old_prod > 1) {
       
  1724 				closeit = false;
       
  1725 				continue;
       
  1726 			}
       
  1727 
       
  1728 			percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
       
  1729 			i->production_rate[j] = new_prod;
       
  1730 
       
  1731 			/* Close the industry when it has the lowest possible production rate */
       
  1732 			if (new_prod > 1) closeit = false;
       
  1733 
       
  1734 			mag = abs(percent);
       
  1735 			if (mag >= 10) {
       
  1736 				SetDParam(2, mag);
       
  1737 				SetDParam(0, GetCargo(indspec->produced_cargo[j])->name);
       
  1738 				SetDParam(1, i->index);
       
  1739 				AddNewsItem(
       
  1740 					percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
       
  1741 					NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ECONOMY, 0),
       
  1742 					i->xy + TileDiffXY(1, 1), 0
       
  1743 				);
       
  1744 			}
       
  1745 		}
       
  1746 	}
       
  1747 
       
  1748 	if ((indspec->life_type & INDUSTRYLIFE_PROCESSING) != 0) {
       
  1749 		if ((byte)(_cur_year - i->last_prod_year) < 5 || !CHANCE16(1, 180)) closeit = false;
       
  1750 	}
       
  1751 
       
  1752 	/* If industry will be closed down, show this */
       
  1753 	if (closeit) {
       
  1754 		i->prod_level = 0;
       
  1755 		SetDParam(0, i->index);
       
  1756 		AddNewsItem(
       
  1757 			indspec->closure_text,
       
  1758 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0),
       
  1759 			i->xy + TileDiffXY(1, 1), 0
       
  1760 		);
       
  1761 	}
       
  1762 }
       
  1763 
       
  1764 
       
  1765 static void UpdateIndustryStatistics(Industry *i)
  1698 static void UpdateIndustryStatistics(Industry *i)
  1766 {
  1699 {
  1767 	byte pct;
  1700 	byte pct;
  1768 	bool refresh = false;
  1701 	bool refresh = false;
  1769 	const IndustrySpec *indsp = GetIndustrySpec(i->type);
  1702 	const IndustrySpec *indsp = GetIndustrySpec(i->type);
  1784 			i->this_month_transported[j] = 0;
  1717 			i->this_month_transported[j] = 0;
  1785 			refresh = true;
  1718 			refresh = true;
  1786 		}
  1719 		}
  1787 	}
  1720 	}
  1788 
  1721 
  1789 	if (refresh)
  1722 	if (refresh) InvalidateWindow(WC_INDUSTRY_VIEW, i->index);
  1790 		InvalidateWindow(WC_INDUSTRY_VIEW, i->index);
       
  1791 
       
  1792 	if (i->prod_level == 0) {
       
  1793 		delete i;
       
  1794 	} else if (_patches.smooth_economy) {
       
  1795 		ExtChangeIndustryProduction(i);
       
  1796 	}
       
  1797 }
  1723 }
  1798 
  1724 
  1799 /** Simple helper that will collect data for the generation of industries */
  1725 /** Simple helper that will collect data for the generation of industries */
  1800 struct ProbabilityHelper {
  1726 struct ProbabilityHelper {
  1801 	uint16 prob;      ///< probability
  1727 	uint16 prob;      ///< probability
  1852 	SetDParam(1, ind->town->index);
  1778 	SetDParam(1, ind->town->index);
  1853 	AddNewsItem(ind_spc->new_industry_text,
  1779 	AddNewsItem(ind_spc->new_industry_text,
  1854 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1780 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1855 }
  1781 }
  1856 
  1782 
  1857 static void ChangeIndustryProduction(Industry *i)
  1783 /**
  1858 {
  1784  * Protects an industry from closure if the appropriate flags and conditions are met
       
  1785  * INDUSTRYBEH_CANCLOSE_LASTINSTANCE must be set (which, by default, it is not) and the
       
  1786  * count of industries of this type must one (or lower) in order to be protected
       
  1787  * against closure.
       
  1788  * @param type IndustryType been queried
       
  1789  * @result true if protection is on, false otherwise (except for oil wells)
       
  1790  */
       
  1791 static bool CheckIndustryCloseDownProtection(IndustryType type)
       
  1792 {
       
  1793 	const IndustrySpec *indspec = GetIndustrySpec(type);
       
  1794 
       
  1795 	/* oil wells (or the industries with that flag set) are always allowed to closedown */
       
  1796 	if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _opt.landscape == LT_TEMPERATE) return false;
       
  1797 	return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE && GetIndustryTypeCount(type) <= 1);
       
  1798 }
       
  1799 
       
  1800 /** Change industry production or do closure
       
  1801  * @param i Industry for which changes are performed
       
  1802  * @param monthly true if it's the monthly call, false if it's the random call
       
  1803  */
       
  1804 static void ChangeIndustryProduction(Industry *i, bool monthly)
       
  1805 {
       
  1806 	extern StringID MapGRFStringID(uint32 grfid, StringID str);
  1859 	StringID str = STR_NULL;
  1807 	StringID str = STR_NULL;
  1860 	int type = i->type;
  1808 	bool closeit = false;
  1861 	const IndustrySpec *indspec = GetIndustrySpec(type);
  1809 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
  1862 
  1810 	bool standard = true;
  1863 	if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
  1811 	bool suppress_message = false;
  1864 
  1812 	byte div = 0;
  1865 	if ((indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0) {
  1813 	byte mul = 0;
  1866 		bool only_decrease = false;
  1814 
  1867 
  1815 	if (HASBIT(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) {
       
  1816 		uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy);
       
  1817 		if (res != CALLBACK_FAILED) {
       
  1818 			standard = false;
       
  1819 			suppress_message = HASBIT(res, 7);
       
  1820 			/* Get the custom message if any */
       
  1821 			if (HASBIT(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
       
  1822 			res = GB(res, 0, 4);
       
  1823 			switch(res) {
       
  1824 				default: NOT_REACHED();
       
  1825 				case 0x0: break;                  // Do nothing, but show the custom message if any
       
  1826 				case 0x1: div = 1; break;         // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
       
  1827 				case 0x2: mul = 1; break;         // Double industry production if it hasn't reached eight times of the original yet.
       
  1828 				case 0x3: closeit = true; break;  // The industry announces imminent closure, and is physically removed from the map next month.
       
  1829 				case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
       
  1830 				case 0x5: case 0x6: case 0x7:     // Divide production by 4, 8, 16
       
  1831 				case 0x8: div = res - 0x5; break; // Divide production by 32
       
  1832 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
       
  1833 				case 0xC: mul = res - 0x9; break; // Multiply production by 32
       
  1834 			}
       
  1835 		}
       
  1836 	}
       
  1837 
       
  1838 	if (standard && monthly != _patches.smooth_economy) return;
       
  1839 
       
  1840 	if (standard && indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
       
  1841 
       
  1842 	if (standard && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0) {
  1868 		/* decrease or increase */
  1843 		/* decrease or increase */
  1869 		if ((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE)
  1844 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  1870 			only_decrease = true;
  1845 
  1871 
  1846 		if (_patches.smooth_economy) {
  1872 		if (only_decrease || CHANCE16(1, 3)) {
  1847 			closeit = true;
  1873 			/* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
  1848 			for (byte j = 0; j < 2 && indspec->produced_cargo[j] != CT_INVALID; j++){
  1874 			if (!only_decrease && (i->last_month_pct_transported[0] > 153) != CHANCE16(1, 3)) {
  1849 				uint32 r = Random();
  1875 				/* Increase production */
  1850 				int old_prod, new_prod, percent;
  1876 				if (i->prod_level != 0x80) {
  1851 				int mag;
  1877 					byte b;
  1852 
  1878 
  1853 				new_prod = old_prod = i->production_rate[j];
  1879 					i->prod_level <<= 1;
  1854 
  1880 
  1855 				if (CHANCE16I(20, 1024, r)) new_prod -= max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
  1881 					b = i->production_rate[0] * 2;
  1856 				/* Chance of increasing becomes better when more is transported */
  1882 					if (i->production_rate[0] >= 128)
  1857 				if (CHANCE16I(20 + (i->last_month_pct_transported[j] * 20 >> 8), 1024, r >> 16) && !only_decrease) {
  1883 						b = 0xFF;
  1858 					new_prod += max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
  1884 					i->production_rate[0] = b;
       
  1885 
       
  1886 					b = i->production_rate[1] * 2;
       
  1887 					if (i->production_rate[1] >= 128)
       
  1888 						b = 0xFF;
       
  1889 					i->production_rate[1] = b;
       
  1890 
       
  1891 					str = indspec->production_up_text;
       
  1892 				}
  1859 				}
  1893 			} else {
  1860 
  1894 				/* Decrease production */
  1861 				new_prod = clamp(new_prod, 1, 255);
  1895 				if (i->prod_level == 4) {
  1862 				/* Do not stop closing the industry when it has the lowest possible production rate */
  1896 					i->prod_level = 0;
  1863 				if (new_prod == old_prod && old_prod > 1) {
  1897 					str = indspec->closure_text;
  1864 					closeit = false;
       
  1865 					continue;
       
  1866 				}
       
  1867 
       
  1868 				percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
       
  1869 				i->production_rate[j] = new_prod;
       
  1870 
       
  1871 				/* Close the industry when it has the lowest possible production rate */
       
  1872 				if (new_prod > 1) closeit = false;
       
  1873 
       
  1874 				mag = abs(percent);
       
  1875 				if (mag >= 10) {
       
  1876 					SetDParam(2, mag);
       
  1877 					SetDParam(0, GetCargo(indspec->produced_cargo[j])->name);
       
  1878 					SetDParam(1, i->index);
       
  1879 					AddNewsItem(
       
  1880 						percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
       
  1881 						NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ECONOMY, 0),
       
  1882 						i->xy + TileDiffXY(1, 1), 0
       
  1883 					);
       
  1884 				}
       
  1885 			}
       
  1886 		} else {
       
  1887 			if (only_decrease || CHANCE16(1, 3)) {
       
  1888 				/* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
       
  1889 				if (!only_decrease && (i->last_month_pct_transported[0] > 153) != CHANCE16(1, 3)) {
       
  1890 					mul = 1; // Increase production
  1898 				} else {
  1891 				} else {
  1899 					i->prod_level >>= 1;
  1892 					div = 1; // Decrease production
  1900 					i->production_rate[0] = (i->production_rate[0] + 1) >> 1;
       
  1901 					i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
       
  1902 
       
  1903 					str = indspec->production_down_text;
       
  1904 				}
  1893 				}
  1905 			}
  1894 			}
  1906 		}
  1895 		}
  1907 	}
  1896 	}
  1908 	if (indspec->life_type & INDUSTRYLIFE_PROCESSING) {
  1897 
  1909 		/* maybe close */
  1898 	if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) {
  1910 		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, 2)) {
  1899 		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, _patches.smooth_economy ? 180 : 2)) {
  1911 			i->prod_level = 0;
  1900 			closeit = true;
  1912 			str = indspec->closure_text;
  1901 		}
  1913 		}
  1902 	}
  1914 	}
  1903 
  1915 
  1904 	/* Increase if needed */
  1916 	if (str != STR_NULL) {
  1905 	while (mul-- != 0 && i->prod_level < 0x80) {
       
  1906 		i->prod_level <<= 1;
       
  1907 		i->production_rate[0] = min(i->production_rate[0] * 2, 0xFF);
       
  1908 		i->production_rate[1] = min(i->production_rate[1] * 2, 0xFF);
       
  1909 		if (str == STR_NULL) str = indspec->production_up_text;
       
  1910 	}
       
  1911 
       
  1912 	/* Decrease if needed */
       
  1913 	while (div-- != 0 && !closeit) {
       
  1914 		if (i->prod_level == 4) {
       
  1915 			closeit = true;
       
  1916 		} else {
       
  1917 			i->prod_level >>= 1;
       
  1918 			i->production_rate[0] = (i->production_rate[0] + 1) >> 1;
       
  1919 			i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
       
  1920 			if (str == STR_NULL) str = indspec->production_down_text;
       
  1921 		}
       
  1922 	}
       
  1923 
       
  1924 	/* Close if needed and allowed */
       
  1925 	if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
       
  1926 		i->prod_level = 0;
       
  1927 		str = indspec->closure_text;
       
  1928 	}
       
  1929 
       
  1930 	if (!suppress_message && str != STR_NULL) {
  1917 		SetDParam(0, i->index);
  1931 		SetDParam(0, i->index);
  1918 		AddNewsItem(str, NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, str == indspec->closure_text ? NT_OPENCLOSE : NT_ECONOMY, 0), i->xy + TileDiffXY(1, 1), 0);
  1932 		AddNewsItem(str,
       
  1933 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, closeit ? NT_OPENCLOSE : NT_ECONOMY, 0),
       
  1934 			i->xy + TileDiffXY(1, 1), 0);
  1919 	}
  1935 	}
  1920 }
  1936 }
  1921 
  1937 
  1922 void IndustryMonthlyLoop()
  1938 void IndustryMonthlyLoop()
  1923 {
  1939 {
  1925 	PlayerID old_player = _current_player;
  1941 	PlayerID old_player = _current_player;
  1926 	_current_player = OWNER_NONE;
  1942 	_current_player = OWNER_NONE;
  1927 
  1943 
  1928 	FOR_ALL_INDUSTRIES(i) {
  1944 	FOR_ALL_INDUSTRIES(i) {
  1929 		UpdateIndustryStatistics(i);
  1945 		UpdateIndustryStatistics(i);
       
  1946 		if (i->prod_level == 0) {
       
  1947 			delete i;
       
  1948 		} else {
       
  1949 			ChangeIndustryProduction(i, true);
       
  1950 		}
  1930 	}
  1951 	}
  1931 
  1952 
  1932 	/* 3% chance that we start a new industry */
  1953 	/* 3% chance that we start a new industry */
  1933 	if (CHANCE16(3, 100)) {
  1954 	if (CHANCE16(3, 100)) {
  1934 		MaybeNewIndustry();
  1955 		MaybeNewIndustry();
  1935 	} else if (!_patches.smooth_economy) {
  1956 	} else {
  1936 		i = GetRandomIndustry();
  1957 		i = GetRandomIndustry();
  1937 		if (i != NULL) ChangeIndustryProduction(i);
  1958 		if (i != NULL) ChangeIndustryProduction(i, false);
  1938 	}
  1959 	}
  1939 
  1960 
  1940 	_current_player = old_player;
  1961 	_current_player = old_player;
  1941 
  1962 
  1942 	/* production-change */
  1963 	/* production-change */
  1971 			)) >> 8;
  1992 			)) >> 8;
  1972 }
  1993 }
  1973 
  1994 
  1974 static CommandCost TerraformTile_Industry(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  1995 static CommandCost TerraformTile_Industry(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  1975 {
  1996 {
       
  1997 	if (AutoslopeEnabled()) {
       
  1998 		/* We imitate here TTDP's behaviour:
       
  1999 		 *  - Both new and old slope must not be steep.
       
  2000 		 *  - TileMaxZ must not be changed.
       
  2001 		 *  - Allow autoslope by default.
       
  2002 		 *  - Disallow autoslope if callback succeeds and returns non-zero.
       
  2003 		 */
       
  2004 		Slope tileh_old = GetTileSlope(tile, NULL);
       
  2005 		/* TileMaxZ must not be changed. Slopes must not be steep. */
       
  2006 		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
       
  2007 			const IndustryGfx gfx = GetIndustryGfx(tile);
       
  2008 			const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
       
  2009 
       
  2010 			/* Call callback 3C 'disable autosloping for industry tiles'. */
       
  2011 			if (HASBIT(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
       
  2012 				/* If the callback fails, allow autoslope. */
       
  2013 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
       
  2014 				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
       
  2015 			} else {
       
  2016 				// allow autoslope
       
  2017 				return _price.terraform;
       
  2018 			}
       
  2019 		}
       
  2020 	}
  1976 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); // funny magic bulldozer
  2021 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); // funny magic bulldozer
  1977 }
  2022 }
  1978 
  2023 
  1979 extern const TileTypeProcs _tile_type_industry_procs = {
  2024 extern const TileTypeProcs _tile_type_industry_procs = {
  1980 	DrawTile_Industry,           /* draw_tile_proc */
  2025 	DrawTile_Industry,           /* draw_tile_proc */
  2018 	    SLE_VAR(Industry, random_color,               SLE_UINT8),
  2063 	    SLE_VAR(Industry, random_color,               SLE_UINT8),
  2019 	SLE_CONDVAR(Industry, last_prod_year,             SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
  2064 	SLE_CONDVAR(Industry, last_prod_year,             SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
  2020 	SLE_CONDVAR(Industry, last_prod_year,             SLE_INT32,                 31, SL_MAX_VERSION),
  2065 	SLE_CONDVAR(Industry, last_prod_year,             SLE_INT32,                 31, SL_MAX_VERSION),
  2021 	    SLE_VAR(Industry, was_cargo_delivered,        SLE_UINT8),
  2066 	    SLE_VAR(Industry, was_cargo_delivered,        SLE_UINT8),
  2022 
  2067 
  2023 	SLE_CONDVAR(Industry, owner,                      SLE_UINT8,                 70, SL_MAX_VERSION),
  2068 	SLE_CONDVAR(Industry, founder,                    SLE_UINT8,                 70, SL_MAX_VERSION),
  2024 	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 70, SL_MAX_VERSION),
  2069 	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 70, SL_MAX_VERSION),
  2025 	SLE_CONDVAR(Industry, construction_type,          SLE_UINT8,                 70, SL_MAX_VERSION),
  2070 	SLE_CONDVAR(Industry, construction_type,          SLE_UINT8,                 70, SL_MAX_VERSION),
  2026 	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
  2071 	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
  2027 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
  2072 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
       
  2073 
       
  2074 	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
  2028 
  2075 
  2029 	/* reserve extra space in savegame here. (currently 32 bytes) */
  2076 	/* reserve extra space in savegame here. (currently 32 bytes) */
  2030 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
  2077 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
  2031 
  2078 
  2032 	SLE_END()
  2079 	SLE_END()