--- 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);