Skip to content

Commit

Permalink
Overpopulation building tweak (#407)
Browse files Browse the repository at this point in the history
* Increase weight of buildings not capped by arable land in overpopulated states.

* Increase building weight of overpopulated countries.
  • Loading branch information
kingofmen authored May 23, 2023
1 parent 301d062 commit 35d851c
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 22 deletions.
52 changes: 37 additions & 15 deletions EU4ToVic3/Source/V3World/ClayManager/State/SubState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ double V3::SubState::getTerrainFrequency(const std::string& theTerrain) const
return 0;
}

double V3::SubState::getOverPopulation() const
{
const double pops = subStatePops.getPopCount();
const double capacity = getResource("bg_agriculture") * 5000.0; // One arable land supports roughly 5k people.
if (capacity < 5000)
{
return 10.0;
}
const auto ratio = pops / capacity;
if (ratio < 1.0)
{
return 1.0;
}
return ratio;
}

void V3::SubState::gatherPossibleBuildings(const std::map<std::string, Building>& templateBuildings,
const BuildingGroups& buildingGroups,
const std::map<std::string, std::map<std::string, double>>& buildingTerrainModifiers,
Expand Down Expand Up @@ -281,27 +297,32 @@ double V3::SubState::calcBuildingIndustrialWeight(const Building& building, cons
if (owner->getIndustryFactor() > 0 && owner->getProcessedData().civLevel >= 40)
return calcBuildingIncorporationWeight(building, buildingGroups);

// Your non-industrial so urban buildings are not built
auto buildingGroup = buildingGroups.getBuildingGroupMap().at(building.getBuildingGroup());
if (buildingGroup->getCategory())
// You're non-industrial so urban buildings are not built.
const auto& category = buildingGroups.getAncestralCategory(building.getBuildingGroup());
if (category)
{
if (*buildingGroup->getCategory() == "urban")
if (*category == "urban")
return 0;
}

while (buildingGroup->getParentName())
// If building isn't urban, run incorporation check.
return calcBuildingIncorporationWeight(building, buildingGroups);
}

double V3::SubState::calcBuildingOverPopulationWeight(const Building& building, const BuildingGroups& buildingGroups) const
{
auto overPop = getOverPopulation();
if (overPop <= 1.0)
{
buildingGroup = buildingGroups.getBuildingGroupMap().at(*buildingGroup->getParentName());
if (buildingGroup->getCategory())
{
if (*buildingGroup->getCategory() == "urban")
return 0;
}
return 1.0;
}

// If building isn't urban, run incorporation check
return calcBuildingIncorporationWeight(building, buildingGroups);
if (buildingGroups.usesArableLand(building.getBuildingGroup()))
{
return 1.0;
}
return overPop;
}

double V3::SubState::calcBuildingIncorporationWeight(const Building& building, const BuildingGroups& buildingGroups) const
{
// Only adjust unincorporated states
Expand Down Expand Up @@ -547,8 +568,9 @@ double V3::SubState::calcBuildingWeight(const Building& building,
const double traitWeight = calcBuildingTraitWeight(building, traitMap, traitStrength);
const double investmentWeight = calcBuildingInvestmentWeight(building);
const double industrialWeight = calcBuildingIndustrialWeight(building, buildingGroups);
const double overPopWeight = calcBuildingOverPopulationWeight(building, buildingGroups);

return (1 + terrainWeight + EU4BuildingWeight) * traitWeight * investmentWeight * industrialWeight;
return (1 + terrainWeight + EU4BuildingWeight) * traitWeight * investmentWeight * industrialWeight * overPopWeight;
}

void V3::SubState::calculateInfrastructure(const StateModifiers& theStateModifiers, const std::map<std::string, Tech>& techMap)
Expand Down
2 changes: 2 additions & 0 deletions EU4ToVic3/Source/V3World/ClayManager/State/SubState.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class SubState
[[nodiscard]] const auto& getInfrastructure() const { return infrastructure; }
[[nodiscard]] int getResource(const std::string& theResource) const;
[[nodiscard]] double getTerrainFrequency(const std::string& theTerrain) const;
[[nodiscard]] double getOverPopulation() const;
[[nodiscard]] const auto& getTerrainFrequencies() { return terrainFrequency; }
[[nodiscard]] const auto& getDemographics() const { return demographics; }
[[nodiscard]] const auto& getSubStatePops() const { return subStatePops; }
Expand Down Expand Up @@ -173,6 +174,7 @@ class SubState
[[nodiscard]] double calcBuildingInvestmentWeight(const Building& building) const;
[[nodiscard]] double calcBuildingIndustrialWeight(const Building& building, const BuildingGroups& buildingGroups) const;
[[nodiscard]] double calcBuildingIncorporationWeight(const Building& building, const BuildingGroups& buildingGroups) const;
[[nodiscard]] double calcBuildingOverPopulationWeight(const Building& building, const BuildingGroups& buildingGroups) const;
[[nodiscard]] bool isBuildingValid(const Building& building,
const BuildingGroups& buildingGroups,
const std::map<std::string, Law>& lawsMap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ void V3::BuildingGroup::registerKeys()
resourceCapped = (commonItems::getString(theStream) == "yes");
});
registerKeyword("land_usage", [this](std::istream& theStream) {
resourceCapped = (commonItems::getString(theStream) == "rural");
arableCapped = (commonItems::getString(theStream) == "rural");
if (arableCapped)
{
resourceCapped = true;
}
});
registerKeyword("parent_group", [this](std::istream& theStream) {
parent = commonItems::getString(theStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BuildingGroup: commonItems::parser
[[nodiscard]] const auto& getCategory() const { return category; }
[[nodiscard]] const auto& getInfrastructureCost() const { return infrastructureCost; }
[[nodiscard]] const auto& possibleIsResourceCapped() const { return resourceCapped; }

[[nodiscard]] const auto& usesArableLand() const { return arableCapped; }

private:
void registerKeys();
Expand All @@ -27,6 +27,7 @@ class BuildingGroup: commonItems::parser
std::optional<std::string> category;
std::optional<double> infrastructureCost;
std::optional<bool> resourceCapped;
std::optional<bool> arableCapped;
};
} // namespace V3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,66 @@ void V3::BuildingGroups::addBuildingGroup(const std::shared_ptr<BuildingGroup>&
buildingGroups[theBuildingGroup->getName()] = theBuildingGroup;
}

std::optional<std::string> V3::BuildingGroups::getAncestralCategory(const std::optional<std::string>& theGroupName) const
{
if (!theGroupName)
{
return std::nullopt;
}
auto name = theGroupName.value();
while (!name.empty())
{
const auto& possibleGroup = buildingGroups.find(name);
if (possibleGroup == buildingGroups.end())
{
break;
}
const auto cat = possibleGroup->second->getCategory();
if (cat)
{
return *cat;
}
const auto& parentName = possibleGroup->second->getParentName();
if (!parentName)
{
break;
}
name = parentName.value();
}

return std::nullopt;
}

bool V3::BuildingGroups::usesArableLand(const std::optional<std::string>& theGroupName) const
{
if (!theGroupName)
{
return false;
}
auto name = theGroupName.value();
while (!name.empty())
{
const auto& possibleGroup = buildingGroups.find(name);
if (possibleGroup == buildingGroups.end())
{
break;
}
const auto& cat = possibleGroup->second->getCategory();
if (possibleGroup->second->usesArableLand())
{
return true;
}
const auto& parentName = possibleGroup->second->getParentName();
if (!parentName)
{
break;
}
name = parentName.value();
}

return false;
}

std::optional<std::string> V3::BuildingGroups::tryGetParentName(const std::optional<std::string>& theGroupName) const
{
if (!theGroupName)
Expand Down Expand Up @@ -85,4 +145,4 @@ std::optional<bool> V3::BuildingGroups::tryGetIsCapped(const std::optional<std::
}

return std::nullopt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ class BuildingGroups
void setInfrastructureCosts();
void setResourceCaps();

[[nodiscard]] std::optional<std::string> getAncestralCategory(const std::optional<std::string>& theGroupName) const;
[[nodiscard]] const auto& getBuildingGroupMap() const { return buildingGroups; }
[[nodiscard]] std::optional<std::string> tryGetParentName(const std::optional<std::string>& theGroupName) const;
[[nodiscard]] std::optional<double> tryGetInfraCost(const std::optional<std::string>& theGroupName) const;
[[nodiscard]] std::optional<bool> tryGetIsCapped(const std::optional<std::string>& theGroupName) const;
[[nodiscard]] bool usesArableLand(const std::optional<std::string>& theGroupName) const;

private:
std::map<std::string, std::shared_ptr<BuildingGroup>> buildingGroups;
};
} // namespace V3

#endif // V3_BUILDING_GROUPS_H
#endif // V3_BUILDING_GROUPS_H
9 changes: 6 additions & 3 deletions EU4ToVic3/Source/V3World/EconomyManager/EconomyManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,17 +285,20 @@ std::pair<double, double> V3::EconomyManager::civLevelCountryBudgets() const
double accumulatedWeight = 0;
double totalCivLevel = 0.0;
const double geoMeanPop = calculateGeoMeanCentralizedPops();
// while determining individual country's industry score, accumulate total industry factor & weight
// While determining individual countries' industry scores, accumulate total industry factor and weight.

for (const auto& country: centralizedCountries)
{
const int popCount = country->getPopCount();
country->setIndustryWeight(popCount * (country->getProcessedData().civLevel / 100) * calculatePopDistanceFactor(popCount, geoMeanPop));
double weight = popCount * (country->getProcessedData().civLevel * 0.01);
weight *= calculatePopDistanceFactor(popCount, geoMeanPop);
weight *= country->getOverPopulation();
country->setIndustryWeight(weight);
accumulatedWeight += country->getIndustryWeight();
totalCivLevel += country->getProcessedData().civLevel;
}

// adjust global total by average industry factor compared to baseline
// Adjust global total by average industry factor compared to baseline.
const double globalIndustryFactor = (totalCivLevel / static_cast<double>(centralizedCountries.size()) / econDefines.getMeanCivlevel()) - 1;

Log(LogLevel::Info) << std::fixed << std::setprecision(0) << "<> The world is " << (globalIndustryFactor + 1) * 100
Expand Down
22 changes: 22 additions & 0 deletions EU4ToVic3/Source/V3World/PoliticalManager/Country/Country.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,28 @@ double V3::Country::getTotalDev() const
});
}

double V3::Country::getOverPopulation() const
{
double pops = 0;
double capacity = 0;
for (const auto& subState: subStates)
{
pops += subState->getSubStatePops().getPopCount();
capacity += subState->getResource("bg_agriculture");
}
capacity *= 5000;
if (capacity < 5000)
{
return 10.0;
}
const auto ratio = pops / capacity;
if (ratio < 1.0)
{
return 1.0;
}
return ratio;
}

void V3::Country::determineWesternizationWealthAndLiteracy(double topTech,
double topInstitutions,
const mappers::CultureMapper& cultureMapper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class Country: commonItems::parser
[[nodiscard]] std::string getName(const std::string& language) const;
[[nodiscard]] std::string getAdjective(const std::string& language) const;
[[nodiscard]] double getTotalDev() const;
[[nodiscard]] double getOverPopulation() const;
[[nodiscard]] int getPopCount() const;
[[nodiscard]] int getVanillaPopCount() const; // vanilla pop count of all the provinces this country holds
[[nodiscard]] int getIncorporatedPopCount() const;
Expand Down

0 comments on commit 35d851c

Please sign in to comment.