From 5f64f983d0cead266a28791be42162c443fd2a75 Mon Sep 17 00:00:00 2001 From: hop311 Date: Sun, 31 Dec 2023 00:47:31 +0000 Subject: Added framework for loading all Conditions and Effects --- .../economy/BuildingInstance.hpp | 2 +- src/openvic-simulation/economy/ProductionType.cpp | 102 ++++++++++++++------- src/openvic-simulation/economy/ProductionType.hpp | 44 +++++---- 3 files changed, 98 insertions(+), 50 deletions(-) (limited to 'src/openvic-simulation/economy') diff --git a/src/openvic-simulation/economy/BuildingInstance.hpp b/src/openvic-simulation/economy/BuildingInstance.hpp index e027a69..5d48321 100644 --- a/src/openvic-simulation/economy/BuildingInstance.hpp +++ b/src/openvic-simulation/economy/BuildingInstance.hpp @@ -14,7 +14,7 @@ namespace OpenVic { level_t PROPERTY_RW(level); ExpansionState PROPERTY(expansion_state); - Date PROPERTY(start_date) + Date PROPERTY(start_date); Date PROPERTY(end_date); float PROPERTY(expansion_progress); diff --git a/src/openvic-simulation/economy/ProductionType.cpp b/src/openvic-simulation/economy/ProductionType.cpp index f0ad6ea..4714ee5 100644 --- a/src/openvic-simulation/economy/ProductionType.cpp +++ b/src/openvic-simulation/economy/ProductionType.cpp @@ -6,15 +6,28 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; EmployedPop::EmployedPop( - PopType const* pop_type, bool artisan, effect_t effect, fixed_point_t effect_multiplier, fixed_point_t amount -) : pop_type { pop_type }, artisan { artisan }, effect { effect }, effect_multiplier { effect_multiplier }, - amount { amount } {} + PopType const* new_pop_type, bool new_artisan, effect_t new_effect, fixed_point_t new_effect_multiplier, + fixed_point_t new_amount +) : pop_type { new_pop_type }, artisan { new_artisan }, effect { new_effect }, effect_multiplier { new_effect_multiplier }, + amount { new_amount } {} ProductionType::ProductionType( - PRODUCTION_TYPE_ARGS -) : HasIdentifier { identifier }, owner { owner }, employees { employees }, type { type }, workforce { workforce }, - input_goods { std::move(input_goods) }, output_goods { output_goods }, value { value }, bonuses { std::move(bonuses) }, - efficiency { std::move(efficiency) }, coastal { coastal }, farm { farm }, mine { mine } {} + std::string_view new_identifier, EmployedPop new_owner, std::vector new_employees, type_t new_type, + Pop::pop_size_t new_workforce, Good::good_map_t&& new_input_goods, Good const* new_output_goods, + fixed_point_t new_value, std::vector&& new_bonuses, Good::good_map_t&& new_efficiency, bool new_coastal, + bool new_farm, bool new_mine +) : HasIdentifier { new_identifier }, owner { new_owner }, employees { new_employees }, type { new_type }, + workforce { new_workforce }, input_goods { std::move(new_input_goods) }, output_goods { new_output_goods }, + value { new_value }, bonuses { std::move(new_bonuses) }, efficiency { std::move(new_efficiency) }, + coastal { new_coastal }, farm { new_farm }, mine { new_mine } {} + +bool ProductionType::parse_scripts(GameManager const& game_manager) { + bool ret = true; + for (auto& [bonus_script, bonus_value] : bonuses) { + ret &= bonus_script.parse_script(false, game_manager); + } + return ret; +} ProductionTypeManager::ProductionTypeManager() : rgo_owner_sprite { 0 } {} @@ -72,7 +85,11 @@ node_callback_t ProductionTypeManager::_expect_employed_pop_list( return false; \ } -bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS) { +bool ProductionTypeManager::add_production_type( + std::string_view identifier, EmployedPop owner, std::vector employees, ProductionType::type_t type, + Pop::pop_size_t workforce, Good::good_map_t&& input_goods, Good const* output_goods, fixed_point_t value, + std::vector&& bonuses, Good::good_map_t&& efficiency, bool coastal, bool farm, bool mine +) { if (identifier.empty()) { Logger::error("Invalid production type identifier - empty!"); return false; @@ -110,22 +127,6 @@ bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS) { return ret; } -#define PARSE_NODE \ - expect_dictionary_keys_and_default( \ - key_value_success_callback, \ - "owner", ZERO_OR_ONE, _expect_employed_pop(good_manager, pop_manager, move_variable_callback(owner)), \ - "employees", ZERO_OR_ONE, _expect_employed_pop_list(good_manager, pop_manager, move_variable_callback(employees)), \ - "type", ZERO_OR_ONE, expect_identifier(expect_mapped_string(type_map, assign_variable_callback(type))), \ - "workforce", ZERO_OR_ONE, expect_uint(assign_variable_callback(workforce)), \ - "input_goods", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(input_goods)), \ - "output_goods", ZERO_OR_ONE, good_manager.expect_good_identifier(assign_variable_callback_pointer(output_goods)), \ - "value", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(value)), \ - "efficiency", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(efficiency)), \ - "is_coastal", ZERO_OR_ONE, expect_bool(assign_variable_callback(coastal)), \ - "farm", ZERO_OR_ONE, expect_bool(assign_variable_callback(farm)), \ - "mine", ZERO_OR_ONE, expect_bool(assign_variable_callback(mine)) \ - ) - bool ProductionTypeManager::load_production_types_file( GoodManager const& good_manager, PopManager const& pop_manager, ast::NodeCPtr root ) { @@ -183,7 +184,7 @@ bool ProductionTypeManager::load_production_types_file( Pop::pop_size_t workforce = 0; // 0 is a meaningless value -> unset Good::good_map_t input_goods, efficiency; fixed_point_t value = 0; // 0 is a meaningless value -> unset - std::vector bonuses; + std::vector bonuses; bool coastal = false, farm = false, mine = false; bool ret = true; @@ -193,16 +194,47 @@ bool ProductionTypeManager::load_production_types_file( { "factory", FACTORY }, { "rgo", RGO }, { "artisan", ARTISAN } }; + const node_callback_t parse_node = expect_dictionary_keys( + "template", ZERO_OR_ONE, success_callback, + "bonus", ZERO_OR_MORE, [&bonuses](ast::NodeCPtr bonus_node) -> bool { + ConditionScript trigger; + fixed_point_t value {}; + const bool ret = expect_dictionary_keys( + "trigger", ONE_EXACTLY, trigger.expect_script(), + "value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(value)) + )(bonus_node); + bonuses.emplace_back(std::move(trigger), value); + return ret; + }, + "owner", ZERO_OR_ONE, _expect_employed_pop(good_manager, pop_manager, move_variable_callback(owner)), + "employees", ZERO_OR_ONE, _expect_employed_pop_list(good_manager, pop_manager, move_variable_callback(employees)), + "type", ZERO_OR_ONE, expect_identifier(expect_mapped_string(type_map, assign_variable_callback(type))), + "workforce", ZERO_OR_ONE, expect_uint(assign_variable_callback(workforce)), + "input_goods", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(input_goods)), + "output_goods", ZERO_OR_ONE, good_manager.expect_good_identifier(assign_variable_callback_pointer(output_goods)), + "value", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(value)), + "efficiency", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(efficiency)), + "is_coastal", ZERO_OR_ONE, expect_bool(assign_variable_callback(coastal)), + "farm", ZERO_OR_ONE, expect_bool(assign_variable_callback(farm)), + "mine", ZERO_OR_ONE, expect_bool(assign_variable_callback(mine)) + ); + // apply template first - if (template_target_map.contains(key)) { - std::string_view template_id = template_target_map[key]; - if (template_node_map.contains(template_id)) { - ast::NodeCPtr template_node = template_node_map[template_id]; - ret &= PARSE_NODE(template_node); + { + const typename decltype(template_target_map)::const_iterator target_it = template_target_map.find(key); + if (target_it != template_target_map.end()) { + const std::string_view template_id = target_it->second; + const typename decltype(template_node_map)::const_iterator node_it = template_node_map.find(template_id); + if (node_it != template_node_map.end()) { + ret &= parse_node(node_it->second); + } else { + Logger::error("Missing template ", template_id, " for production type ", key, "!"); + ret = false; + } } } - ret &= PARSE_NODE(node); + ret &= parse_node(node); ret &= add_production_type( key, owner, employees, type, workforce, std::move(input_goods), output_goods, value, std::move(bonuses), @@ -221,3 +253,11 @@ bool ProductionTypeManager::load_production_types_file( return ret; } + +bool ProductionTypeManager::parse_scripts(GameManager const& game_manager) { + bool ret = true; + for (ProductionType& production_type : production_types.get_items()) { + ret &= production_type.parse_scripts(game_manager); + } + return ret; +} diff --git a/src/openvic-simulation/economy/ProductionType.hpp b/src/openvic-simulation/economy/ProductionType.hpp index 4fdceda..5d51f60 100644 --- a/src/openvic-simulation/economy/ProductionType.hpp +++ b/src/openvic-simulation/economy/ProductionType.hpp @@ -2,14 +2,10 @@ #include "openvic-simulation/economy/Good.hpp" #include "openvic-simulation/pop/Pop.hpp" +#include "openvic-simulation/scripts/ConditionScript.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" -#define PRODUCTION_TYPE_ARGS \ - std::string_view identifier, EmployedPop owner, std::vector employees, ProductionType::type_t type, \ - Pop::pop_size_t workforce, Good::good_map_t&& input_goods, Good const* output_goods, fixed_point_t value, \ - std::vector&& bonuses, Good::good_map_t&& efficiency, bool coastal, bool farm, bool mine - namespace OpenVic { struct ProductionTypeManager; @@ -26,40 +22,46 @@ namespace OpenVic { fixed_point_t PROPERTY(amount); EmployedPop( - PopType const* pop_type, bool artisan, effect_t effect, fixed_point_t effect_multiplier, fixed_point_t amount + PopType const* new_pop_type, bool new_artisan, effect_t new_effect, fixed_point_t new_effect_multiplier, + fixed_point_t new_amount ); public: EmployedPop() = default; }; - struct Bonus { - // TODO: trigger condition(s) - const fixed_point_t value; - }; - struct ProductionType : HasIdentifier { friend struct ProductionTypeManager; + enum struct type_t { FACTORY, RGO, ARTISAN }; + + using bonus_t = std::pair; + private: const EmployedPop PROPERTY(owner); - const std::vector PROPERTY(employees); - const enum struct type_t { FACTORY, RGO, ARTISAN } PROPERTY(type); + std::vector PROPERTY(employees); + const type_t PROPERTY(type); const Pop::pop_size_t workforce; - const Good::good_map_t PROPERTY(input_goods); + Good::good_map_t PROPERTY(input_goods); Good const* PROPERTY(output_goods); const fixed_point_t PROPERTY(value); - const std::vector PROPERTY(bonuses); + std::vector PROPERTY(bonuses); - const Good::good_map_t PROPERTY(efficiency); + Good::good_map_t PROPERTY(efficiency); const bool PROPERTY_CUSTOM_PREFIX(coastal, is); // is_coastal const bool PROPERTY_CUSTOM_PREFIX(farm, is); const bool PROPERTY_CUSTOM_PREFIX(mine, is); - ProductionType(PRODUCTION_TYPE_ARGS); + ProductionType( + std::string_view new_identifier, EmployedPop new_owner, std::vector new_employees, type_t new_type, + Pop::pop_size_t new_workforce, Good::good_map_t&& new_input_goods, Good const* new_output_goods, + fixed_point_t new_value, std::vector&& new_bonuses, Good::good_map_t&& new_efficiency, bool new_coastal, + bool new_farm, bool new_mine + ); + bool parse_scripts(GameManager const& game_manager); public: ProductionType(ProductionType&&) = default; }; @@ -80,8 +82,14 @@ namespace OpenVic { public: ProductionTypeManager(); - bool add_production_type(PRODUCTION_TYPE_ARGS); + bool add_production_type( + std::string_view identifier, EmployedPop owner, std::vector employees, ProductionType::type_t type, + Pop::pop_size_t workforce, Good::good_map_t&& input_goods, Good const* output_goods, fixed_point_t value, + std::vector&& bonuses, Good::good_map_t&& efficiency, bool coastal, bool farm, bool mine + ); bool load_production_types_file(GoodManager const& good_manager, PopManager const& pop_manager, ast::NodeCPtr root); + + bool parse_scripts(GameManager const& game_manager); }; } -- cgit v1.2.3-56-ga3b1