src/industry_cmd.cpp
branchgamebalance
changeset 9908 0fa543611bbe
parent 9907 3b068c3a1c74
child 9909 dce9a6923bb7
--- a/src/industry_cmd.cpp	Thu Apr 19 14:48:10 2007 +0000
+++ b/src/industry_cmd.cpp	Tue Jun 12 11:56:35 2007 +0000
@@ -259,7 +259,7 @@
 	/* Add industry on top of the ground? */
 	image = dits->building.sprite;
 	if (image != 0) {
-		if (_display_opt & DO_TRANS_BUILDINGS) {
+		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) {
 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
 			pal = PALETTE_TO_TRANSPARENT;
 		} else {
@@ -274,7 +274,7 @@
 			dits->dz,
 			z);
 
-		if (_display_opt & DO_TRANS_BUILDINGS) return;
+		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
 	}
 
 	{
@@ -1161,7 +1161,10 @@
 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
 
 			if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
-				return IsClearWaterTile(cur_tile);
+				/* As soon as the tile is not water, bail out.
+				 * But that does not mean the search is over.  You have
+				 * to make sure every tile of the industry will be only water*/
+				if (!IsClearWaterTile(cur_tile)) return false;
 			} else {
 				Slope tileh;
 
@@ -1548,16 +1551,16 @@
 	{0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10},   //high
 };
 
+/** This function is the one who really do the creation work
+ * of random industries during game creation
+ * @param type IndustryType of the desired industry
+ * @param amount of industries that need to be built */
 static void PlaceInitialIndustry(IndustryType type, int amount)
 {
 	int num = _numof_industry_table[_opt.diff.number_industries][amount];
 
-	if (type == IT_OIL_REFINERY || type == IT_OIL_RIG) {
-		/* These are always placed next to the coastline, so we scale by the perimeter instead. */
-		num = ScaleByMapSize1D(num);
-	} else {
-		num = ScaleByMapSize(num);
-	}
+	/* These are always placed next to the coastline, so we scale by the perimeter instead. */
+	num = (type == IT_OIL_REFINERY || type == IT_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num);
 
 	if (_opt.diff.number_industries != 0) {
 		PlayerID old_player = _current_player;
@@ -1578,31 +1581,45 @@
 	}
 }
 
+/** This function will create ramdon industries during game creation.
+ * It will scale the amount of industries by map size as well as difficulty level */
 void GenerateIndustries()
 {
-	const byte *b;
 	uint i = 0;
+	uint8 chance;
+	IndustryType it;
+	const IndustrySpec *ind_spc;
 
 	/* Find the total amount of industries */
-	b = _industry_create_table[_opt.landscape];
-	do {
-		int num = _numof_industry_table[_opt.diff.number_industries][b[0]];
+	for (it = IT_COAL_MINE; it < IT_END; it++) {
+		int num;
 
-		if (b[1] == IT_OIL_REFINERY || b[1] == IT_OIL_RIG) {
+		ind_spc = GetIndustrySpec(it);
+		chance = ind_spc->appear_creation[_opt.landscape];
+
+		if (chance > 0) {
+			/* once the chance of appearance is determind, it have to be scaled by
+			 * the difficulty level. The "chance" in question is more an index into
+			 * the _numof_industry_table,in fact */
+			num = _numof_industry_table[_opt.diff.number_industries][chance];
+
 			/* These are always placed next to the coastline, so we scale by the perimeter instead. */
-			num = ScaleByMapSize1D(num);
-		} else {
-			num = ScaleByMapSize(num);
+			num = (it == IT_OIL_REFINERY || it == IT_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num);
+			i += num;
 		}
+	}
 
-		i += num;
-	} while ( (b+=2)[0] != 0);
 	SetGeneratingWorldProgress(GWP_INDUSTRY, i);
 
-	b = _industry_create_table[_opt.landscape];
-	do {
-		PlaceInitialIndustry(b[1], b[0]);
-	} while ( (b+=2)[0] != 0);
+	for (it = IT_COAL_MINE; it < IT_END; it++) {
+		/* Once the number of industries has been determined, let's really create them.
+		 * The test for chance allows us to try create industries that are available only
+		 * for this landscape.
+		 * @todo :  Do we really have to pass chance as un-scaled value, since we've already
+		 *          processed that scaling above? No, don't think so.  Will find a way. */
+		chance = GetIndustrySpec(it)->appear_creation[_opt.landscape];
+		if (chance > 0) PlaceInitialIndustry(it, chance);
+	};
 }
 
 /* Change industry production or do closure */
@@ -1718,34 +1735,61 @@
 	}
 }
 
-static const byte _new_industry_rand[4][32] = {
-	{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},
-	{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},
-	{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},
-	{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},
+/** Simple helper that will collect data for the generation of industries */
+struct ProbabilityHelper {
+	uint16 prob;      ///< probability
+	IndustryType ind; ///< industry id correcponding
 };
 
-static void MaybeNewIndustry(uint32 r)
+/**
+ * Try to create a random industry, during gameplay
+ */
+static void MaybeNewIndustry(void)
 {
-	int type =_new_industry_rand[_opt.landscape][GB(r, 16, 5)];
-	int j;
-	Industry *i;
-	const IndustrySpec *ind_spc = GetIndustrySpec(type);;
+	Industry *ind;               //will receive the industry's creation pointer
+	IndustryType rndtype, j;     // Loop controlers
+	const IndustrySpec *ind_spc;
+	uint num = 0;
+	ProbabilityHelper cumulative_probs[IT_END]; // probability collector
+	uint16 probability_max = 0;
 
+	/* Generate a list of all possible industries that can be built. */
+	for (j = 0; j < IT_END; j++) {
+		byte chance = GetIndustrySpec(j)->appear_ingame[_opt.landscape];
+
+		/* if appearing chance for this landscape is above 0, this industry can be chosen */
+		if (chance != 0) {
+			probability_max += chance;
+			/* adds the result for this industry */
+			cumulative_probs[num].ind = j;
+			cumulative_probs[num++].prob = probability_max;
+		}
+	}
+
+	/* Find a random type, with maximum being what has been evaluate above*/
+	rndtype = RandomRange(probability_max);
+	for (j = 0; j < IT_END; j++) {
+		/* and choose the index of the industry that matches as close as possible this random type */
+		if (cumulative_probs[j].prob >= rndtype) break;
+	}
+
+	ind_spc = GetIndustrySpec(cumulative_probs[j].ind);
+	/*  Check if it is allowed */
 	if ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) return;
 	if ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) return;
 
-	j = 2000;
+	/* try to create 2000 times this industry */
+	num = 2000;
 	for (;;) {
-		i = CreateNewIndustry(RandomTile(), type);
-		if (i != NULL) break;
-		if (--j == 0) return;
+		ind = CreateNewIndustry(RandomTile(), cumulative_probs[j].ind);
+		if (ind != NULL) break;
+		if (--num == 0) return;
 	}
 
 	SetDParam(0, ind_spc->name);
-	SetDParam(1, i->town->index);
+	SetDParam(1, ind->town->index);
 	AddNewsItem(ind_spc->new_industry_text,
-		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_OPENCLOSE, 0), i->xy, 0);
+		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
 }
 
 static void ChangeIndustryProduction(Industry *i)
@@ -1828,7 +1872,7 @@
 
 	/* 3% chance that we start a new industry */
 	if (CHANCE16(3, 100)) {
-		MaybeNewIndustry(Random());
+		MaybeNewIndustry();
 	} else if (!_patches.smooth_economy) {
 		i = GetRandomIndustry();
 		if (i != NULL) ChangeIndustryProduction(i);