diff options
Diffstat (limited to 'src/openvic-simulation/pop/Pop.hpp')
-rw-r--r-- | src/openvic-simulation/pop/Pop.hpp | 167 |
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 ); |