mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-13 02:52:37 +00:00
(svn r21168) -Feature: Use desired industry counts rather than relative probability to decide which industry to build.
This commit is contained in:
parent
e861487bcb
commit
3211ab301e
@ -146,6 +146,7 @@ void ReleaseDisastersTargetingIndustry(IndustryID);
|
|||||||
/** Data for managing the number of industries of a single industry type. */
|
/** Data for managing the number of industries of a single industry type. */
|
||||||
struct IndustryTypeBuildData {
|
struct IndustryTypeBuildData {
|
||||||
uint32 probability; ///< Relative probability of building this industry.
|
uint32 probability; ///< Relative probability of building this industry.
|
||||||
|
uint16 target_count; ///< Desired number of industries of this type.
|
||||||
|
|
||||||
void GetIndustryTypeData(IndustryType it);
|
void GetIndustryTypeData(IndustryType it);
|
||||||
};
|
};
|
||||||
@ -156,6 +157,7 @@ struct IndustryTypeBuildData {
|
|||||||
struct IndustryBuildData {
|
struct IndustryBuildData {
|
||||||
IndustryTypeBuildData builddata[NUM_INDUSTRYTYPES]; ///< Industry build data for every industry type.
|
IndustryTypeBuildData builddata[NUM_INDUSTRYTYPES]; ///< Industry build data for every industry type.
|
||||||
|
|
||||||
|
void SetupTargetCount();
|
||||||
void TryBuildNewIndustry();
|
void TryBuildNewIndustry();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2055,26 +2055,56 @@ void IndustryTypeBuildData::GetIndustryTypeData(IndustryType it)
|
|||||||
this->probability = GetIndustryGamePlayProbability(it);
|
this->probability = GetIndustryGamePlayProbability(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Decide how many industries of each type are needed. */
|
||||||
|
void IndustryBuildData::SetupTargetCount()
|
||||||
|
{
|
||||||
|
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
|
||||||
|
this->builddata[it].GetIndustryTypeData(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint total_amount = GetNumberOfIndustries(); // Desired number of industries.
|
||||||
|
uint32 total_prob = 0; // Sum of probabilities.
|
||||||
|
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
|
||||||
|
this->builddata[it].target_count = 0;
|
||||||
|
total_prob += this->builddata[it].probability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign number of industries that should be aimed for, by using the probability as a weight. */
|
||||||
|
while (total_amount > 0) {
|
||||||
|
uint32 r = RandomRange(total_prob);
|
||||||
|
IndustryType it = 0;
|
||||||
|
while (r >= this->builddata[it].probability) {
|
||||||
|
r -= this->builddata[it].probability;
|
||||||
|
it++;
|
||||||
|
assert(it < NUM_INDUSTRYTYPES);
|
||||||
|
}
|
||||||
|
assert(this->builddata[it].probability > 0);
|
||||||
|
this->builddata[it].target_count++;
|
||||||
|
total_amount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to create a random industry, during gameplay
|
* Try to create a random industry, during gameplay
|
||||||
*/
|
*/
|
||||||
void IndustryBuildData::TryBuildNewIndustry()
|
void IndustryBuildData::TryBuildNewIndustry()
|
||||||
{
|
{
|
||||||
/* Generate a list of all possible industries that can be built. */
|
this->SetupTargetCount();
|
||||||
for (IndustryType j = 0; j < NUM_INDUSTRYTYPES; j++) {
|
|
||||||
this->builddata[j].GetIndustryTypeData(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int missing = 0; // Number of industries that need to be build.
|
||||||
uint count = 0; // Number of industry types eligible for build.
|
uint count = 0; // Number of industry types eligible for build.
|
||||||
uint32 total_prob = 0; // Sum of probabilities.
|
uint32 total_prob = 0; // Sum of probabilities.
|
||||||
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
|
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
|
||||||
uint32 chance = this->builddata[it].probability;
|
int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
|
||||||
if (chance > 0) {
|
missing += difference;
|
||||||
total_prob += chance;
|
if (difference > 0) {
|
||||||
|
total_prob += difference;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (missing <= 0 || total_prob == 0) count = 0; // Skip creation of an industry.
|
||||||
|
|
||||||
if (count >= 1) {
|
if (count >= 1) {
|
||||||
/* Pick a weighted random industry to build.
|
/* Pick a weighted random industry to build.
|
||||||
* For the case that count == 1, there is no need to draw a random number. */
|
* For the case that count == 1, there is no need to draw a random number. */
|
||||||
@ -2083,13 +2113,13 @@ void IndustryBuildData::TryBuildNewIndustry()
|
|||||||
uint32 r = 0; // Initialized to silence the compiler.
|
uint32 r = 0; // Initialized to silence the compiler.
|
||||||
if (count > 1) r = RandomRange(total_prob);
|
if (count > 1) r = RandomRange(total_prob);
|
||||||
for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
|
for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
|
||||||
uint32 chance = this->builddata[it].probability;
|
int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
|
||||||
if (chance == 0) continue;
|
if (difference <= 0) continue; // Too many of this kind.
|
||||||
if (count == 1) break;
|
if (count == 1) break;
|
||||||
if (r < chance) break;
|
if (r < (uint)difference) break;
|
||||||
r -= chance;
|
r -= difference;
|
||||||
}
|
}
|
||||||
assert(it < NUM_INDUSTRYTYPES);
|
assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
|
||||||
|
|
||||||
/* Try to create the industry. */
|
/* Try to create the industry. */
|
||||||
const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
|
const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user