src/industry_cmd.cpp
branchgamebalance
changeset 9908 0fa543611bbe
parent 9907 3b068c3a1c74
child 9909 dce9a6923bb7
equal deleted inserted replaced
9907:3b068c3a1c74 9908:0fa543611bbe
   257 	}
   257 	}
   258 
   258 
   259 	/* Add industry on top of the ground? */
   259 	/* Add industry on top of the ground? */
   260 	image = dits->building.sprite;
   260 	image = dits->building.sprite;
   261 	if (image != 0) {
   261 	if (image != 0) {
   262 		if (_display_opt & DO_TRANS_BUILDINGS) {
   262 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) {
   263 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   263 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   264 			pal = PALETTE_TO_TRANSPARENT;
   264 			pal = PALETTE_TO_TRANSPARENT;
   265 		} else {
   265 		} else {
   266 			pal = dits->building.pal;
   266 			pal = dits->building.pal;
   267 		}
   267 		}
   272 			dits->width  + 1,
   272 			dits->width  + 1,
   273 			dits->height + 1,
   273 			dits->height + 1,
   274 			dits->dz,
   274 			dits->dz,
   275 			z);
   275 			z);
   276 
   276 
   277 		if (_display_opt & DO_TRANS_BUILDINGS) return;
   277 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
   278 	}
   278 	}
   279 
   279 
   280 	{
   280 	{
   281 		int proc = dits->draw_proc - 1;
   281 		int proc = dits->draw_proc - 1;
   282 		if (proc >= 0) _industry_draw_tile_procs[proc](ti);
   282 		if (proc >= 0) _industry_draw_tile_procs[proc](ti);
  1159 		} else {
  1159 		} else {
  1160 			if (!EnsureNoVehicle(cur_tile)) return false;
  1160 			if (!EnsureNoVehicle(cur_tile)) return false;
  1161 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1161 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1162 
  1162 
  1163 			if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
  1163 			if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
  1164 				return IsClearWaterTile(cur_tile);
  1164 				/* As soon as the tile is not water, bail out.
       
  1165 				 * But that does not mean the search is over.  You have
       
  1166 				 * to make sure every tile of the industry will be only water*/
       
  1167 				if (!IsClearWaterTile(cur_tile)) return false;
  1165 			} else {
  1168 			} else {
  1166 				Slope tileh;
  1169 				Slope tileh;
  1167 
  1170 
  1168 				if (IsClearWaterTile(cur_tile)) return false;
  1171 				if (IsClearWaterTile(cur_tile)) return false;
  1169 
  1172 
  1546 	{0, 1, 1, 1, 2, 2, 3, 3,  4,  4,  5},   //low
  1549 	{0, 1, 1, 1, 2, 2, 3, 3,  4,  4,  5},   //low
  1547 	{0, 1, 2, 3, 4, 5, 6, 7,  8,  9, 10},   //normal
  1550 	{0, 1, 2, 3, 4, 5, 6, 7,  8,  9, 10},   //normal
  1548 	{0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10},   //high
  1551 	{0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10},   //high
  1549 };
  1552 };
  1550 
  1553 
       
  1554 /** This function is the one who really do the creation work
       
  1555  * of random industries during game creation
       
  1556  * @param type IndustryType of the desired industry
       
  1557  * @param amount of industries that need to be built */
  1551 static void PlaceInitialIndustry(IndustryType type, int amount)
  1558 static void PlaceInitialIndustry(IndustryType type, int amount)
  1552 {
  1559 {
  1553 	int num = _numof_industry_table[_opt.diff.number_industries][amount];
  1560 	int num = _numof_industry_table[_opt.diff.number_industries][amount];
  1554 
  1561 
  1555 	if (type == IT_OIL_REFINERY || type == IT_OIL_RIG) {
  1562 	/* These are always placed next to the coastline, so we scale by the perimeter instead. */
  1556 		/* These are always placed next to the coastline, so we scale by the perimeter instead. */
  1563 	num = (type == IT_OIL_REFINERY || type == IT_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num);
  1557 		num = ScaleByMapSize1D(num);
       
  1558 	} else {
       
  1559 		num = ScaleByMapSize(num);
       
  1560 	}
       
  1561 
  1564 
  1562 	if (_opt.diff.number_industries != 0) {
  1565 	if (_opt.diff.number_industries != 0) {
  1563 		PlayerID old_player = _current_player;
  1566 		PlayerID old_player = _current_player;
  1564 		_current_player = OWNER_NONE;
  1567 		_current_player = OWNER_NONE;
  1565 		assert(num > 0);
  1568 		assert(num > 0);
  1576 
  1579 
  1577 		_current_player = old_player;
  1580 		_current_player = old_player;
  1578 	}
  1581 	}
  1579 }
  1582 }
  1580 
  1583 
       
  1584 /** This function will create ramdon industries during game creation.
       
  1585  * It will scale the amount of industries by map size as well as difficulty level */
  1581 void GenerateIndustries()
  1586 void GenerateIndustries()
  1582 {
  1587 {
  1583 	const byte *b;
       
  1584 	uint i = 0;
  1588 	uint i = 0;
       
  1589 	uint8 chance;
       
  1590 	IndustryType it;
       
  1591 	const IndustrySpec *ind_spc;
  1585 
  1592 
  1586 	/* Find the total amount of industries */
  1593 	/* Find the total amount of industries */
  1587 	b = _industry_create_table[_opt.landscape];
  1594 	for (it = IT_COAL_MINE; it < IT_END; it++) {
  1588 	do {
  1595 		int num;
  1589 		int num = _numof_industry_table[_opt.diff.number_industries][b[0]];
  1596 
  1590 
  1597 		ind_spc = GetIndustrySpec(it);
  1591 		if (b[1] == IT_OIL_REFINERY || b[1] == IT_OIL_RIG) {
  1598 		chance = ind_spc->appear_creation[_opt.landscape];
       
  1599 
       
  1600 		if (chance > 0) {
       
  1601 			/* once the chance of appearance is determind, it have to be scaled by
       
  1602 			 * the difficulty level. The "chance" in question is more an index into
       
  1603 			 * the _numof_industry_table,in fact */
       
  1604 			num = _numof_industry_table[_opt.diff.number_industries][chance];
       
  1605 
  1592 			/* These are always placed next to the coastline, so we scale by the perimeter instead. */
  1606 			/* These are always placed next to the coastline, so we scale by the perimeter instead. */
  1593 			num = ScaleByMapSize1D(num);
  1607 			num = (it == IT_OIL_REFINERY || it == IT_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num);
  1594 		} else {
  1608 			i += num;
  1595 			num = ScaleByMapSize(num);
  1609 		}
  1596 		}
  1610 	}
  1597 
  1611 
  1598 		i += num;
       
  1599 	} while ( (b+=2)[0] != 0);
       
  1600 	SetGeneratingWorldProgress(GWP_INDUSTRY, i);
  1612 	SetGeneratingWorldProgress(GWP_INDUSTRY, i);
  1601 
  1613 
  1602 	b = _industry_create_table[_opt.landscape];
  1614 	for (it = IT_COAL_MINE; it < IT_END; it++) {
  1603 	do {
  1615 		/* Once the number of industries has been determined, let's really create them.
  1604 		PlaceInitialIndustry(b[1], b[0]);
  1616 		 * The test for chance allows us to try create industries that are available only
  1605 	} while ( (b+=2)[0] != 0);
  1617 		 * for this landscape.
       
  1618 		 * @todo :  Do we really have to pass chance as un-scaled value, since we've already
       
  1619 		 *          processed that scaling above? No, don't think so.  Will find a way. */
       
  1620 		chance = GetIndustrySpec(it)->appear_creation[_opt.landscape];
       
  1621 		if (chance > 0) PlaceInitialIndustry(it, chance);
       
  1622 	};
  1606 }
  1623 }
  1607 
  1624 
  1608 /* Change industry production or do closure */
  1625 /* Change industry production or do closure */
  1609 static void ExtChangeIndustryProduction(Industry *i)
  1626 static void ExtChangeIndustryProduction(Industry *i)
  1610 {
  1627 {
  1716 	} else if (_patches.smooth_economy) {
  1733 	} else if (_patches.smooth_economy) {
  1717 		ExtChangeIndustryProduction(i);
  1734 		ExtChangeIndustryProduction(i);
  1718 	}
  1735 	}
  1719 }
  1736 }
  1720 
  1737 
  1721 static const byte _new_industry_rand[4][32] = {
  1738 /** Simple helper that will collect data for the generation of industries */
  1722 	{12, 12, 12, 12, 12, 12, 12,  0,  0,  6,  6,  9,  9,  3,  3,  3, 18, 18,  4,  4,  2,  2,  5,  5,  5,  5,  5,  5,  1,  1,  8,  8},
  1739 struct ProbabilityHelper {
  1723 	{16, 16, 16,  0,  0,  0,  9,  9,  9,  9, 13, 13,  3,  3,  3,  3, 15, 15, 15,  4,  4, 11, 11, 11, 11, 11, 14, 14,  1,  1,  7,  7},
  1740 	uint16 prob;      ///< probability
  1724 	{21, 21, 21, 24, 22, 22, 22, 22, 23, 23, 16, 16, 16,  4,  4, 19, 19, 19, 13, 13, 20, 20, 20, 11, 11, 11, 17, 17, 17, 10, 10, 10},
  1741 	IndustryType ind; ///< industry id correcponding
  1725 	{30, 30, 30, 36, 36, 31, 31, 31, 27, 27, 27, 28, 28, 28, 26, 26, 26, 34, 34, 34, 35, 35, 35, 29, 29, 29, 32, 32, 32, 33, 33, 33},
       
  1726 };
  1742 };
  1727 
  1743 
  1728 static void MaybeNewIndustry(uint32 r)
  1744 /**
  1729 {
  1745  * Try to create a random industry, during gameplay
  1730 	int type =_new_industry_rand[_opt.landscape][GB(r, 16, 5)];
  1746  */
  1731 	int j;
  1747 static void MaybeNewIndustry(void)
  1732 	Industry *i;
  1748 {
  1733 	const IndustrySpec *ind_spc = GetIndustrySpec(type);;
  1749 	Industry *ind;               //will receive the industry's creation pointer
  1734 
  1750 	IndustryType rndtype, j;     // Loop controlers
       
  1751 	const IndustrySpec *ind_spc;
       
  1752 	uint num = 0;
       
  1753 	ProbabilityHelper cumulative_probs[IT_END]; // probability collector
       
  1754 	uint16 probability_max = 0;
       
  1755 
       
  1756 	/* Generate a list of all possible industries that can be built. */
       
  1757 	for (j = 0; j < IT_END; j++) {
       
  1758 		byte chance = GetIndustrySpec(j)->appear_ingame[_opt.landscape];
       
  1759 
       
  1760 		/* if appearing chance for this landscape is above 0, this industry can be chosen */
       
  1761 		if (chance != 0) {
       
  1762 			probability_max += chance;
       
  1763 			/* adds the result for this industry */
       
  1764 			cumulative_probs[num].ind = j;
       
  1765 			cumulative_probs[num++].prob = probability_max;
       
  1766 		}
       
  1767 	}
       
  1768 
       
  1769 	/* Find a random type, with maximum being what has been evaluate above*/
       
  1770 	rndtype = RandomRange(probability_max);
       
  1771 	for (j = 0; j < IT_END; j++) {
       
  1772 		/* and choose the index of the industry that matches as close as possible this random type */
       
  1773 		if (cumulative_probs[j].prob >= rndtype) break;
       
  1774 	}
       
  1775 
       
  1776 	ind_spc = GetIndustrySpec(cumulative_probs[j].ind);
       
  1777 	/*  Check if it is allowed */
  1735 	if ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) return;
  1778 	if ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) return;
  1736 	if ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) return;
  1779 	if ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) return;
  1737 
  1780 
  1738 	j = 2000;
  1781 	/* try to create 2000 times this industry */
       
  1782 	num = 2000;
  1739 	for (;;) {
  1783 	for (;;) {
  1740 		i = CreateNewIndustry(RandomTile(), type);
  1784 		ind = CreateNewIndustry(RandomTile(), cumulative_probs[j].ind);
  1741 		if (i != NULL) break;
  1785 		if (ind != NULL) break;
  1742 		if (--j == 0) return;
  1786 		if (--num == 0) return;
  1743 	}
  1787 	}
  1744 
  1788 
  1745 	SetDParam(0, ind_spc->name);
  1789 	SetDParam(0, ind_spc->name);
  1746 	SetDParam(1, i->town->index);
  1790 	SetDParam(1, ind->town->index);
  1747 	AddNewsItem(ind_spc->new_industry_text,
  1791 	AddNewsItem(ind_spc->new_industry_text,
  1748 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_OPENCLOSE, 0), i->xy, 0);
  1792 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1749 }
  1793 }
  1750 
  1794 
  1751 static void ChangeIndustryProduction(Industry *i)
  1795 static void ChangeIndustryProduction(Industry *i)
  1752 {
  1796 {
  1753 	bool only_decrease = false;
  1797 	bool only_decrease = false;
  1826 		UpdateIndustryStatistics(i);
  1870 		UpdateIndustryStatistics(i);
  1827 	}
  1871 	}
  1828 
  1872 
  1829 	/* 3% chance that we start a new industry */
  1873 	/* 3% chance that we start a new industry */
  1830 	if (CHANCE16(3, 100)) {
  1874 	if (CHANCE16(3, 100)) {
  1831 		MaybeNewIndustry(Random());
  1875 		MaybeNewIndustry();
  1832 	} else if (!_patches.smooth_economy) {
  1876 	} else if (!_patches.smooth_economy) {
  1833 		i = GetRandomIndustry();
  1877 		i = GetRandomIndustry();
  1834 		if (i != NULL) ChangeIndustryProduction(i);
  1878 		if (i != NULL) ChangeIndustryProduction(i);
  1835 	}
  1879 	}
  1836 
  1880