aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/country/CountryInstance.cpp
diff options
context:
space:
mode:
author Hop311 <Hop3114@gmail.com>2024-07-23 19:47:47 +0200
committer GitHub <noreply@github.com>2024-07-23 19:47:47 +0200
commit6cd55c452d1643666ff4169a89402fd3e3b66c61 (patch)
tree888b847a54c66b6e9d1b2f7ee3e3d0f8071eceda /src/openvic-simulation/country/CountryInstance.cpp
parent9d57ca273e4b32ab82a51789ec58e08fefb5276a (diff)
parent67cbd14630c4344902d3fa1ddca178809da4293b (diff)
Merge pull request #177 from OpenVicProject/country-instance
Fleshing out Country, State and Province instances + history
Diffstat (limited to 'src/openvic-simulation/country/CountryInstance.cpp')
-rw-r--r--src/openvic-simulation/country/CountryInstance.cpp313
1 files changed, 281 insertions, 32 deletions
diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp
index 8d2955b..0b27b78 100644
--- a/src/openvic-simulation/country/CountryInstance.cpp
+++ b/src/openvic-simulation/country/CountryInstance.cpp
@@ -2,59 +2,156 @@
#include "openvic-simulation/country/CountryDefinition.hpp"
#include "openvic-simulation/history/CountryHistory.hpp"
-#include "openvic-simulation/military/UnitInstanceGroup.hpp"
+#include "openvic-simulation/map/MapInstance.hpp"
+#include "openvic-simulation/politics/Ideology.hpp"
+#include "openvic-simulation/research/Invention.hpp"
+#include "openvic-simulation/research/Technology.hpp"
using namespace OpenVic;
+static constexpr colour_t ERROR_COLOUR = colour_t::from_integer(0xFF0000);
+
CountryInstance::CountryInstance(
CountryDefinition const* new_country_definition,
decltype(technologies)::keys_t const& technology_keys,
decltype(inventions)::keys_t const& invention_keys,
- decltype(upper_house)::keys_t const& ideology_keys
-) : country_definition { new_country_definition },
- primary_culture { nullptr },
- religion { nullptr },
- ruling_party { nullptr },
- last_election {},
+ decltype(upper_house)::keys_t const& ideology_keys,
+ decltype(pop_type_distribution)::keys_t const& pop_type_keys
+) : /* Main attributes */
+ country_definition { new_country_definition },
+ colour { ERROR_COLOUR },
capital { nullptr },
+ country_flags {},
+ civilised { false },
+ releasable_vassal { true },
+ owned_provinces {},
+ controlled_provinces {},
+ core_provinces {},
+ states {},
+
+ /* Production */
+
+ /* Budget */
+ cash_stockpile { 0 },
+
+ /* Technology */
+ technologies { &technology_keys },
+ inventions { &invention_keys },
+ current_research { nullptr },
+ invested_research_points { 0 },
+ expected_completion_date {},
+ research_point_stockpile { 0 },
+ daily_research_points { 0 },
+ national_literacy { 0 },
+ tech_school { nullptr },
+
+ /* Politics */
+ national_value { nullptr },
government_type { nullptr },
+ last_election {},
+ ruling_party { nullptr },
+ upper_house { &ideology_keys },
+ reforms {},
+ suppression_points { 0 },
+ infamy { 0 },
plurality { 0 },
- national_value { nullptr },
- civilised { false },
+ revanchism { 0 },
+
+ /* Population */
+ primary_culture { nullptr },
+ accepted_cultures {},
+ religion { nullptr },
+ total_population { 0 },
+ national_consciousness { 0 },
+ national_militancy { 0 },
+ pop_type_distribution { &pop_type_keys },
+ national_focus_capacity { 0 },
+
+ /* Trade */
+
+ /* Diplomacy */
+ total_rank { 0 },
prestige { 0 },
- upper_house { &ideology_keys },
- technologies { &technology_keys },
- inventions { &invention_keys } {}
+ prestige_rank { 0 },
+ industrial_power { 0 },
+ industrial_rank { 0 },
+ military_power { 0 },
+ military_rank { 0 },
+ diplomatic_points { 0 },
+
+ /* Military */
+ generals {},
+ admirals {},
+ armies {},
+ navies {},
+ regiment_count { 0 },
+ mobilisation_regiment_potential { 0 },
+ ship_count { 0 },
+ total_consumed_ship_supply { 0 },
+ max_ship_supply { 0 },
+ leadership_points { 0 },
+ war_exhaustion { 0 } {}
std::string_view CountryInstance::get_identifier() const {
- return country_definition != nullptr ? country_definition->get_identifier() : "NULL";
+ return country_definition->get_identifier();
}
-bool CountryInstance::add_accepted_culture(Culture const* new_accepted_culture) {
- if (std::find(accepted_cultures.begin(), accepted_cultures.end(), new_accepted_culture) != accepted_cultures.end()) {
+bool CountryInstance::set_country_flag(std::string_view flag, bool warn) {
+ if (flag.empty()) {
+ Logger::error("Attempted to set empty country flag for country ", get_identifier());
+ return false;
+ }
+ if (!country_flags.emplace(flag).second && warn) {
Logger::warning(
- "Attempted to add accepted culture ", new_accepted_culture->get_identifier(), " to country ",
- country_definition->get_identifier(), ": already present!"
+ "Attempted to set country flag \"", flag, "\" for country ", get_identifier(), ": already set!"
);
- return false;
}
- accepted_cultures.push_back(new_accepted_culture);
return true;
}
-bool CountryInstance::remove_accepted_culture(Culture const* culture_to_remove) {
- auto existing_entry = std::find(accepted_cultures.begin(), accepted_cultures.end(), culture_to_remove);
- if (existing_entry == accepted_cultures.end()) {
+bool CountryInstance::clear_country_flag(std::string_view flag, bool warn) {
+ if (flag.empty()) {
+ Logger::error("Attempted to clear empty country flag from country ", get_identifier());
+ return false;
+ }
+ if (country_flags.erase(flag) == 0 && warn) {
Logger::warning(
- "Attempted to remove accepted culture ", culture_to_remove->get_identifier(), " from country ",
- country_definition->get_identifier(), ": not present!"
+ "Attempted to clear country flag \"", flag, "\" from country ", get_identifier(), ": not set!"
);
- return false;
}
- accepted_cultures.erase(existing_entry);
return true;
}
+#define ADD_AND_REMOVE(item) \
+ bool CountryInstance::add_##item(std::remove_pointer_t<decltype(item##s)::value_type>& new_item) { \
+ if (!item##s.emplace(&new_item).second) { \
+ Logger::error( \
+ "Attempted to add " #item " \"", new_item.get_identifier(), "\" to country ", get_identifier(), \
+ ": already present!" \
+ ); \
+ return false; \
+ } \
+ return true; \
+ } \
+ bool CountryInstance::remove_##item(std::remove_pointer_t<decltype(item##s)::value_type>& item_to_remove) { \
+ if (item##s.erase(&item_to_remove) == 0) { \
+ Logger::error( \
+ "Attempted to remove " #item " \"", item_to_remove.get_identifier(), "\" from country ", get_identifier(), \
+ ": not present!" \
+ ); \
+ return false; \
+ } \
+ return true; \
+ }
+
+ADD_AND_REMOVE(owned_province)
+ADD_AND_REMOVE(controlled_province)
+ADD_AND_REMOVE(core_province)
+ADD_AND_REMOVE(state)
+ADD_AND_REMOVE(accepted_culture)
+
+#undef ADD_AND_REMOVE
+
bool CountryInstance::set_upper_house(Ideology const* ideology, fixed_point_t popularity) {
if (ideology != nullptr) {
upper_house[*ideology] = popularity;
@@ -145,7 +242,7 @@ template void CountryInstance::add_leader(LeaderBranched<UnitType::branch_t::NAV
template bool CountryInstance::remove_leader(LeaderBranched<UnitType::branch_t::LAND> const*);
template bool CountryInstance::remove_leader(LeaderBranched<UnitType::branch_t::NAVAL> const*);
-bool CountryInstance::apply_history_to_country(CountryHistoryEntry const* entry) {
+bool CountryInstance::apply_history_to_country(CountryHistoryEntry const* entry, MapInstance& map_instance) {
if (entry == nullptr) {
Logger::error("Trying to apply null country history to ", get_identifier());
return false;
@@ -161,13 +258,15 @@ bool CountryInstance::apply_history_to_country(CountryHistoryEntry const* entry)
set_optional(primary_culture, entry->get_primary_culture());
for (Culture const* culture : entry->get_accepted_cultures()) {
- ret &= add_accepted_culture(culture);
+ ret &= add_accepted_culture(*culture);
}
set_optional(religion, entry->get_religion());
set_optional(ruling_party, entry->get_ruling_party());
set_optional(last_election, entry->get_last_election());
ret &= upper_house.copy(entry->get_upper_house());
- set_optional(capital, entry->get_capital());
+ if (entry->get_capital()) {
+ capital = &map_instance.get_province_instance_from_definition(**entry->get_capital());
+ }
set_optional(government_type, entry->get_government_type());
set_optional(plurality, entry->get_plurality());
set_optional(national_value, entry->get_national_value());
@@ -176,20 +275,158 @@ bool CountryInstance::apply_history_to_country(CountryHistoryEntry const* entry)
for (Reform const* reform : entry->get_reforms()) {
ret &= add_reform(reform);
}
+ set_optional(tech_school, entry->get_tech_school());
+ constexpr auto set_bool_map_to_indexed_map =
+ []<typename T>(IndexedMap<T, bool>& target, ordered_map<T const*, bool> source) {
+ for (auto const& [key, value] : source) {
+ target[*key] = value;
+ }
+ };
+ set_bool_map_to_indexed_map(technologies, entry->get_technologies());
+ set_bool_map_to_indexed_map(inventions, entry->get_inventions());
+ // entry->get_foreign_investment();
+
+ // These need to be applied to pops
+ // entry->get_consciousness();
+ // entry->get_nonstate_consciousness();
+ // entry->get_literacy();
+ // entry->get_nonstate_culture_literacy();
+
+ set_optional(releasable_vassal, entry->is_releasable_vassal());
+ // entry->get_colonial_points();
+ for (std::string const& flag : entry->get_country_flags()) {
+ ret &= set_country_flag(flag, true);
+ }
+ for (std::string const& flag : entry->get_global_flags()) {
+ // TODO - set global flag
+ }
+ // entry->get_government_flag_overrides();
+ for (Decision const* decision : entry->get_decisions()) {
+ // TODO - take decision
+ }
return ret;
}
+void CountryInstance::_update_production() {
+
+}
+
+void CountryInstance::_update_budget() {
+
+}
+
+void CountryInstance::_update_technology() {
+
+}
+
+void CountryInstance::_update_politics() {
+
+}
+
+void CountryInstance::_update_population() {
+ total_population = 0;
+ national_literacy = 0;
+ national_consciousness = 0;
+ national_militancy = 0;
+ pop_type_distribution.clear();
+
+ for (auto const& state : states) {
+ total_population += state->get_total_population();
+
+ // TODO - change casting if Pop::pop_size_t changes type
+ const fixed_point_t state_population = fixed_point_t::parse(state->get_total_population());
+ national_literacy += state->get_average_literacy() * state_population;
+ national_consciousness += state->get_average_consciousness() * state_population;
+ national_militancy += state->get_average_militancy() * state_population;
+
+ pop_type_distribution += state->get_pop_type_distribution();
+ }
+
+ if (total_population > 0) {
+ national_literacy /= total_population;
+ national_consciousness /= total_population;
+ national_militancy /= total_population;
+ }
+
+ // TODO - update national focus capacity
+}
+
+void CountryInstance::_update_trade() {
+ // TODO - update total amount of each good exported and imported
+}
+
+void CountryInstance::_update_diplomacy() {
+ // TODO - update prestige, industrial_power, military_power (ranks will be updated after all countries have calculated their scores)
+ // TODO - update diplomatic points and colonial power
+}
+
+void CountryInstance::_update_military() {
+ regiment_count = 0;
+
+ for (ArmyInstance const* army : armies) {
+ regiment_count += army->get_unit_count();
+ }
+
+ ship_count = 0;
+ total_consumed_ship_supply = 0;
+
+ for (NavyInstance const* navy : navies) {
+ ship_count += navy->get_unit_count();
+ total_consumed_ship_supply += navy->get_total_consumed_supply();
+ }
+
+ // TODO - update mobilisation_regiment_potential, max_ship_supply, leadership_points, war_exhaustion
+}
+
+void CountryInstance::update_gamestate() {
+ if (country_definition != nullptr) {
+ const CountryDefinition::government_colour_map_t::const_iterator it =
+ country_definition->get_alternative_colours().find(government_type);
+
+ if (it != country_definition->get_alternative_colours().end()) {
+ colour = it->second;
+ } else {
+ colour = country_definition->get_colour();
+ }
+ } else {
+ colour = ERROR_COLOUR;
+ }
+
+ // Order of updates might need to be changed/functions split up to account for dependencies
+ _update_production();
+ _update_budget();
+ _update_technology();
+ _update_politics();
+ _update_population();
+ _update_trade();
+ _update_diplomacy();
+ _update_military();
+}
+
+void CountryInstance::tick() {
+
+}
+
+CountryInstance& CountryInstanceManager::get_country_instance_from_definition(CountryDefinition const& country) {
+ return country_instances.get_items()[country.get_index()];
+}
+
+CountryInstance const& CountryInstanceManager::get_country_instance_from_definition(CountryDefinition const& country) const {
+ return country_instances.get_items()[country.get_index()];
+}
+
bool CountryInstanceManager::generate_country_instances(
CountryDefinitionManager const& country_definition_manager,
decltype(CountryInstance::technologies)::keys_t const& technology_keys,
decltype(CountryInstance::inventions)::keys_t const& invention_keys,
- decltype(CountryInstance::upper_house)::keys_t const& ideology_keys
+ decltype(CountryInstance::upper_house)::keys_t const& ideology_keys,
+ decltype(CountryInstance::pop_type_distribution)::keys_t const& pop_type_keys
) {
reserve_more(country_instances, country_definition_manager.get_country_definition_count());
for (CountryDefinition const& country_definition : country_definition_manager.get_country_definitions()) {
- country_instances.add_item({ &country_definition, technology_keys, invention_keys, ideology_keys });
+ country_instances.add_item({ &country_definition, technology_keys, invention_keys, ideology_keys, pop_type_keys });
}
return true;
@@ -210,7 +447,7 @@ bool CountryInstanceManager::apply_history_to_countries(
CountryHistoryEntry const* oob_history_entry = nullptr;
for (CountryHistoryEntry const* entry : history_map->get_entries_up_to(date)) {
- ret &= country_instance.apply_history_to_country(entry);
+ ret &= country_instance.apply_history_to_country(entry, map_instance);
if (entry->get_inital_oob()) {
oob_history_entry = entry;
@@ -231,3 +468,15 @@ bool CountryInstanceManager::apply_history_to_countries(
return ret;
}
+
+void CountryInstanceManager::update_gamestate() {
+ for (CountryInstance& country : country_instances.get_items()) {
+ country.update_gamestate();
+ }
+}
+
+void CountryInstanceManager::tick() {
+ for (CountryInstance& country : country_instances.get_items()) {
+ country.tick();
+ }
+}