aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/pop/Pop.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/pop/Pop.hpp')
-rw-r--r--src/openvic-simulation/pop/Pop.hpp167
1 files changed, 143 insertions, 24 deletions
diff --git a/src/openvic-simulation/pop/Pop.hpp b/src/openvic-simulation/pop/Pop.hpp
index ffef6ea..5a4cebf 100644
--- a/src/openvic-simulation/pop/Pop.hpp
+++ b/src/openvic-simulation/pop/Pop.hpp
@@ -1,16 +1,21 @@
#pragma once
+#include <limits>
+#include <ostream>
+
#include "openvic-simulation/economy/Good.hpp"
-#include "openvic-simulation/military/Unit.hpp"
#include "openvic-simulation/pop/Culture.hpp"
#include "openvic-simulation/pop/Religion.hpp"
#include "openvic-simulation/scripts/ConditionalWeight.hpp"
+#include "openvic-simulation/types/EnumBitfield.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
namespace OpenVic {
struct PopManager;
struct PopType;
+ struct Unit;
+ struct UnitManager;
struct RebelType;
struct RebelManager;
struct Ideology;
@@ -26,6 +31,8 @@ namespace OpenVic {
using pop_size_t = int64_t;
+ static constexpr pop_size_t MAX_SIZE = std::numeric_limits<pop_size_t>::max();
+
private:
PopType const& PROPERTY(type);
Culture const& PROPERTY(culture);
@@ -46,8 +53,13 @@ namespace OpenVic {
RebelType const* PROPERTY(rebel_type);
Pop(
- PopType const& new_type, Culture const& new_culture, Religion const& new_religion, pop_size_t new_size,
- fixed_point_t new_militancy, fixed_point_t new_consciousness, RebelType const* new_rebel_type
+ PopType const& new_type,
+ Culture const& new_culture,
+ Religion const& new_religion,
+ pop_size_t new_size,
+ fixed_point_t new_militancy,
+ fixed_point_t new_consciousness,
+ RebelType const* new_rebel_type
);
public:
@@ -73,6 +85,16 @@ namespace OpenVic {
struct PopType : HasIdentifierAndColour {
friend struct PopManager;
+ /* This is a bitfield - PopTypes can have up to one of each income source for each need category. */
+ enum struct income_type_t : uint8_t {
+ NO_INCOME_TYPE = 0,
+ ADMINISTRATION = 1 << 0,
+ EDUCATION = 1 << 1,
+ MILITARY = 1 << 2,
+ REFORMS = 1 << 3,
+ MAX_INCOME_TYPE = (1 << 4) - 1
+ };
+
using sprite_t = uint8_t;
using rebel_units_t = fixed_point_map_t<Unit const*>;
using poptype_weight_map_t = ordered_map<PopType const*, ConditionalWeight>;
@@ -85,6 +107,9 @@ namespace OpenVic {
Good::good_map_t PROPERTY(life_needs);
Good::good_map_t PROPERTY(everyday_needs);
Good::good_map_t PROPERTY(luxury_needs);
+ income_type_t PROPERTY(life_needs_income_types);
+ income_type_t PROPERTY(everyday_needs_income_types);
+ income_type_t PROPERTY(luxury_needs_income_types);
rebel_units_t PROPERTY(rebel_units);
const Pop::pop_size_t PROPERTY(max_size);
const Pop::pop_size_t PROPERTY(merge_max_size);
@@ -96,10 +121,15 @@ namespace OpenVic {
const bool PROPERTY(can_be_recruited);
const bool PROPERTY(can_reduce_consciousness);
const bool PROPERTY(administrative_efficiency);
- const bool PROPERTY(can_build);
+ const bool PROPERTY(can_invest);
const bool PROPERTY(factory);
const bool PROPERTY(can_work_factory);
const bool PROPERTY(unemployment);
+ const fixed_point_t PROPERTY(research_points);
+ const fixed_point_t PROPERTY(leadership_points);
+ const fixed_point_t PROPERTY(research_leadership_optimum);
+ const fixed_point_t PROPERTY(state_administration_multiplier);
+ PopType const* PROPERTY(equivalent);
ConditionalWeight PROPERTY(country_migration_target); /* Scope - country, THIS - pop */
ConditionalWeight PROPERTY(migration_target); /* Scope - province, THIS - pop */
@@ -108,14 +138,41 @@ namespace OpenVic {
issue_weight_map_t PROPERTY(issues); /* Scope - province, THIS - country (?) */
PopType(
- std::string_view new_identifier, colour_t new_colour, Strata const& new_strata, sprite_t new_sprite,
- Good::good_map_t&& new_life_needs, Good::good_map_t&& new_everyday_needs, Good::good_map_t&& new_luxury_needs,
- rebel_units_t&& new_rebel_units, Pop::pop_size_t new_max_size, Pop::pop_size_t new_merge_max_size,
- bool new_state_capital_only, bool new_demote_migrant, bool new_is_artisan, bool new_allowed_to_vote,
- bool new_is_slave, bool new_can_be_recruited, bool new_can_reduce_consciousness,
- bool new_administrative_efficiency, bool new_can_build, bool new_factory, bool new_can_work_factory,
- bool new_unemployment, ConditionalWeight&& new_country_migration_target, ConditionalWeight&& new_migration_target,
- poptype_weight_map_t&& new_promote_to, ideology_weight_map_t&& new_ideologies, issue_weight_map_t&& new_issues
+ std::string_view new_identifier,
+ colour_t new_colour,
+ Strata const& new_strata,
+ sprite_t new_sprite,
+ Good::good_map_t&& new_life_needs,
+ Good::good_map_t&& new_everyday_needs,
+ Good::good_map_t&& new_luxury_needs,
+ income_type_t new_life_needs_income_types,
+ income_type_t new_everyday_needs_income_types,
+ income_type_t new_luxury_needs_income_types,
+ rebel_units_t&& new_rebel_units,
+ Pop::pop_size_t new_max_size,
+ Pop::pop_size_t new_merge_max_size,
+ bool new_state_capital_only,
+ bool new_demote_migrant,
+ bool new_is_artisan,
+ bool new_allowed_to_vote,
+ bool new_is_slave,
+ bool new_can_be_recruited,
+ bool new_can_reduce_consciousness,
+ bool new_administrative_efficiency,
+ bool new_can_invest,
+ bool new_factory,
+ bool new_can_work_factory,
+ bool new_unemployment,
+ fixed_point_t new_research_points,
+ fixed_point_t new_leadership_points,
+ fixed_point_t new_research_leadership_optimum,
+ fixed_point_t new_state_administration_multiplier,
+ PopType const* new_equivalent,
+ ConditionalWeight&& new_country_migration_target,
+ ConditionalWeight&& new_migration_target,
+ poptype_weight_map_t&& new_promote_to,
+ ideology_weight_map_t&& new_ideologies,
+ issue_weight_map_t&& new_issues
);
bool parse_scripts(GameManager const& game_manager);
@@ -124,6 +181,40 @@ namespace OpenVic {
PopType(PopType&&) = default;
};
+ template<> struct enable_bitfield<PopType::income_type_t> : std::true_type {};
+
+ /* This returns true if at least one income type is shared by both arguments. */
+ constexpr inline bool share_income_type(PopType::income_type_t lhs, PopType::income_type_t rhs) {
+ return (lhs & rhs) != PopType::income_type_t::NO_INCOME_TYPE;
+ }
+
+ inline std::ostream& operator<<(std::ostream& stream, PopType::income_type_t income_type) {
+ using enum PopType::income_type_t;
+ if (income_type == NO_INCOME_TYPE) {
+ return stream << "[NO_INCOME_TYPE]";
+ }
+ bool type_found = false;
+ stream << '[';
+#define BUILD_STRING(entry) \
+ if (share_income_type(income_type, entry)) { \
+ if (type_found) { \
+ stream << " | "; \
+ } else { \
+ type_found = true; \
+ } \
+ stream << #entry; \
+ }
+ BUILD_STRING(ADMINISTRATION);
+ BUILD_STRING(EDUCATION);
+ BUILD_STRING(MILITARY);
+ BUILD_STRING(REFORMS);
+#undef BUILD_STRING
+ if (!type_found) {
+ stream << "INVALID INCOME TYPE";
+ }
+ return stream << ']';
+ }
+
struct Province;
struct PopManager {
@@ -131,11 +222,12 @@ namespace OpenVic {
/* Using strata/stratas instead of stratum/strata to avoid confusion. */
IdentifierRegistry<Strata> IDENTIFIER_REGISTRY(strata);
IdentifierRegistry<PopType> IDENTIFIER_REGISTRY(pop_type);
- /* promote_to can't be parsed until after all PopTypes are registered, and issues requires Issues to be loaded,
- * which themselves depend on pop strata. To get around this, the nodes for these variables are stored here and
- * parsed after both PopTypes and Issues. The nodes will remain valid as PopType files' Parser objects are cached
- * to preserve their condition script nodes until all other defines are loaded and the scripts can be parsed. */
- std::vector<std::pair<ast::NodeCPtr, ast::NodeCPtr>> delayed_parse_promote_to_and_issues_nodes;
+ /* equivalent and promote_to can't be parsed until after all PopTypes are registered, and issues requires Issues
+ * to be loaded, which themselves depend on pop strata. To get around this, the nodes for these variables are stored
+ * here and parsed after both PopTypes and Issues. The nodes will remain valid as PopType files' Parser objects are
+ * cached to preserve their condition script nodes until all other defines are loaded and the scripts can be parsed.
+ * Entries contain: (equivalent, promote_to, issues) */
+ std::vector<std::tuple<ast::NodeCPtr, ast::NodeCPtr, ast::NodeCPtr>> delayed_parse_nodes;
ConditionalWeight PROPERTY(promotion_chance);
ConditionalWeight PROPERTY(demotion_chance);
@@ -157,13 +249,40 @@ namespace OpenVic {
bool add_strata(std::string_view identifier);
bool add_pop_type(
- std::string_view identifier, colour_t new_colour, Strata const* strata, PopType::sprite_t sprite,
- Good::good_map_t&& life_needs, Good::good_map_t&& everyday_needs, Good::good_map_t&& luxury_needs,
- PopType::rebel_units_t&& rebel_units, Pop::pop_size_t max_size, Pop::pop_size_t merge_max_size,
- bool state_capital_only, bool demote_migrant, bool is_artisan, bool allowed_to_vote, bool is_slave,
- bool can_be_recruited, bool can_reduce_consciousness, bool administrative_efficiency, bool can_build, bool factory,
- bool can_work_factory, bool unemployment, ConditionalWeight&& country_migration_target,
- ConditionalWeight&& migration_target, ast::NodeCPtr promote_to_node, PopType::ideology_weight_map_t&& ideologies,
+ std::string_view identifier,
+ colour_t new_colour,
+ Strata const* strata,
+ PopType::sprite_t sprite,
+ Good::good_map_t&& life_needs,
+ Good::good_map_t&& everyday_needs,
+ Good::good_map_t&& luxury_needs,
+ PopType::income_type_t life_needs_income_types,
+ PopType::income_type_t everyday_needs_income_types,
+ PopType::income_type_t luxury_needs_income_types,
+ PopType::rebel_units_t&& rebel_units,
+ Pop::pop_size_t max_size,
+ Pop::pop_size_t merge_max_size,
+ bool state_capital_only,
+ bool demote_migrant,
+ bool is_artisan,
+ bool allowed_to_vote,
+ bool is_slave,
+ bool can_be_recruited,
+ bool can_reduce_consciousness,
+ bool administrative_efficiency,
+ bool can_invest,
+ bool factory,
+ bool can_work_factory,
+ bool unemployment,
+ fixed_point_t research_points,
+ fixed_point_t leadership_points,
+ fixed_point_t research_leadership_optimum,
+ fixed_point_t state_administration_multiplier,
+ ast::NodeCPtr equivalent,
+ ConditionalWeight&& country_migration_target,
+ ConditionalWeight&& migration_target,
+ ast::NodeCPtr promote_to_node,
+ PopType::ideology_weight_map_t&& ideologies,
ast::NodeCPtr issues_node
);