(svn r19120) -Fix: [NewGRF] Industry property 0x17 was interpreted incorrectly and in some cases circumvented the density difficulty setting.

-Change: Do not scale the number of industry creations during map creation with the number of available industry types.
-Feature: [NewGRF] Implement special industry flag 0x10000.
This commit is contained in:
frosch 2010-02-13 14:06:01 +00:00
parent 06600a6834
commit 3fe58a2250

View File

@ -1764,76 +1764,108 @@ static Industry *CreateNewIndustry(TileIndex tile, IndustryType type)
return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, OWNER_NONE); return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, OWNER_NONE);
} }
enum { /**
NB_NUMOFINDUSTRY = 11, * Compute the appearance probability for an industry during map creation.
NB_DIFFICULTY_LEVEL = 5, * @param it Industrytype to compute for
* @param force_at_least_one Returns whether at least one instance should be forced on map creation
* @return relative probability for the industry to appear
*/
static uint32 GetScaledIndustryProbability(IndustryType it, bool *force_at_least_one)
{
const IndustrySpec *ind_spc = GetIndustrySpec(it);
uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision
if (!ind_spc->enabled || chance == 0 || ind_spc->num_table == 0 ||
!CheckIfCallBackAllowsAvailability(it, IACT_MAPGENERATION) || _settings_game.difficulty.number_industries == 0) {
*force_at_least_one = false;
return 0;
} else {
/* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
* For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */
chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance);
*force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION);
return chance;
}
}
/** Number of industries on a 256x256 map */
static const byte _numof_industry_table[]= {
0, // none
10, // very low
25, // low
55, // normal
80, // high
}; };
static const byte _numof_industry_table[NB_DIFFICULTY_LEVEL][NB_NUMOFINDUSTRY] = { /**
/* difficulty settings for number of industries */ * Try to build a industry on the map.
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // none
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // very low
{0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5}, // low
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, // normal
{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 type IndustryType of the desired industry
* @param amount of industries that need to be built */ * @param try_hard Try very hard to find a place. (Used to place at least one industry per type)
static void PlaceInitialIndustry(IndustryType type, uint amount) */
static void PlaceInitialIndustry(IndustryType type, bool try_hard)
{ {
CompanyID old_company = _current_company; CompanyID old_company = _current_company;
_current_company = OWNER_NONE; _current_company = OWNER_NONE;
for (; amount > 0; amount--) { IncreaseGeneratingWorldProgress(GWP_INDUSTRY);
IncreaseGeneratingWorldProgress(GWP_INDUSTRY);
for (uint i = 0; i < 2000; i++) { for (uint i = 0; i < (try_hard ? 10000 : 2000); i++) {
if (CreateNewIndustry(RandomTile(), type) != NULL) break; if (CreateNewIndustry(RandomTile(), type) != NULL) break;
}
} }
_current_company = old_company; _current_company = old_company;
} }
/** This function will create ramdon industries during game creation. /**
* It will scale the amount of industries by map size as well as difficulty level */ * This function will create random industries during game creation.
* It will scale the amount of industries by mapsize and difficulty level.
*/
void GenerateIndustries() void GenerateIndustries()
{ {
uint total_amount = 0; assert(_settings_game.difficulty.number_industries < lengthof(_numof_industry_table));
uint industry_counts[NUM_INDUSTRYTYPES]; uint total_amount = ScaleByMapSize(_numof_industry_table[_settings_game.difficulty.number_industries]);
memset(industry_counts, 0, sizeof(industry_counts));
/* Find the total amount of industries */ /* Do not create any industries? */
if (_settings_game.difficulty.number_industries > 0) { if (total_amount == 0) return;
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
const IndustrySpec *ind_spc = GetIndustrySpec(it);
uint8 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape]; uint32 industry_probs[NUM_INDUSTRYTYPES];
if (ind_spc->enabled && chance > 0 && ind_spc->num_table > 0 && CheckIfCallBackAllowsAvailability(it, IACT_MAPGENERATION)) { bool force_at_least_one[NUM_INDUSTRYTYPES];
/* once the chance of appearance is determind, it have to be scaled by uint32 total_prob = 0;
* the difficulty level. The "chance" in question is more an index into uint num_forced = 0;
* the _numof_industry_table,in fact */
uint num = (chance > NB_NUMOFINDUSTRY) ? chance : _numof_industry_table[_settings_game.difficulty.number_industries][chance];
/* These are always placed next to the coastline, so we scale by the perimeter instead. */ for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
num = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num); industry_probs[it] = GetScaledIndustryProbability(it, force_at_least_one + it);
industry_counts[it] = num; total_prob += industry_probs[it];
total_amount += num; if (force_at_least_one[it]) num_forced++;
} }
}
if (total_prob == 0 || total_amount < num_forced) {
/* Only place the forced ones */
total_amount = num_forced;
} }
SetGeneratingWorldProgress(GWP_INDUSTRY, total_amount); SetGeneratingWorldProgress(GWP_INDUSTRY, total_amount);
if (_settings_game.difficulty.number_industries > 0) { /* Try to build one industry per type independent of any probabilities */
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
/* Once the number of industries has been determined, let's really create them. */ if (force_at_least_one[it]) {
if (industry_counts[it] > 0) PlaceInitialIndustry(it, industry_counts[it]); assert(total_amount > 0);
total_amount--;
PlaceInitialIndustry(it, true);
} }
} }
/* Add the remaining industries according to their probabilities */
for (uint i = 0; i < total_amount; i++) {
uint32 r = RandomRange(total_prob);
IndustryType it = 0;
while (it < NUM_INDUSTRYTYPES && r > industry_probs[it]) {
r -= industry_probs[it];
it++;
}
assert(it < NUM_INDUSTRYTYPES && industry_probs[it] > 0);
PlaceInitialIndustry(it, false);
}
} }
static void UpdateIndustryStatistics(Industry *i) static void UpdateIndustryStatistics(Industry *i)