diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 4 | ||||
-rw-r--r-- | src/openvic-simulation/military/LeaderTrait.cpp | 9 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/Modifier.hpp | 2 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierEffect.cpp | 15 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierEffect.hpp | 5 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierEffectMapping.cpp | 80 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierEffectMapping.hpp | 45 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierManager.cpp | 194 | ||||
-rw-r--r-- | src/openvic-simulation/modifier/ModifierManager.hpp | 32 | ||||
-rw-r--r-- | src/openvic-simulation/research/Invention.cpp | 11 |
10 files changed, 286 insertions, 111 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 99a8d68..0c029f7 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -898,6 +898,10 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) { Logger::error("Failed to load interface files!"); ret = false; } + if (!definition_manager.get_modifier_manager().setup_modifier_effect_mappings()) { + Logger::error("Failed to set up modifier effect mappings!"); + ret = false; + } if (!definition_manager.get_modifier_manager().setup_modifier_effects()) { Logger::error("Failed to set up modifier effects!"); ret = false; diff --git a/src/openvic-simulation/military/LeaderTrait.cpp b/src/openvic-simulation/military/LeaderTrait.cpp index 7835636..1694828 100644 --- a/src/openvic-simulation/military/LeaderTrait.cpp +++ b/src/openvic-simulation/military/LeaderTrait.cpp @@ -34,15 +34,10 @@ bool LeaderTraitManager::load_leader_traits_file(ModifierManager const& modifier [this, &modifier_manager, type](std::string_view trait_identifier, ast::NodeCPtr value) -> bool { using enum Modifier::modifier_type_t; - static const string_set_t allowed_modifiers = { - "attack", "defence leader", "morale", "organisation", "reconnaissance", - "speed", "attrition", "experience", "reliability" - }; - ModifierValue modifiers; - bool ret = modifier_manager.expect_whitelisted_modifier_value( - move_variable_callback(modifiers), LEADER, allowed_modifiers + bool ret = modifier_manager.expect_modifier_value( + move_variable_callback(modifiers), LEADER )(value); ret &= add_leader_trait(trait_identifier, type, std::move(modifiers)); diff --git a/src/openvic-simulation/modifier/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp index 1277c76..ebd54a7 100644 --- a/src/openvic-simulation/modifier/Modifier.hpp +++ b/src/openvic-simulation/modifier/Modifier.hpp @@ -16,7 +16,7 @@ namespace OpenVic { enum struct modifier_type_t : uint8_t { EVENT, STATIC, TRIGGERED, CRIME, TERRAIN, CLIMATE, CONTINENT, BUILDING, LEADER, UNIT_TERRAIN, - NATIONAL_VALUE, NATIONAL_FOCUS, ISSUE, REFORM, TECHNOLOGY, INVENTION, TECH_SCHOOL + NATIONAL_VALUE, NATIONAL_FOCUS, ISSUE, REFORM, TECHNOLOGY, INVENTION, INVENTION_EFFECT, TECH_SCHOOL }; static std::string_view modifier_type_to_string(modifier_type_t type); diff --git a/src/openvic-simulation/modifier/ModifierEffect.cpp b/src/openvic-simulation/modifier/ModifierEffect.cpp index 2ffb9a5..37822c3 100644 --- a/src/openvic-simulation/modifier/ModifierEffect.cpp +++ b/src/openvic-simulation/modifier/ModifierEffect.cpp @@ -41,9 +41,18 @@ std::string ModifierEffect::make_default_modifier_effect_localisation_key(std::s } ModifierEffect::ModifierEffect( - std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t new_targets, + std::string_view new_identifier, + bool new_positive_good, + format_t new_format, + target_t new_targets, + std::string_view new_mapping_key, std::string_view new_localisation_key -) : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format }, targets { new_targets }, +) : HasIdentifier { new_identifier }, + positive_good { new_positive_good }, + format { new_format }, + targets { new_targets }, + mapping_key { new_mapping_key.empty() ? new_identifier : new_mapping_key }, localisation_key { - new_localisation_key.empty() ? make_default_modifier_effect_localisation_key(new_identifier) : new_localisation_key + // mapping_key will have been initialised by this point as it's before localisation_key in the struct's declaration + new_localisation_key.empty() ? make_default_modifier_effect_localisation_key(mapping_key) : new_localisation_key } {} diff --git a/src/openvic-simulation/modifier/ModifierEffect.hpp b/src/openvic-simulation/modifier/ModifierEffect.hpp index ff82acf..1ba9f63 100644 --- a/src/openvic-simulation/modifier/ModifierEffect.hpp +++ b/src/openvic-simulation/modifier/ModifierEffect.hpp @@ -40,13 +40,12 @@ namespace OpenVic { const bool PROPERTY_CUSTOM_PREFIX(positive_good, is); const format_t PROPERTY(format); const target_t PROPERTY(targets); + std::string PROPERTY(mapping_key); // The identifier in the text defines that maps to this effect std::string PROPERTY(localisation_key); - // TODO - format/precision, e.g. 80% vs 0.8 vs 0.800, 2 vs 2.0 vs 200% - ModifierEffect( std::string_view new_identifier, bool new_positive_good, format_t new_format, target_t mew_targets, - std::string_view new_localisation_key + std::string_view new_mapping_key, std::string_view new_localisation_key ); public: diff --git a/src/openvic-simulation/modifier/ModifierEffectMapping.cpp b/src/openvic-simulation/modifier/ModifierEffectMapping.cpp new file mode 100644 index 0000000..388c47f --- /dev/null +++ b/src/openvic-simulation/modifier/ModifierEffectMapping.cpp @@ -0,0 +1,80 @@ +#include "ModifierEffectMapping.hpp" + +#include "openvic-simulation/modifier/ModifierEffect.hpp" +#include "openvic-simulation/utility/Logger.hpp" + +using namespace OpenVic; + +std::string_view ModifierEffectMapping::modifier_effect_mapping_type_to_string(modifier_effect_mapping_type_t type) { + using enum ModifierEffectMapping::modifier_effect_mapping_type_t; + + switch (type) { +#define _CASE(X) case X: return #X; + _CASE(LEADER_MAPPING) + _CASE(TECHNOLOGY_MAPPING) + _CASE(UNIT_TERRAIN_MAPPING) + _CASE(BASE_COUNTRY_MAPPING) + _CASE(BASE_PROVINCE_MAPPING) + _CASE(EVENT_MAPPING) + _CASE(TERRAIN_MAPPING) +#undef _CASE + default: return "INVALID MODIFIER TYPE"; + } +} + +ModifierEffectMapping::ModifierEffectMapping( + modifier_effect_mapping_type_t new_type, ModifierEffectMapping const* new_fallback_mapping +) : type { new_type }, locked { false }, fallback_mapping { new_fallback_mapping }, effect_map {} {} + +std::string_view ModifierEffectMapping::get_type_name() const { + return modifier_effect_mapping_type_to_string(type); +} + +bool ModifierEffectMapping::add_modifier_effect(ModifierEffect const& effect) { + if (locked) { + Logger::error("Cannot add modifier effect to modifier effect mapping \"", get_type_name(), "\" - locked!"); + return false; + } + + const auto [effect_it, effect_was_added] = effect_map.emplace(effect.get_mapping_key(), &effect); + + if (!effect_was_added) { + Logger::error( + "Cannot add modifier effect \"", effect.get_identifier(), "\" to modifier effect mapping \"", get_type_name(), + "\" - the key \"", effect.get_mapping_key(), "\" is already mapped to modifier effect \"", + effect_it->second->get_identifier(), "\"!" + ); + } + + return effect_was_added; +} + +void ModifierEffectMapping::lock() { + if (locked) { + Logger::error("Cannot lock modifier effect mapping \"", get_type_name(), "\" - already locked!"); + } else { + locked = true; + } +} + +ModifierEffect const* ModifierEffectMapping::lookup_modifier_effect(std::string_view identifier) const { + if (!locked) { + Logger::error( + "Cannot lookup modifier effect \"", identifier, "\" in modifier effect mapping \"", get_type_name(), + "\" - not locked!" + ); + return nullptr; + } + + const decltype(effect_map)::const_iterator it = effect_map.find(identifier); + + if (it != effect_map.end()) { + return it->second; + } + + if (fallback_mapping != nullptr) { + return fallback_mapping->lookup_modifier_effect(identifier); + } + + return nullptr; +} diff --git a/src/openvic-simulation/modifier/ModifierEffectMapping.hpp b/src/openvic-simulation/modifier/ModifierEffectMapping.hpp new file mode 100644 index 0000000..1042bb2 --- /dev/null +++ b/src/openvic-simulation/modifier/ModifierEffectMapping.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include <string_view> + +#include "openvic-simulation/types/OrderedContainers.hpp" +#include "openvic-simulation/utility/Getters.hpp" + +namespace OpenVic { + struct ModifierManager; + struct ModifierEffect; + + struct ModifierEffectMapping { + enum struct modifier_effect_mapping_type_t : uint8_t { + LEADER_MAPPING, // Isolated + TECHNOLOGY_MAPPING, // Isolated + UNIT_TERRAIN_MAPPING, // Isolated + BASE_COUNTRY_MAPPING, // Fallen back to by BASE_PROVINCE_MAPPING, and in turn by EVENT_MAPPING and TERRAIN_MAPPING + BASE_PROVINCE_MAPPING, // Falls back to BASE_COUNTRY_MAPPING, fallen back to by EVENT_MAPPING and TERRAIN_MAPPING + EVENT_MAPPING, // Falls back to BASE_PROVINCE_MAPPING + TERRAIN_MAPPING, // Falls back to BASE_PROVINCE_MAPPING + MODIFIER_EFFECT_MAPPING_COUNT + }; + + static std::string_view modifier_effect_mapping_type_to_string(modifier_effect_mapping_type_t type); + + private: + const modifier_effect_mapping_type_t PROPERTY(type); + bool PROPERTY_CUSTOM_PREFIX(locked, is); + ModifierEffectMapping const* const PROPERTY(fallback_mapping); + string_map_t<ModifierEffect const*> PROPERTY(effect_map); + + public: + ModifierEffectMapping( + modifier_effect_mapping_type_t new_type, ModifierEffectMapping const* new_fallback_mapping = nullptr + ); + ModifierEffectMapping(ModifierEffectMapping&&) = default; + + std::string_view get_type_name() const; + + bool add_modifier_effect(ModifierEffect const& effect); + void lock(); + + ModifierEffect const* lookup_modifier_effect(std::string_view identifier) const; + }; +} diff --git a/src/openvic-simulation/modifier/ModifierManager.cpp b/src/openvic-simulation/modifier/ModifierManager.cpp index daf186f..a426f23 100644 --- a/src/openvic-simulation/modifier/ModifierManager.cpp +++ b/src/openvic-simulation/modifier/ModifierManager.cpp @@ -5,7 +5,7 @@ using namespace OpenVic::NodeTools; bool ModifierManager::add_modifier_effect( ModifierEffect const*& effect_cache, std::string_view identifier, bool positive_good, ModifierEffect::format_t format, - ModifierEffect::target_t targets, std::string_view localisation_key + ModifierEffect::target_t targets, std::string_view localisation_key, std::string_view mapping_key ) { using enum ModifierEffect::target_t; @@ -35,7 +35,7 @@ bool ModifierManager::add_modifier_effect( return false; } - const bool ret = modifier_effects.add_item({ std::move(identifier), positive_good, format, targets, localisation_key }); + const bool ret = modifier_effects.add_item({ identifier, positive_good, format, targets, mapping_key, localisation_key }); if (ret) { effect_cache = &modifier_effects.get_items().back(); @@ -44,6 +44,53 @@ bool ModifierManager::add_modifier_effect( return ret; } +bool ModifierManager::setup_modifier_effect_mappings() { + if (!modifier_effect_mappings.empty()) { + Logger::error("Modifier effect mappings have already been initialised!"); + return false; + } + + using enum ModifierEffectMapping::modifier_effect_mapping_type_t; + + modifier_effect_mappings.reserve(static_cast<size_t>(MODIFIER_EFFECT_MAPPING_COUNT)); + + bool ret = true; + + const auto add_modifier_effect_mapping = [this, &ret]( + ModifierEffectMapping::modifier_effect_mapping_type_t type, + // MODIFIER_EFFECT_MAPPING_COUNT is used as an invalid/unset value here + ModifierEffectMapping::modifier_effect_mapping_type_t fallback_type = MODIFIER_EFFECT_MAPPING_COUNT + ) -> void { + if (static_cast<size_t>(type) != modifier_effect_mappings.size()) { + Logger::error( + "Trying to place modifier effect mapping type \"", + ModifierEffectMapping::modifier_effect_mapping_type_to_string(type), "\" with index ", + static_cast<size_t>(type), " in position ", modifier_effect_mappings.size(), "!" + ); + ret = false; + return; + } + + // The fallback pointer will be valid even if its map hasn't yet been initialised as we have reserved the space + // (further emplacements won't invalidate the pointer for the same reason). + + modifier_effect_mappings.emplace_back( + type, fallback_type < MODIFIER_EFFECT_MAPPING_COUNT ? + &modifier_effect_mappings[static_cast<size_t>(fallback_type)] : nullptr + ); + }; + + add_modifier_effect_mapping(LEADER_MAPPING); + add_modifier_effect_mapping(TECHNOLOGY_MAPPING); + add_modifier_effect_mapping(UNIT_TERRAIN_MAPPING); + add_modifier_effect_mapping(BASE_COUNTRY_MAPPING); + add_modifier_effect_mapping(BASE_PROVINCE_MAPPING, BASE_COUNTRY_MAPPING); + add_modifier_effect_mapping(EVENT_MAPPING, BASE_PROVINCE_MAPPING); + add_modifier_effect_mapping(TERRAIN_MAPPING, BASE_PROVINCE_MAPPING); + + return ret; +} + bool ModifierManager::setup_modifier_effects() { // Variant Modifier Effeects static const std::string combat_width = "combat_width"; @@ -686,36 +733,59 @@ bool ModifierManager::parse_scripts(DefinitionManager const& definition_manager) return ret; } +static constexpr ModifierEffectMapping::modifier_effect_mapping_type_t modifier_type_to_modifier_effect_mapping_type( + Modifier::modifier_type_t type +) { + using enum Modifier::modifier_type_t; + using enum ModifierEffectMapping::modifier_effect_mapping_type_t; + + switch (type) { + case EVENT: return EVENT_MAPPING; + case STATIC: return BASE_COUNTRY_MAPPING; // shouldn't this be BASE_PROVINCE_MAPPING or EVENT_MAPPING? + case TRIGGERED: return BASE_COUNTRY_MAPPING; // maybe should be BASE_PROVINCE_MAPPING or EVENT_MAPPING, but less likely + case CRIME: return BASE_PROVINCE_MAPPING; + case TERRAIN: return TERRAIN_MAPPING; + case CLIMATE: return BASE_PROVINCE_MAPPING; + case CONTINENT: return BASE_PROVINCE_MAPPING; + case BUILDING: return BASE_PROVINCE_MAPPING; + case LEADER: return LEADER_MAPPING; + case UNIT_TERRAIN: return UNIT_TERRAIN_MAPPING; + case NATIONAL_VALUE: return BASE_COUNTRY_MAPPING; + case NATIONAL_FOCUS: return BASE_PROVINCE_MAPPING; + case ISSUE: return BASE_COUNTRY_MAPPING; + case REFORM: return BASE_COUNTRY_MAPPING; + case TECHNOLOGY: return TECHNOLOGY_MAPPING; + case INVENTION: return BASE_COUNTRY_MAPPING; + case INVENTION_EFFECT: return TECHNOLOGY_MAPPING; + case TECH_SCHOOL: return BASE_COUNTRY_MAPPING; + default: return MODIFIER_EFFECT_MAPPING_COUNT; // Used as an invalid valid + } +} + key_value_callback_t ModifierManager::_modifier_effect_callback( - ModifierValue& modifier, Modifier::modifier_type_t type, key_value_callback_t default_callback, - ModifierEffectValidator auto effect_validator + ModifierValue& modifier, Modifier::modifier_type_t type, key_value_callback_t default_callback ) const { - const auto add_modifier_cb = [this, &modifier, effect_validator]( + const auto add_modifier_cb = [this, &modifier]( ModifierEffect const* effect, ast::NodeCPtr value ) -> bool { - if (effect_validator(*effect)) { - static const case_insensitive_string_set_t no_effect_modifiers { - "boost_strongest_party", "poor_savings_modifier", "local_artisan_input", "local_artisan_throughput", - "local_artisan_output", "artisan_input", "artisan_throughput", "artisan_output", - "import_cost", "unciv_economic_modifier", "unciv_military_modifier" - }; - - if (no_effect_modifiers.contains(effect->get_identifier())) { - Logger::warning("This modifier does nothing: ", effect->get_identifier()); - } - - return expect_fixed_point(map_callback(modifier.values, effect))(value); - } else { - Logger::error("Failed to validate modifier effect: ", effect->get_identifier()); - return false; + static const case_insensitive_string_set_t no_effect_modifiers { + "boost_strongest_party", "poor_savings_modifier", "local_artisan_input", "local_artisan_throughput", + "local_artisan_output", "artisan_input", "artisan_throughput", "artisan_output", + "import_cost", "unciv_economic_modifier", "unciv_military_modifier" + }; + + if (no_effect_modifiers.contains(effect->get_identifier())) { + Logger::warning("This modifier does nothing: ", effect->get_identifier()); } + + return expect_fixed_point(map_callback(modifier.values, effect))(value); }; const auto add_flattened_modifier_cb = [this, add_modifier_cb]( - std::string_view prefix, std::string_view key, ast::NodeCPtr value + ModifierEffectMapping const& modifier_effect_mapping, std::string_view prefix, std::string_view key, ast::NodeCPtr value ) -> bool { const std::string flat_identifier = get_flat_identifier(prefix, key); - ModifierEffect const* effect = get_modifier_effect_by_identifier(flat_identifier); + ModifierEffect const* effect = modifier_effect_mapping.lookup_modifier_effect(flat_identifier); if (effect != nullptr) { return add_modifier_cb(effect, value); } else { @@ -727,13 +797,33 @@ key_value_callback_t ModifierManager::_modifier_effect_callback( return [this, type, default_callback, add_modifier_cb, add_flattened_modifier_cb]( std::string_view key, ast::NodeCPtr value ) -> bool { + using enum ModifierEffectMapping::modifier_effect_mapping_type_t; + + // TODO - template-ise the modifier type argument so getting the ModifierEffectMapping pointer can be made constexpr + const ModifierEffectMapping::modifier_effect_mapping_type_t mapping_type = + modifier_type_to_modifier_effect_mapping_type(type); + + if (mapping_type >= MODIFIER_EFFECT_MAPPING_COUNT) { + Logger::error( + "Modifier type \"", Modifier::modifier_type_to_string(type), + "\" has produced an invalid modifier effect mapping type \"", + ModifierEffectMapping::modifier_effect_mapping_type_to_string(mapping_type), "\"!" + ); + return false; + } + + ModifierEffectMapping const& modifier_effect_mapping = modifier_effect_mappings[static_cast<size_t>(mapping_type)]; if (dryad::node_has_kind<ast::IdentifierValue>(value)) { - ModifierEffect const* effect = get_modifier_effect_by_identifier(key); + ModifierEffect const* effect = modifier_effect_mapping.lookup_modifier_effect(key); if (effect != nullptr) { return add_modifier_cb(effect, value); - } else if (key == "war_exhaustion_effect") { + } + + // This will all be unnecessary when using modifier effect mappings + + /* else if (key == "war_exhaustion_effect") { Logger::warning("war_exhaustion_effect does nothing (vanilla issues have it)."); return true; } else { @@ -758,7 +848,7 @@ key_value_callback_t ModifierManager::_modifier_effect_callback( ); return false; } - } + }*/ } else if (dryad::node_has_kind<ast::ListValue>(value) && complex_modifiers.contains(key)) { if (key == "rebel_org_gain") { // because of course there's a special one std::string_view faction_identifier; @@ -769,11 +859,17 @@ key_value_callback_t ModifierManager::_modifier_effect_callback( "value", ONE_EXACTLY, assign_variable_callback(value_node) )(value); - ret &= add_flattened_modifier_cb(key, faction_identifier, value_node); + ret &= add_flattened_modifier_cb(modifier_effect_mapping, key, faction_identifier, value_node); return ret; } else { - return expect_dictionary(std::bind_front(add_flattened_modifier_cb, key))(value); + return expect_dictionary( + [add_flattened_modifier_cb, &modifier_effect_mapping, key]( + std::string_view dict_key, ast::NodeCPtr dict_value + ) -> bool { + return add_flattened_modifier_cb(modifier_effect_mapping, key, dict_key, dict_value); + } + )(value); } } @@ -781,16 +877,15 @@ key_value_callback_t ModifierManager::_modifier_effect_callback( }; } -node_callback_t ModifierManager::expect_validated_modifier_value_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback, - ModifierEffectValidator auto effect_validator +node_callback_t ModifierManager::expect_modifier_value_and_default( + callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback ) const { - return [this, modifier_callback, type, default_callback, effect_validator](ast::NodeCPtr root) -> bool { + return [this, modifier_callback, type, default_callback](ast::NodeCPtr root) -> bool { ModifierValue modifier; bool ret = expect_dictionary_reserve_length( modifier.values, - _modifier_effect_callback(modifier, type, default_callback, effect_validator) + _modifier_effect_callback(modifier, type, default_callback) )(root); ret &= modifier_callback(std::move(modifier)); @@ -799,47 +894,12 @@ node_callback_t ModifierManager::expect_validated_modifier_value_and_default( }; } -node_callback_t ModifierManager::expect_validated_modifier_value( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - ModifierEffectValidator auto effect_validator -) const { - return expect_validated_modifier_value_and_default(modifier_callback, type, key_value_invalid_callback, effect_validator); -} - -node_callback_t ModifierManager::expect_modifier_value_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback -) const { - return expect_validated_modifier_value_and_default( - modifier_callback, type, default_callback, [](ModifierEffect const&) -> bool { - return true; - } - ); -} - node_callback_t ModifierManager::expect_modifier_value( callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type ) const { return expect_modifier_value_and_default(modifier_callback, type, key_value_invalid_callback); } -node_callback_t ModifierManager::expect_whitelisted_modifier_value_and_default( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, string_set_t const& whitelist, - key_value_callback_t default_callback -) const { - return expect_validated_modifier_value_and_default( - modifier_callback, type, default_callback, - [&whitelist](ModifierEffect const& effect) -> bool { - return whitelist.contains(effect.get_identifier()); - } - ); -} - -node_callback_t ModifierManager::expect_whitelisted_modifier_value( - callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, string_set_t const& whitelist -) const { - return expect_whitelisted_modifier_value_and_default(modifier_callback, type, whitelist, key_value_invalid_callback); -} - node_callback_t ModifierManager::expect_modifier_value_and_key_map_and_default( callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, key_value_callback_t default_callback, key_map_t&& key_map diff --git a/src/openvic-simulation/modifier/ModifierManager.hpp b/src/openvic-simulation/modifier/ModifierManager.hpp index 51f89ae..bb946a7 100644 --- a/src/openvic-simulation/modifier/ModifierManager.hpp +++ b/src/openvic-simulation/modifier/ModifierManager.hpp @@ -2,14 +2,12 @@ #include "openvic-simulation/modifier/Modifier.hpp" #include "openvic-simulation/modifier/ModifierEffectCache.hpp" +#include "openvic-simulation/modifier/ModifierEffectMapping.hpp" #include "openvic-simulation/modifier/StaticModifierCache.hpp" #include "openvic-simulation/types/IdentifierRegistry.hpp" namespace OpenVic { - template<typename Fn> - concept ModifierEffectValidator = std::predicate<Fn, ModifierEffect const&>; - struct ModifierManager { friend struct StaticModifierCache; friend struct BuildingTypeManager; @@ -37,10 +35,11 @@ namespace OpenVic { ModifierEffectCache PROPERTY(modifier_effect_cache); StaticModifierCache PROPERTY(static_modifier_cache); + std::vector<ModifierEffectMapping> PROPERTY(modifier_effect_mappings); + /* effect_validator takes in ModifierEffect const& */ NodeTools::key_value_callback_t _modifier_effect_callback( - ModifierValue& modifier, Modifier::modifier_type_t type, NodeTools::key_value_callback_t default_callback, - ModifierEffectValidator auto effect_validator + ModifierValue& modifier, Modifier::modifier_type_t type, NodeTools::key_value_callback_t default_callback ) const; public: @@ -50,7 +49,9 @@ namespace OpenVic { bool positive_good, ModifierEffect::format_t format, ModifierEffect::target_t targets, - std::string_view localisation_key = {} + std::string_view localisation_key = {}, + // mapping_key is placed after localisation_key as it's less likely to be set explicitly + std::string_view mapping_key = {} ); bool register_complex_modifier(std::string_view identifier); @@ -62,6 +63,7 @@ namespace OpenVic { std::string const& identifier, ModifierEffect const* effect, std::vector<Modifier::modifier_type_t> const& types ); + bool setup_modifier_effect_mappings(); bool setup_modifier_effects(); bool add_event_modifier(std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon); @@ -77,15 +79,6 @@ namespace OpenVic { bool parse_scripts(DefinitionManager const& definition_manager); - NodeTools::node_callback_t expect_validated_modifier_value_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - NodeTools::key_value_callback_t default_callback, ModifierEffectValidator auto effect_validator - ) const; - NodeTools::node_callback_t expect_validated_modifier_value( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - ModifierEffectValidator auto effect_validator - ) const; - NodeTools::node_callback_t expect_modifier_value_and_default( NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, NodeTools::key_value_callback_t default_callback @@ -94,15 +87,6 @@ namespace OpenVic { NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type ) const; - NodeTools::node_callback_t expect_whitelisted_modifier_value_and_default( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - string_set_t const& whitelist, NodeTools::key_value_callback_t default_callback - ) const; - NodeTools::node_callback_t expect_whitelisted_modifier_value( - NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, - string_set_t const& whitelist - ) const; - // In the functions below, key_map refers to a map from identifier strings to NodeTools::dictionary_entry_t, // allowing any non-modifier effect keys found to be parsed in a custom way, similar to expect_dictionary_keys. NodeTools::node_callback_t expect_modifier_value_and_key_map_and_default( diff --git a/src/openvic-simulation/research/Invention.cpp b/src/openvic-simulation/research/Invention.cpp index 808dad4..d39a4b8 100644 --- a/src/openvic-simulation/research/Invention.cpp +++ b/src/openvic-simulation/research/Invention.cpp @@ -64,9 +64,8 @@ bool InventionManager::load_inventions_file( ) -> bool { using enum Modifier::modifier_type_t; - // TODO - use the same variable for all modifiers rather than combining them at the end? ModifierValue loose_modifiers; - ModifierValue modifiers; + ModifierValue effect_modifiers; Invention::unit_set_t activated_units; Invention::building_set_t activated_buildings; @@ -86,8 +85,8 @@ bool InventionManager::load_inventions_file( "limit", ONE_EXACTLY, limit.expect_script(), "chance", ONE_EXACTLY, chance.expect_conditional_weight(ConditionalWeight::BASE), "effect", ZERO_OR_ONE, modifier_manager.expect_modifier_value_and_keys( - move_variable_callback(modifiers), - INVENTION, + move_variable_callback(effect_modifiers), + INVENTION_EFFECT, "gas_attack", ZERO_OR_ONE, expect_bool(assign_variable_callback(unlock_gas_attack)), "gas_defence", ZERO_OR_ONE, expect_bool(assign_variable_callback(unlock_gas_defence)), "activate_unit", ZERO_OR_MORE, @@ -101,10 +100,10 @@ bool InventionManager::load_inventions_file( ) )(value); - modifiers += loose_modifiers; + loose_modifiers += effect_modifiers; ret &= add_invention( - identifier, std::move(modifiers), news, std::move(activated_units), std::move(activated_buildings), + identifier, std::move(loose_modifiers), news, std::move(activated_units), std::move(activated_buildings), std::move(enabled_crimes), unlock_gas_attack, unlock_gas_defence, std::move(limit), std::move(chance) ); |