1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#pragma once
#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 {
struct ModifierManager {
friend struct StaticModifierCache;
friend struct BuildingTypeManager;
friend struct GoodDefinitionManager;
friend struct UnitTypeManager;
friend struct RebelManager;
friend struct PopManager;
friend struct TechnologyManager;
using effect_variant_map_t = ordered_map<Modifier::modifier_type_t, ModifierEffect const*>;
/* Some ModifierEffects are generated mid-load, such as max/min count modifiers for each building, so
* we can't lock it until loading is over. This means we can't rely on locking for pointer stability,
* so instead we store the effects in a deque which doesn't invalidate pointers on insert.
*/
private:
CaseInsensitiveIdentifierRegistry<ModifierEffect, RegistryStorageInfoDeque> IDENTIFIER_REGISTRY(modifier_effect);
case_insensitive_string_set_t complex_modifiers;
string_map_t<effect_variant_map_t> modifier_effect_variants;
IdentifierRegistry<IconModifier> IDENTIFIER_REGISTRY(event_modifier);
IdentifierRegistry<Modifier> IDENTIFIER_REGISTRY(static_modifier);
IdentifierRegistry<TriggeredModifier> IDENTIFIER_REGISTRY(triggered_modifier);
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
) const;
public:
bool 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 = {},
// 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);
static std::string get_flat_identifier(
std::string_view complex_modifier_identifier, std::string_view variant_identifier
);
bool register_modifier_effect_variants(
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);
bool load_event_modifiers(ast::NodeCPtr root);
bool add_static_modifier(std::string_view identifier, ModifierValue&& values);
bool load_static_modifiers(ast::NodeCPtr root);
bool add_triggered_modifier(
std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger
);
bool load_triggered_modifiers(ast::NodeCPtr root);
bool parse_scripts(DefinitionManager const& definition_manager);
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
) const;
NodeTools::node_callback_t expect_modifier_value(
NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type
) 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(
NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type,
NodeTools::key_value_callback_t default_callback, NodeTools::key_map_t&& key_map
) const;
NodeTools::node_callback_t expect_modifier_value_and_key_map(
NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type,
NodeTools::key_map_t&& key_map
) const;
template<typename... Args>
NodeTools::node_callback_t expect_modifier_value_and_key_map_and_default(
NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type,
NodeTools::key_value_callback_t default_callback, NodeTools::key_map_t&& key_map, Args... args
) const {
NodeTools::add_key_map_entries(key_map, args...);
return expect_modifier_value_and_key_map_and_default(
modifier_callback, type, default_callback, std::move(key_map)
);
}
template<typename... Args>
NodeTools::node_callback_t expect_modifier_value_and_keys_and_default(
NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type,
NodeTools::key_value_callback_t default_callback, Args... args
) const {
return expect_modifier_value_and_key_map_and_default(modifier_callback, type, default_callback, {}, args...);
}
template<typename... Args>
NodeTools::node_callback_t expect_modifier_value_and_keys(
NodeTools::callback_t<ModifierValue&&> modifier_callback, Modifier::modifier_type_t type, Args... args
) const {
return expect_modifier_value_and_key_map_and_default(
modifier_callback, type, NodeTools::key_value_invalid_callback, {}, args...
);
}
};
}
|