diff options
Diffstat (limited to 'src/openvic-simulation')
24 files changed, 275 insertions, 131 deletions
diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index 51e3e82..43c5092 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -287,11 +287,14 @@ namespace OpenVic { ret &= add_key_map_entries(FWD(key_map), FWD(args)...); return ret; } + template<IsOrderedMap Map> NodeCallback auto expect_dictionary_key_map_and_length_and_default( Map&& key_map, LengthCallback auto&& length_callback, KeyValueCallback auto&& default_callback ) { - return [length_callback = FWD(length_callback), default_callback = FWD(default_callback), key_map = MOV(key_map)](ast::NodeCPtr node) mutable -> bool { + return [length_callback = FWD(length_callback), default_callback = FWD(default_callback), key_map = MOV(key_map)]( + ast::NodeCPtr node + ) mutable -> bool { bool ret = expect_dictionary_and_length( FWD(length_callback), dictionary_keys_callback(key_map, FWD(default_callback)) )(node); @@ -335,6 +338,28 @@ namespace OpenVic { return expect_dictionary_key_map_and_length_and_default(FWD(key_map), FWD(length_callback), FWD(default_callback)); } + template<IsOrderedMap Map, typename... Args> + NodeCallback auto expect_dictionary_key_map_and_length( + Map&& key_map, LengthCallback auto&& length_callback, Args&&... args + ) { + add_key_map_entries(FWD(key_map), FWD(args)...); + return expect_dictionary_key_map_and_length(FWD(key_map), FWD(length_callback)); + } + + template<IsOrderedMap Map, typename... Args> + NodeCallback auto expect_dictionary_key_map_and_default( + Map&& key_map, KeyValueCallback auto&& default_callback, Args&&... args + ) { + add_key_map_entries(FWD(key_map), FWD(args)...); + return expect_dictionary_key_map_and_default(FWD(key_map), FWD(default_callback)); + } + + template<IsOrderedMap Map, typename... Args> + NodeCallback auto expect_dictionary_key_map(Map&& key_map, Args&&... args) { + add_key_map_entries(FWD(key_map), FWD(args)...); + return expect_dictionary_key_map(FWD(key_map)); + } + template<StringMapCase Case = StringMapCaseSensitive, typename... Args> NodeCallback auto expect_dictionary_keys_and_length_and_default( LengthCallback auto&& length_callback, KeyValueCallback auto&& default_callback, Args&&... args diff --git a/src/openvic-simulation/economy/production/ProductionType.cpp b/src/openvic-simulation/economy/production/ProductionType.cpp index c5db641..033026d 100644 --- a/src/openvic-simulation/economy/production/ProductionType.cpp +++ b/src/openvic-simulation/economy/production/ProductionType.cpp @@ -271,13 +271,18 @@ bool ProductionTypeManager::load_production_types_file( auto parse_node = expect_dictionary_keys( "template", ZERO_OR_ONE, success_callback, /* Already parsed using expect_key in Pass #1 above. */ "bonus", ZERO_OR_MORE, [&bonuses](ast::NodeCPtr bonus_node) -> bool { - ConditionScript trigger { scope_t::STATE, scope_t::NO_SCOPE, scope_t::NO_SCOPE }; + using enum scope_type_t; + + ConditionScript trigger { STATE, NO_SCOPE, NO_SCOPE }; fixed_point_t bonus_value {}; + const bool ret = expect_dictionary_keys( "trigger", ONE_EXACTLY, trigger.expect_script(), "value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(bonus_value)) )(bonus_node); + bonuses.emplace_back(std::move(trigger), bonus_value); + return ret; }, "owner", ZERO_OR_ONE, _expect_job(good_definition_manager, pop_manager, move_variable_callback(owner)), diff --git a/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp b/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp index df91645..70cb64d 100644 --- a/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp +++ b/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp @@ -83,12 +83,20 @@ Pop::pop_size_t ResourceGatheringOperation::update_size_and_return_total_worker_ } } } + + fixed_point_t base_size_modifier = fixed_point_t::_1(); + if (production_type.is_farm()) { + base_size_modifier += location.get_modifier_effect_value_nullcheck(modifier_effect_cache.get_farm_rgo_size_local()); + } + if (production_type.is_mine()) { + base_size_modifier += location.get_modifier_effect_value_nullcheck(modifier_effect_cache.get_mine_rgo_size_local()); + } const fixed_point_t base_workforce_size = production_type.get_base_workforce_size(); - if (size_modifier == fixed_point_t::_0()) { + if (base_size_modifier == fixed_point_t::_0()) { size_multiplier = 0; } else { - size_multiplier = ((total_worker_count_in_province / (size_modifier * base_workforce_size)).ceil() * fixed_point_t::_1_50()).floor(); + size_multiplier = ((total_worker_count_in_province / (base_size_modifier * base_workforce_size)).ceil() * fixed_point_t::_1_50()).floor(); } max_employee_count_cache = (size_modifier * size_multiplier * base_workforce_size).floor(); return total_worker_count_in_province; diff --git a/src/openvic-simulation/map/Crime.cpp b/src/openvic-simulation/map/Crime.cpp index f52352c..ce0c623 100644 --- a/src/openvic-simulation/map/Crime.cpp +++ b/src/openvic-simulation/map/Crime.cpp @@ -30,9 +30,11 @@ bool CrimeManager::load_crime_modifiers(ModifierManager const& modifier_manager, const bool ret = expect_dictionary_reserve_length( crime_modifiers, [this, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool { + using enum scope_type_t; + ModifierValue modifier_value; IconModifier::icon_t icon = 0; - ConditionScript trigger { scope_t::PROVINCE, scope_t::NO_SCOPE, scope_t::NO_SCOPE }; + ConditionScript trigger { PROVINCE, NO_SCOPE, NO_SCOPE }; bool default_active = false; bool ret = NodeTools::expect_dictionary_keys_and_default( diff --git a/src/openvic-simulation/military/Wargoal.cpp b/src/openvic-simulation/military/Wargoal.cpp index 773e791..ce6b153 100644 --- a/src/openvic-simulation/military/Wargoal.cpp +++ b/src/openvic-simulation/military/Wargoal.cpp @@ -86,6 +86,7 @@ bool WargoalTypeManager::load_wargoal_file(ovdl::v2script::Parser const& parser) } using enum WargoalType::peace_options_t; + using enum scope_type_t; std::string_view war_name; Timespan available {}, truce {}; @@ -94,12 +95,12 @@ bool WargoalTypeManager::load_wargoal_file(ovdl::v2script::Parser const& parser) mutual = false, all_allowed_states = false, always = false; WargoalType::peace_options_t peace_options = NO_PEACE_OPTIONS; WargoalType::peace_modifiers_t modifiers; - ConditionScript can_use { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::COUNTRY }; - ConditionScript is_valid { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::COUNTRY }; - ConditionScript allowed_states { scope_t::STATE, scope_t::COUNTRY, scope_t::COUNTRY }; - ConditionScript allowed_substate_regions { scope_t::STATE, scope_t::COUNTRY, scope_t::COUNTRY }; - ConditionScript allowed_states_in_crisis { scope_t::STATE, scope_t::COUNTRY, scope_t::COUNTRY }; - ConditionScript allowed_countries { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::COUNTRY }; + ConditionScript can_use { COUNTRY, COUNTRY, COUNTRY }; + ConditionScript is_valid { COUNTRY, COUNTRY, COUNTRY }; + ConditionScript allowed_states { STATE, COUNTRY, COUNTRY }; + ConditionScript allowed_substate_regions { STATE, COUNTRY, COUNTRY }; + ConditionScript allowed_states_in_crisis { STATE, COUNTRY, COUNTRY }; + ConditionScript allowed_countries { COUNTRY, COUNTRY, COUNTRY }; EffectScript on_add, on_po_accepted; //country as default scope for both const auto expect_peace_option = [&peace_options](WargoalType::peace_options_t peace_option) -> node_callback_t { diff --git a/src/openvic-simulation/misc/Decision.cpp b/src/openvic-simulation/misc/Decision.cpp index 41d4f81..7812fc1 100644 --- a/src/openvic-simulation/misc/Decision.cpp +++ b/src/openvic-simulation/misc/Decision.cpp @@ -55,12 +55,15 @@ bool DecisionManager::load_decision_file(ast::NodeCPtr root) { "political_decisions", ZERO_OR_ONE, expect_dictionary_reserve_length( decisions, [this](std::string_view identifier, ast::NodeCPtr node) -> bool { + using enum scope_type_t; + bool alert = true, news = false; std::string_view news_title, news_desc_long, news_desc_medium, news_desc_short, picture; - ConditionScript potential { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionScript allow { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight ai_will_do { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionScript potential { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionScript allow { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight ai_will_do { COUNTRY, COUNTRY, NO_SCOPE }; EffectScript effect; + bool ret = expect_dictionary_keys( "alert", ZERO_OR_ONE, expect_bool(assign_variable_callback(alert)), "news", ZERO_OR_ONE, expect_bool(assign_variable_callback(news)), @@ -74,10 +77,12 @@ bool DecisionManager::load_decision_file(ast::NodeCPtr root) { "effect", ONE_EXACTLY, effect.expect_script(), "ai_will_do", ZERO_OR_ONE, ai_will_do.expect_conditional_weight(ConditionalWeight::FACTOR) )(node); + ret &= add_decision( identifier, alert, news, news_title, news_desc_long, news_desc_medium, news_desc_short, picture, std::move(potential), std::move(allow), std::move(ai_will_do), std::move(effect) ); + return ret; } ) diff --git a/src/openvic-simulation/misc/Event.cpp b/src/openvic-simulation/misc/Event.cpp index 5bfc929..64b1f64 100644 --- a/src/openvic-simulation/misc/Event.cpp +++ b/src/openvic-simulation/misc/Event.cpp @@ -119,15 +119,17 @@ bool EventManager::load_event_file(IssueManager const& issue_manager, ast::NodeC return expect_dictionary_reserve_length( events, [this, &issue_manager](std::string_view key, ast::NodeCPtr value) -> bool { + using enum scope_type_t; + Event::event_type_t type; - scope_t initial_scope; + scope_type_t initial_scope; if (key == "country_event") { type = Event::event_type_t::COUNTRY; - initial_scope = scope_t::COUNTRY; + initial_scope = COUNTRY; } else if (key == "province_event") { type = Event::event_type_t::PROVINCE; - initial_scope = scope_t::PROVINCE; + initial_scope = PROVINCE; } else { Logger::error("Invalid event type: ", key); return false; @@ -138,8 +140,8 @@ bool EventManager::load_event_file(IssueManager const& issue_manager, ast::NodeC bool triggered_only = false, major = false, fire_only_once = false, allows_multiple_instances = false, news = false, election = false; IssueGroup const* election_issue_group = nullptr; - ConditionScript trigger { initial_scope, initial_scope, scope_t::NO_SCOPE }; - ConditionalWeight mean_time_to_happen { initial_scope, initial_scope, scope_t::NO_SCOPE }; + ConditionScript trigger { initial_scope, initial_scope, NO_SCOPE }; + ConditionalWeight mean_time_to_happen { initial_scope, initial_scope, NO_SCOPE }; EffectScript immediate; std::vector<Event::EventOption> options; @@ -166,7 +168,7 @@ bool EventManager::load_event_file(IssueManager const& issue_manager, ast::NodeC ConditionalWeight ai_chance { initial_scope, initial_scope, - scope_t::COUNTRY | scope_t::PROVINCE + COUNTRY | PROVINCE // TODO - decide which to use? }; bool ret = expect_dictionary_keys_and_default( @@ -181,7 +183,7 @@ bool EventManager::load_event_file(IssueManager const& issue_manager, ast::NodeC return ret; }, "trigger", ZERO_OR_ONE, trigger.expect_script(), - "mean_time_to_happen", ZERO_OR_ONE, mean_time_to_happen.expect_conditional_weight(ConditionalWeight::MONTHS), + "mean_time_to_happen", ZERO_OR_ONE, mean_time_to_happen.expect_conditional_weight(ConditionalWeight::TIME), "immediate", ZERO_OR_MORE, immediate.expect_script() )(value); ret &= register_event( diff --git a/src/openvic-simulation/misc/SongChance.cpp b/src/openvic-simulation/misc/SongChance.cpp index 94fb571..d05afdf 100644 --- a/src/openvic-simulation/misc/SongChance.cpp +++ b/src/openvic-simulation/misc/SongChance.cpp @@ -17,12 +17,14 @@ bool SongChanceManager::load_songs_file(ast::NodeCPtr root) { ret &= expect_dictionary_reserve_length( song_chances, [this](std::string_view key, ast::NodeCPtr value) -> bool { + using enum scope_type_t; + if (key != "song") { Logger::error("Invalid song declaration ", key); return false; } std::string_view name {}; - ConditionalWeight chance { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionalWeight chance { COUNTRY, COUNTRY, NO_SCOPE }; bool ret = expect_dictionary_keys( "name", ONE_EXACTLY, expect_string(assign_variable_callback(name)), diff --git a/src/openvic-simulation/modifier/ModifierEffectCache.cpp b/src/openvic-simulation/modifier/ModifierEffectCache.cpp index afb733a..a02dcb6 100644 --- a/src/openvic-simulation/modifier/ModifierEffectCache.cpp +++ b/src/openvic-simulation/modifier/ModifierEffectCache.cpp @@ -181,6 +181,7 @@ ModifierEffectCache::ModifierEffectCache() farm_rgo_throughput_global { nullptr }, farm_rgo_output_global { nullptr }, farm_rgo_output_local { nullptr }, + farm_rgo_size_fake { nullptr }, farm_rgo_size_global { nullptr }, farm_rgo_size_local { nullptr }, immigrant_attract { nullptr }, @@ -202,6 +203,7 @@ ModifierEffectCache::ModifierEffectCache() mine_rgo_throughput_global { nullptr }, mine_rgo_output_global { nullptr }, mine_rgo_output_local { nullptr }, + mine_rgo_size_fake { nullptr }, mine_rgo_size_global { nullptr }, mine_rgo_size_local { nullptr }, movement_cost_base { nullptr }, diff --git a/src/openvic-simulation/modifier/ModifierEffectCache.hpp b/src/openvic-simulation/modifier/ModifierEffectCache.hpp index 757eca0..7d08d29 100644 --- a/src/openvic-simulation/modifier/ModifierEffectCache.hpp +++ b/src/openvic-simulation/modifier/ModifierEffectCache.hpp @@ -151,6 +151,7 @@ namespace OpenVic { ModifierEffect const* PROPERTY(farm_rgo_throughput_global); ModifierEffect const* PROPERTY(farm_rgo_output_global); ModifierEffect const* PROPERTY(farm_rgo_output_local); + ModifierEffect const* PROPERTY(farm_rgo_size_fake); ModifierEffect const* PROPERTY(farm_rgo_size_global); ModifierEffect const* PROPERTY(farm_rgo_size_local); ModifierEffect const* PROPERTY(immigrant_attract); @@ -172,6 +173,7 @@ namespace OpenVic { ModifierEffect const* PROPERTY(mine_rgo_throughput_global); ModifierEffect const* PROPERTY(mine_rgo_output_global); ModifierEffect const* PROPERTY(mine_rgo_output_local); + ModifierEffect const* PROPERTY(mine_rgo_size_fake); ModifierEffect const* PROPERTY(mine_rgo_size_global); ModifierEffect const* PROPERTY(mine_rgo_size_local); ModifierEffect const* PROPERTY(movement_cost_base); diff --git a/src/openvic-simulation/modifier/ModifierManager.cpp b/src/openvic-simulation/modifier/ModifierManager.cpp index a5ef8a8..3bc0c97 100644 --- a/src/openvic-simulation/modifier/ModifierManager.cpp +++ b/src/openvic-simulation/modifier/ModifierManager.cpp @@ -428,7 +428,11 @@ bool ModifierManager::setup_modifier_effects() { ret &= register_base_province_modifier_effect( modifier_effect_cache.farm_rgo_output_local, "farm_rgo_eff", true, PROPORTION_DECIMAL, "TECH_FARM_OUTPUT" ); - ret &= register_shared_tech_country_modifier_effect( + ret &= register_base_country_modifier_effect( + modifier_effect_cache.farm_rgo_size_fake, "farm_rgo_size", true, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("farm_size"), has_no_effect + ); + ret &= register_technology_modifier_effect( modifier_effect_cache.farm_rgo_size_global, "farm_rgo_size", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("farm_size") ); @@ -499,7 +503,11 @@ bool ModifierManager::setup_modifier_effects() { ret &= register_base_province_modifier_effect( modifier_effect_cache.mine_rgo_output_local, "mine_rgo_eff", true, PROPORTION_DECIMAL, "TECH_MINE_OUTPUT" ); - ret &= register_shared_tech_country_modifier_effect( + ret &= register_base_country_modifier_effect( + modifier_effect_cache.mine_rgo_size_fake, "mine_rgo_size", true, PROPORTION_DECIMAL, + ModifierEffect::make_default_modifier_effect_localisation_key("mine_size"), has_no_effect + ); + ret &= register_technology_modifier_effect( modifier_effect_cache.mine_rgo_size_global, "mine_rgo_size", true, PROPORTION_DECIMAL, ModifierEffect::make_default_modifier_effect_localisation_key("mine_size") ); @@ -630,9 +638,11 @@ bool ModifierManager::load_triggered_modifiers(const ast::NodeCPtr root) { const bool ret = expect_dictionary_reserve_length( triggered_modifiers, [this](const std::string_view key, const ast::NodeCPtr value) -> bool { + using enum scope_type_t; + ModifierValue modifier_value {}; IconModifier::icon_t icon = 0; - ConditionScript trigger { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionScript trigger { COUNTRY, COUNTRY, NO_SCOPE }; bool ret = expect_dictionary_keys_and_default( expect_base_country_modifier(modifier_value), diff --git a/src/openvic-simulation/politics/Ideology.cpp b/src/openvic-simulation/politics/Ideology.cpp index 546d16e..ca21997 100644 --- a/src/openvic-simulation/politics/Ideology.cpp +++ b/src/openvic-simulation/politics/Ideology.cpp @@ -83,15 +83,17 @@ bool IdeologyManager::load_ideology_file(ast::NodeCPtr root) { IdeologyGroup const* ideology_group = get_ideology_group_by_identifier(ideology_group_key); return expect_dictionary([this, ideology_group](std::string_view key, ast::NodeCPtr value) -> bool { + using enum scope_type_t; + colour_t colour = colour_t::null(); bool uncivilised = true, can_reduce_militancy = false; Date spawn_date; - ConditionalWeight add_political_reform { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight remove_political_reform { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight add_social_reform { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight remove_social_reform { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight add_military_reform { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight add_economic_reform { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionalWeight add_political_reform { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight remove_political_reform { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight add_social_reform { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight remove_social_reform { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight add_military_reform { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight add_economic_reform { COUNTRY, COUNTRY, NO_SCOPE }; bool ret = expect_dictionary_keys( "uncivilized", ZERO_OR_ONE, expect_bool(assign_variable_callback(uncivilised)), @@ -99,20 +101,24 @@ bool IdeologyManager::load_ideology_file(ast::NodeCPtr root) { "date", ZERO_OR_ONE, expect_date(assign_variable_callback(spawn_date)), "can_reduce_militancy", ZERO_OR_ONE, expect_bool(assign_variable_callback(can_reduce_militancy)), "add_political_reform", ONE_EXACTLY, add_political_reform.expect_conditional_weight(ConditionalWeight::BASE), - "remove_political_reform", ONE_EXACTLY, remove_political_reform.expect_conditional_weight(ConditionalWeight::BASE), + "remove_political_reform", ONE_EXACTLY, + remove_political_reform.expect_conditional_weight(ConditionalWeight::BASE), "add_social_reform", ONE_EXACTLY, add_social_reform.expect_conditional_weight(ConditionalWeight::BASE), "remove_social_reform", ONE_EXACTLY, remove_social_reform.expect_conditional_weight(ConditionalWeight::BASE), "add_military_reform", ZERO_OR_ONE, add_military_reform.expect_conditional_weight(ConditionalWeight::BASE), "add_economic_reform", ZERO_OR_ONE, add_economic_reform.expect_conditional_weight(ConditionalWeight::BASE) )(value); + ret &= add_ideology( key, colour, ideology_group, uncivilised, can_reduce_militancy, spawn_date, std::move(add_political_reform), std::move(remove_political_reform), std::move(add_social_reform), std::move(remove_social_reform), std::move(add_military_reform), std::move(add_economic_reform) ); + return ret; })(ideology_group_value); })(root); + lock_ideologies(); return ret; diff --git a/src/openvic-simulation/politics/Issue.cpp b/src/openvic-simulation/politics/Issue.cpp index 8da09fc..71356b6 100644 --- a/src/openvic-simulation/politics/Issue.cpp +++ b/src/openvic-simulation/politics/Issue.cpp @@ -221,12 +221,14 @@ bool IssueManager::_load_reform( ModifierManager const& modifier_manager, RuleManager const& rule_manager, size_t ordinal, std::string_view identifier, ReformGroup const* group, ast::NodeCPtr node ) { + using enum scope_type_t; + ModifierValue values; RuleSet rules; fixed_point_t administrative_multiplier = 0; Reform::tech_cost_t technology_cost = 0; - ConditionScript allow { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionScript on_execute_trigger { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionScript allow { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionScript on_execute_trigger { COUNTRY, COUNTRY, NO_SCOPE }; EffectScript on_execute_effect; bool ret = NodeTools::expect_dictionary_keys_and_default( diff --git a/src/openvic-simulation/politics/NationalFocus.cpp b/src/openvic-simulation/politics/NationalFocus.cpp index 2427d7c..b60b3f5 100644 --- a/src/openvic-simulation/politics/NationalFocus.cpp +++ b/src/openvic-simulation/politics/NationalFocus.cpp @@ -117,6 +117,8 @@ bool NationalFocusManager::load_national_foci_file( [this, &group, &pop_manager, &ideology_manager, &good_definition_manager, &modifier_manager]( std::string_view identifier, ast::NodeCPtr node ) -> bool { + using enum scope_type_t; + uint8_t icon = 0; bool has_flashpoint = false, own_provinces = true, outliner_show_as_percent = false; fixed_point_t flashpoint_tension = 0; @@ -127,7 +129,7 @@ bool NationalFocusManager::load_national_foci_file( fixed_point_map_t<GoodDefinition const*> encourage_goods; fixed_point_map_t<PopType const*> encourage_pop_types; ConditionScript limit { - scope_t::PROVINCE | scope_t::COUNTRY, scope_t::PROVINCE | scope_t::COUNTRY, scope_t::NO_SCOPE + PROVINCE | COUNTRY, PROVINCE | COUNTRY, NO_SCOPE }; const auto expect_base_province_modifier_cb = modifier_manager.expect_base_province_modifier(modifiers); diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp index 9b2927c..ccaee5e 100644 --- a/src/openvic-simulation/politics/Rebel.cpp +++ b/src/openvic-simulation/politics/Rebel.cpp @@ -98,6 +98,8 @@ bool RebelManager::load_rebels_file( bool ret = expect_dictionary_reserve_length( rebel_types, [this, &ideology_manager, &government_type_manager](std::string_view identifier, ast::NodeCPtr node) -> bool { + using enum scope_type_t; + RebelType::icon_t icon = 0; RebelType::area_t area = RebelType::area_t::ALL; RebelType::government_map_t desired_governments; @@ -109,11 +111,11 @@ bool RebelManager::load_rebels_file( allow_all_religions = true, allow_all_ideologies = true, resilient = true, reinforcing = true, general = true, smart = true, unit_transfer = false; fixed_point_t occupation_mult = 0; - ConditionalWeight will_rise { scope_t::POP, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight spawn_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }; - ConditionalWeight movement_evaluation { scope_t::PROVINCE, scope_t::PROVINCE, scope_t::NO_SCOPE }; - ConditionScript siege_won_trigger { scope_t::PROVINCE, scope_t::PROVINCE, scope_t::NO_SCOPE }; - ConditionScript demands_enforced_trigger { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionalWeight will_rise { POP, COUNTRY, NO_SCOPE }; + ConditionalWeight spawn_chance { POP, POP, NO_SCOPE }; + ConditionalWeight movement_evaluation { PROVINCE, PROVINCE, NO_SCOPE }; + ConditionScript siege_won_trigger { PROVINCE, PROVINCE, NO_SCOPE }; + ConditionScript demands_enforced_trigger { COUNTRY, COUNTRY, NO_SCOPE }; EffectScript siege_won_effect, demands_enforced_effect; bool ret = expect_dictionary_keys( diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp index d92aa24..89ff609 100644 --- a/src/openvic-simulation/pop/Pop.cpp +++ b/src/openvic-simulation/pop/Pop.cpp @@ -254,13 +254,13 @@ bool PopType::parse_scripts(DefinitionManager const& definition_manager) { PopManager::PopManager() : slave_sprite { 0 }, administrative_sprite { 0 }, - promotion_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }, - demotion_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }, - migration_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }, - colonialmigration_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }, - emigration_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }, - assimilation_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }, - conversion_chance { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE } {} + promotion_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE }, + demotion_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE }, + migration_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE }, + colonialmigration_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE }, + emigration_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE }, + assimilation_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE }, + conversion_chance { scope_type_t::POP, scope_type_t::POP, scope_type_t::NO_SCOPE } {} bool PopManager::add_strata(std::string_view identifier) { if (identifier.empty()) { @@ -441,6 +441,8 @@ bool PopManager::load_pop_type_file( std::string_view filestem, GoodDefinitionManager const& good_definition_manager, IdeologyManager const& ideology_manager, ast::NodeCPtr root ) { + using enum scope_type_t; + colour_t colour = colour_t::null(); Strata const* strata = nullptr; PopType::sprite_t sprite = 0; @@ -455,8 +457,8 @@ bool PopManager::load_pop_type_file( fixed_point_t research_points = 0, leadership_points = 0, research_leadership_optimum = 0, state_administration_multiplier = 0; ast::NodeCPtr equivalent = nullptr; - ConditionalWeight country_migration_target { scope_t::COUNTRY, scope_t::POP, scope_t::NO_SCOPE }; - ConditionalWeight migration_target { scope_t::PROVINCE, scope_t::POP, scope_t::NO_SCOPE }; + ConditionalWeight country_migration_target { COUNTRY, POP, NO_SCOPE }; + ConditionalWeight migration_target { PROVINCE, POP, NO_SCOPE }; ast::NodeCPtr promote_to_node = nullptr; PopType::ideology_weight_map_t ideologies; ast::NodeCPtr issues_node = nullptr; @@ -505,9 +507,12 @@ bool PopManager::load_pop_type_file( "ideologies", ZERO_OR_ONE, ideology_manager.expect_ideology_dictionary_reserve_length( ideologies, [&filestem, &ideologies](Ideology const& ideology, ast::NodeCPtr node) -> bool { - ConditionalWeight weight { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }; + ConditionalWeight weight { POP, POP, NO_SCOPE }; + bool ret = weight.expect_conditional_weight(ConditionalWeight::FACTOR)(node); + ret &= map_callback(ideologies, &ideology)(std::move(weight)); + return ret; } ), @@ -564,7 +569,11 @@ bool PopManager::load_pop_type_file( return ret; } -bool PopManager::load_delayed_parse_pop_type_data(UnitTypeManager const& unit_type_manager, IssueManager const& issue_manager) { +bool PopManager::load_delayed_parse_pop_type_data( + UnitTypeManager const& unit_type_manager, IssueManager const& issue_manager +) { + using enum scope_type_t; + bool ret = true; for (size_t index = 0; index < delayed_parse_nodes.size(); ++index) { const auto [rebel_units, equivalent, promote_to_node, issues_node] = delayed_parse_nodes[index]; @@ -591,7 +600,7 @@ bool PopManager::load_delayed_parse_pop_type_data(UnitTypeManager const& unit_ty Logger::error("Pop type ", type, " cannot have promotion weight to itself!"); return false; } - ConditionalWeight weight { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }; + ConditionalWeight weight { POP, POP, NO_SCOPE }; bool ret = weight.expect_conditional_weight(ConditionalWeight::FACTOR)(node); ret &= map_callback(pop_type->promote_to, &type)(std::move(weight)); return ret; @@ -612,7 +621,7 @@ bool PopManager::load_delayed_parse_pop_type_data(UnitTypeManager const& unit_ty Logger::error("Invalid issue in pop type ", pop_type, " issue weights: ", key); return false; } - ConditionalWeight weight { scope_t::POP, scope_t::POP, scope_t::NO_SCOPE }; + ConditionalWeight weight { POP, POP, NO_SCOPE }; bool ret = weight.expect_conditional_weight(ConditionalWeight::FACTOR)(node); ret &= map_callback(pop_type->issues, issue)(std::move(weight)); return ret; diff --git a/src/openvic-simulation/research/Invention.cpp b/src/openvic-simulation/research/Invention.cpp index 1076a62..4351337 100644 --- a/src/openvic-simulation/research/Invention.cpp +++ b/src/openvic-simulation/research/Invention.cpp @@ -62,6 +62,8 @@ bool InventionManager::load_inventions_file( inventions, [this, &modifier_manager, &unit_type_manager, &building_type_manager, &crime_manager]( std::string_view identifier, ast::NodeCPtr value ) -> bool { + using enum scope_type_t; + // TODO - use the same variable for all modifiers rather than combining them at the end? ModifierValue loose_modifiers; ModifierValue modifiers; @@ -74,8 +76,8 @@ bool InventionManager::load_inventions_file( bool unlock_gas_defence = false; bool news = true; //defaults to true! - ConditionScript limit { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; - ConditionalWeight chance { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionScript limit { COUNTRY, COUNTRY, NO_SCOPE }; + ConditionalWeight chance { COUNTRY, COUNTRY, NO_SCOPE }; bool ret = NodeTools::expect_dictionary_keys_and_default( modifier_manager.expect_base_country_modifier(loose_modifiers), diff --git a/src/openvic-simulation/research/Technology.cpp b/src/openvic-simulation/research/Technology.cpp index 9a1cf27..f2df94b 100644 --- a/src/openvic-simulation/research/Technology.cpp +++ b/src/openvic-simulation/research/Technology.cpp @@ -168,6 +168,8 @@ bool TechnologyManager::load_technologies_file( return expect_dictionary_reserve_length(technologies, [this, &modifier_manager, &unit_type_manager, &building_type_manager]( std::string_view tech_key, ast::NodeCPtr tech_value ) -> bool { + using enum scope_type_t; + ModifierValue modifiers; TechnologyArea const* area = nullptr; Date::year_t year = 0; @@ -176,7 +178,7 @@ bool TechnologyManager::load_technologies_file( std::optional<CountryInstance::unit_variant_t> unit_variant; Technology::unit_set_t activated_units; Technology::building_set_t activated_buildings; - ConditionalWeight ai_chance { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE }; + ConditionalWeight ai_chance { COUNTRY, COUNTRY, NO_SCOPE }; bool ret = NodeTools::expect_dictionary_keys_and_default( modifier_manager.expect_technology_modifier(modifiers), diff --git a/src/openvic-simulation/scripts/Condition.cpp b/src/openvic-simulation/scripts/Condition.cpp index fd1f4fa..bb8b662 100644 --- a/src/openvic-simulation/scripts/Condition.cpp +++ b/src/openvic-simulation/scripts/Condition.cpp @@ -7,12 +7,12 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; using enum value_type_t; -using enum scope_t; +using enum scope_type_t; using enum identifier_type_t; Condition::Condition( - std::string_view new_identifier, value_type_t new_value_type, scope_t new_scope, - scope_t new_scope_change, identifier_type_t new_key_identifier_type, + std::string_view new_identifier, value_type_t new_value_type, scope_type_t new_scope, + scope_type_t new_scope_change, identifier_type_t new_key_identifier_type, identifier_type_t new_value_identifier_type ) : HasIdentifier { new_identifier }, value_type { new_value_type }, scope { new_scope }, scope_change { new_scope_change }, key_identifier_type { new_key_identifier_type }, @@ -26,7 +26,7 @@ ConditionNode::ConditionNode( condition_key_item { new_condition_key_item }, condition_value_item { new_condition_key_item } {} bool ConditionManager::add_condition( - std::string_view identifier, value_type_t value_type, scope_t scope, scope_t scope_change, + std::string_view identifier, value_type_t value_type, scope_type_t scope, scope_type_t scope_change, identifier_type_t key_identifier_type, identifier_type_t value_identifier_type ) { if (identifier.empty()) { @@ -337,8 +337,8 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana const auto import_identifiers = [this, &ret]( std::vector<std::string_view> const& identifiers, value_type_t value_type, - scope_t scope, - scope_t scope_change = NO_SCOPE, + scope_type_t scope, + scope_type_t scope_change = NO_SCOPE, identifier_type_t key_identifier_type = NO_IDENTIFIER, identifier_type_t value_identifier_type = NO_IDENTIFIER ) -> void { @@ -523,10 +523,10 @@ callback_t<std::string_view> ConditionManager::expect_parse_identifier( } node_callback_t ConditionManager::expect_condition_node( - DefinitionManager const& definition_manager, Condition const& condition, scope_t this_scope, - scope_t from_scope, scope_t cur_scope, callback_t<ConditionNode&&> callback + DefinitionManager const& definition_manager, Condition const& condition, scope_type_t current_scope, + scope_type_t this_scope, scope_type_t from_scope, callback_t<ConditionNode&&> callback ) const { - return [this, &definition_manager, &condition, callback, this_scope, from_scope, cur_scope]( + return [this, &definition_manager, &condition, callback, current_scope, this_scope, from_scope]( ast::NodeCPtr node ) -> bool { bool ret = false; @@ -534,8 +534,8 @@ node_callback_t ConditionManager::expect_condition_node( const std::string_view identifier = condition.get_identifier(); const value_type_t value_type = condition.get_value_type(); - const scope_t scope = condition.get_scope(); - const scope_t scope_change = condition.get_scope_change(); + const scope_type_t scope = condition.get_scope(); + const scope_type_t scope_change = condition.get_scope_change(); const identifier_type_t key_identifier_type = condition.get_key_identifier_type(); const identifier_type_t value_identifier_type = condition.get_value_identifier_type(); @@ -647,23 +647,24 @@ node_callback_t ConditionManager::expect_condition_node( if (!ret && share_value_type(value_type, GROUP)) { ConditionNode::condition_list_t node_list; ret |= expect_condition_node_list( - definition_manager, this_scope, from_scope, - scope_change == NO_SCOPE ? cur_scope : scope_change, - false, + definition_manager, + scope_change == NO_SCOPE ? current_scope : scope_change, + this_scope, + from_scope, vector_callback(node_list) )(node); value = std::move(node_list); } // scope validation - scope_t effective_current_scope = cur_scope; - if (share_scope(effective_current_scope, THIS)) { + scope_type_t effective_current_scope = current_scope; + if (share_scope_type(effective_current_scope, THIS)) { effective_current_scope = this_scope; - } else if (share_scope(effective_current_scope, FROM)) { + } else if (share_scope_type(effective_current_scope, FROM)) { effective_current_scope = from_scope; } - if (!share_scope(scope, effective_current_scope) && effective_current_scope > scope) { + if (!share_scope_type(scope, effective_current_scope) && effective_current_scope > scope) { Logger::warning( "Condition or scope ", identifier, " was found in wrong scope ", effective_current_scope, ", expected ", scope, "!" @@ -706,15 +707,15 @@ static bool top_scope_fallback(std::string_view id, ast::NodeCPtr node) { }; node_callback_t ConditionManager::expect_condition_node_list( - DefinitionManager const& definition_manager, scope_t this_scope, scope_t from_scope, - scope_t cur_scope, bool top_scope, callback_t<ConditionNode&&> callback + DefinitionManager const& definition_manager, scope_type_t current_scope, scope_type_t this_scope, scope_type_t from_scope, + callback_t<ConditionNode&&> callback, bool top_scope ) const { - return [this, &definition_manager, callback, this_scope, from_scope, cur_scope, top_scope](ast::NodeCPtr node) -> bool { + return [this, &definition_manager, callback, current_scope, this_scope, from_scope, top_scope](ast::NodeCPtr node) -> bool { const auto expect_node = [ - this, &definition_manager, callback, this_scope, from_scope, cur_scope + this, &definition_manager, callback, current_scope, this_scope, from_scope ](Condition const& condition, ast::NodeCPtr node) -> bool { return expect_condition_node( - definition_manager, condition, this_scope, from_scope, cur_scope, callback + definition_manager, condition, current_scope, this_scope, from_scope, callback )(node); }; @@ -729,19 +730,19 @@ node_callback_t ConditionManager::expect_condition_node_list( } node_callback_t ConditionManager::expect_condition_script( - DefinitionManager const& definition_manager, scope_t initial_scope, scope_t this_scope, - scope_t from_scope, callback_t<ConditionNode&&> callback + DefinitionManager const& definition_manager, scope_type_t initial_scope, scope_type_t this_scope, + scope_type_t from_scope, callback_t<ConditionNode&&> callback ) const { return [this, &definition_manager, initial_scope, this_scope, from_scope, callback](ast::NodeCPtr node) -> bool { ConditionNode::condition_list_t conds; bool ret = expect_condition_node_list( definition_manager, + initial_scope, this_scope, from_scope, - initial_scope, - true, - NodeTools::vector_callback(conds) + NodeTools::vector_callback(conds), + true )(node); ret &= callback({ root_condition, std::move(conds), true }); diff --git a/src/openvic-simulation/scripts/Condition.hpp b/src/openvic-simulation/scripts/Condition.hpp index 8d4d246..1f4929a 100644 --- a/src/openvic-simulation/scripts/Condition.hpp +++ b/src/openvic-simulation/scripts/Condition.hpp @@ -27,7 +27,7 @@ namespace OpenVic { // Order matters in this enum, for the fallback system to work // smaller entities must have smaller integers associated! - enum class scope_t : uint8_t { //TODO: maybe distinguish TRANSPARENT from NO_SCOPE + enum class scope_type_t : uint8_t { //TODO: maybe distinguish TRANSPARENT from NO_SCOPE NO_SCOPE = 0, POP = 1 << 0, PROVINCE = 1 << 1, @@ -74,15 +74,15 @@ namespace OpenVic { /* Allows enum types to be used with bitwise operators. */ template<> struct enable_bitfield<value_type_t> : std::true_type {}; - template<> struct enable_bitfield<scope_t> : std::true_type {}; + template<> struct enable_bitfield<scope_type_t> : std::true_type {}; template<> struct enable_bitfield<identifier_type_t> : std::true_type {}; /* Returns true if the values have any bit in common. */ inline constexpr bool share_value_type(value_type_t lhs, value_type_t rhs) { return (lhs & rhs) != value_type_t::NO_TYPE; } - inline constexpr bool share_scope(scope_t lhs, scope_t rhs) { - return (lhs & rhs) != scope_t::NO_SCOPE; + inline constexpr bool share_scope_type(scope_type_t lhs, scope_type_t rhs) { + return (lhs & rhs) != scope_type_t::NO_SCOPE; } inline constexpr bool share_identifier_type(identifier_type_t lhs, identifier_type_t rhs) { return (lhs & rhs) != identifier_type_t::NO_IDENTIFIER; @@ -122,10 +122,10 @@ namespace OpenVic { } #undef BUILD_STRING -#define BUILD_STRING(entry) _BUILD_STRING(entry, share_scope) +#define BUILD_STRING(entry) _BUILD_STRING(entry, share_scope_type) - inline std::ostream& operator<<(std::ostream& stream, scope_t value) { - using enum scope_t; + inline std::ostream& operator<<(std::ostream& stream, scope_type_t value) { + using enum scope_type_t; if (value == NO_SCOPE) { return stream << "[NO_SCOPE]"; } @@ -198,14 +198,14 @@ namespace OpenVic { private: const value_type_t PROPERTY(value_type); - const scope_t PROPERTY(scope); - const scope_t PROPERTY(scope_change); + const scope_type_t PROPERTY(scope); + const scope_type_t PROPERTY(scope_change); const identifier_type_t PROPERTY(key_identifier_type); const identifier_type_t PROPERTY(value_identifier_type); Condition( - std::string_view new_identifier, value_type_t new_value_type, scope_t new_scope, - scope_t new_scope_change, identifier_type_t new_key_identifier_type, + std::string_view new_identifier, value_type_t new_value_type, scope_type_t new_scope, + scope_type_t new_scope_change, identifier_type_t new_key_identifier_type, identifier_type_t new_value_identifier_type ); @@ -249,8 +249,8 @@ namespace OpenVic { Condition const* root_condition = nullptr; bool add_condition( - std::string_view identifier, value_type_t value_type, scope_t scope, - scope_t scope_change = scope_t::NO_SCOPE, + std::string_view identifier, value_type_t value_type, scope_type_t scope, + scope_type_t scope_change = scope_type_t::NO_SCOPE, identifier_type_t key_identifier_type = identifier_type_t::NO_IDENTIFIER, identifier_type_t value_identifier_type = identifier_type_t::NO_IDENTIFIER ); @@ -261,21 +261,21 @@ namespace OpenVic { ) const; NodeTools::node_callback_t expect_condition_node( - DefinitionManager const& definition_manager, Condition const& condition, scope_t this_scope, - scope_t from_scope, scope_t cur_scope, NodeTools::callback_t<ConditionNode&&> callback + DefinitionManager const& definition_manager, Condition const& condition, scope_type_t current_scope, + scope_type_t this_scope, scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback ) const; NodeTools::node_callback_t expect_condition_node_list( - DefinitionManager const& definition_manager, scope_t this_scope, scope_t from_scope, - scope_t cur_scope, bool top_scope, NodeTools::callback_t<ConditionNode&&> callback + DefinitionManager const& definition_manager, scope_type_t current_scope, scope_type_t this_scope, + scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback, bool top_scope = false ) const; public: bool setup_conditions(DefinitionManager const& definition_manager); NodeTools::node_callback_t expect_condition_script( - DefinitionManager const& definition_manager, scope_t initial_scope, scope_t this_scope, scope_t from_scope, - NodeTools::callback_t<ConditionNode&&> callback + DefinitionManager const& definition_manager, scope_type_t initial_scope, scope_type_t this_scope, + scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback ) const; }; } diff --git a/src/openvic-simulation/scripts/ConditionScript.cpp b/src/openvic-simulation/scripts/ConditionScript.cpp index bee4d07..c556bd2 100644 --- a/src/openvic-simulation/scripts/ConditionScript.cpp +++ b/src/openvic-simulation/scripts/ConditionScript.cpp @@ -6,7 +6,7 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; ConditionScript::ConditionScript( - scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope + scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope ) : initial_scope { new_initial_scope }, this_scope { new_this_scope }, from_scope { new_from_scope } {} bool ConditionScript::_parse_script(ast::NodeCPtr root, DefinitionManager const& definition_manager) { diff --git a/src/openvic-simulation/scripts/ConditionScript.hpp b/src/openvic-simulation/scripts/ConditionScript.hpp index e6ed255..aa386e8 100644 --- a/src/openvic-simulation/scripts/ConditionScript.hpp +++ b/src/openvic-simulation/scripts/ConditionScript.hpp @@ -10,14 +10,14 @@ namespace OpenVic { private: ConditionNode PROPERTY_REF(condition_root); - scope_t PROPERTY(initial_scope); - scope_t PROPERTY(this_scope); - scope_t PROPERTY(from_scope); + scope_type_t PROPERTY(initial_scope); + scope_type_t PROPERTY(this_scope); + scope_type_t PROPERTY(from_scope); protected: bool _parse_script(ast::NodeCPtr root, DefinitionManager const& definition_manager) override; public: - ConditionScript(scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope); + ConditionScript(scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope); }; } diff --git a/src/openvic-simulation/scripts/ConditionalWeight.cpp b/src/openvic-simulation/scripts/ConditionalWeight.cpp index 7c3e0a0..1bb83d0 100644 --- a/src/openvic-simulation/scripts/ConditionalWeight.cpp +++ b/src/openvic-simulation/scripts/ConditionalWeight.cpp @@ -3,12 +3,12 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; -ConditionalWeight::ConditionalWeight(scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope) +ConditionalWeight::ConditionalWeight(scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope) : initial_scope { new_initial_scope }, this_scope { new_this_scope }, from_scope { new_from_scope } {} template<typename T> static NodeCallback auto expect_modifier( - std::vector<T>& items, scope_t initial_scope, scope_t this_scope, scope_t from_scope + std::vector<T>& items, scope_type_t initial_scope, scope_type_t this_scope, scope_type_t from_scope ) { return [&items, initial_scope, this_scope, from_scope](ast::NodeCPtr node) -> bool { fixed_point_t weight = 0; @@ -26,23 +26,86 @@ static NodeCallback auto expect_modifier( } node_callback_t ConditionalWeight::expect_conditional_weight(base_key_t base_key) { - return expect_dictionary_keys( - // TODO - add days and years as options with a shared expected count of ONE_EXACTLY - base_key_to_string(base_key), ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(base)), - "days", ZERO_OR_ONE, success_callback, - "years", ZERO_OR_ONE, success_callback, + key_map_t key_map; + bool successfully_set_up_base_keys = true; + + switch (base_key) { + case BASE: + { + successfully_set_up_base_keys &= add_key_map_entry( + key_map, + "base", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(base)) + ); + + break; + } + case FACTOR: + { + successfully_set_up_base_keys &= add_key_map_entry( + key_map, + "factor", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(base)) + ); + + break; + } + case TIME: + { + const auto time_callback = [this](std::string_view key, Timespan (*to_timespan)(Timespan::day_t)) -> auto { + return [this, key, to_timespan](uint32_t value) -> bool { + if (base == fixed_point_t::_0()) { + base = fixed_point_t::parse((*to_timespan)(value).to_int()); + return true; + } else { + Logger::error( + "ConditionalWeight cannot have multiple base values - trying to set base to ", value, " ", key, + " when it already has a value equivalent to ", base, " days!" + ); + return false; + } + }; + }; + + successfully_set_up_base_keys &= add_key_map_entries( + key_map, + "days", ZERO_OR_ONE, expect_uint<uint32_t>(time_callback("days", Timespan::from_days)), + "months", ZERO_OR_ONE, expect_uint<uint32_t>(time_callback("months", Timespan::from_months)), + "years", ZERO_OR_ONE, expect_uint<uint32_t>(time_callback("years", Timespan::from_years)) + ); + + break; + } + default: + { + successfully_set_up_base_keys = false; + } + } + + if (!successfully_set_up_base_keys) { + return [base_key](ast::NodeCPtr node) -> bool { + Logger::error( + "Failed to set up base keys for ConditionalWeight with base value: ", static_cast<uint32_t>(base_key) + ); + return false; + }; + } + + return expect_dictionary_key_map( + std::move(key_map), "modifier", ZERO_OR_MORE, expect_modifier(condition_weight_items, initial_scope, this_scope, from_scope), "group", ZERO_OR_MORE, [this](ast::NodeCPtr node) -> bool { condition_weight_group_t items; + const bool ret = expect_dictionary_keys( "modifier", ONE_OR_MORE, expect_modifier(items, initial_scope, this_scope, from_scope) )(node); + if (!items.empty()) { condition_weight_items.emplace_back(std::move(items)); return ret; + } else { + Logger::error("ConditionalWeight group must have at least one modifier!"); + return false; } - Logger::error("ConditionalWeight group must have at least one modifier!"); - return false; } ); } diff --git a/src/openvic-simulation/scripts/ConditionalWeight.hpp b/src/openvic-simulation/scripts/ConditionalWeight.hpp index c99d6b0..fcab0a6 100644 --- a/src/openvic-simulation/scripts/ConditionalWeight.hpp +++ b/src/openvic-simulation/scripts/ConditionalWeight.hpp @@ -14,32 +14,23 @@ namespace OpenVic { using condition_weight_item_t = std::variant<condition_weight_t, condition_weight_group_t>; enum class base_key_t : uint8_t { - BASE, FACTOR, MONTHS + BASE, FACTOR, TIME }; using enum base_key_t; private: fixed_point_t PROPERTY(base); std::vector<condition_weight_item_t> PROPERTY(condition_weight_items); - scope_t PROPERTY(initial_scope); - scope_t PROPERTY(this_scope); - scope_t PROPERTY(from_scope); + scope_type_t PROPERTY(initial_scope); + scope_type_t PROPERTY(this_scope); + scope_type_t PROPERTY(from_scope); struct parse_scripts_visitor_t; public: - ConditionalWeight(scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope); + ConditionalWeight(scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope); ConditionalWeight(ConditionalWeight&&) = default; - static constexpr std::string_view base_key_to_string(base_key_t base_key) { - switch (base_key) { - case base_key_t::BASE: return "base"; - case base_key_t::FACTOR: return "factor"; - case base_key_t::MONTHS: return "months"; // TODO - add functionality for days or months or years - default: return "INVALID BASE KEY"; - } - } - NodeTools::node_callback_t expect_conditional_weight(base_key_t base_key); bool parse_scripts(DefinitionManager const& definition_manager); |