aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp2
-rw-r--r--src/openvic-simulation/economy/GoodDefinition.cpp11
-rw-r--r--src/openvic-simulation/economy/production/ProductionType.cpp2
-rw-r--r--src/openvic-simulation/military/Wargoal.cpp6
-rw-r--r--src/openvic-simulation/misc/Event.cpp8
-rw-r--r--src/openvic-simulation/scripts/Condition.cpp1038
-rw-r--r--src/openvic-simulation/scripts/Condition.hpp45
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPoint.hpp100
8 files changed, 808 insertions, 404 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp
index 0ffc00f..2b438c7 100644
--- a/src/openvic-simulation/dataloader/Dataloader.cpp
+++ b/src/openvic-simulation/dataloader/Dataloader.cpp
@@ -1110,7 +1110,7 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) {
ret = false;
}
- // ret &= parse_scripts(definition_manager);
+ ret &= parse_scripts(definition_manager);
free_cache();
diff --git a/src/openvic-simulation/economy/GoodDefinition.cpp b/src/openvic-simulation/economy/GoodDefinition.cpp
index ba5aff8..5440b94 100644
--- a/src/openvic-simulation/economy/GoodDefinition.cpp
+++ b/src/openvic-simulation/economy/GoodDefinition.cpp
@@ -90,6 +90,7 @@ bool GoodDefinitionManager::load_goods_file(ast::NodeCPtr root) {
}
bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager) const {
+ constexpr bool has_no_effect = true;
using enum ModifierEffect::format_t;
using enum ModifierEffect::target_t;
@@ -116,11 +117,11 @@ bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager
const auto good_modifier = [&modifier_manager, &ret, &good_identifier](
ModifierEffect const*& effect_cache, std::string_view name, bool is_positive_good,
- std::string_view localisation_key
+ std::string_view localisation_key, bool has_no_effect = false
) -> void {
ret &= modifier_manager.register_technology_modifier_effect(
effect_cache, ModifierManager::get_flat_identifier(name, good_identifier), is_positive_good,
- PROPORTION_DECIMAL, localisation_key
+ PROPORTION_DECIMAL, localisation_key, has_no_effect
);
};
@@ -132,15 +133,15 @@ bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager
good_modifier(
this_good_effects.artisan_goods_input, "artisan_goods_input", false,
- make_production_localisation_suffix("TECH_INPUT")
+ make_production_localisation_suffix("TECH_INPUT"), has_no_effect
);
good_modifier(
this_good_effects.artisan_goods_output, "artisan_goods_output", true,
- make_production_localisation_suffix("TECH_OUTPUT")
+ make_production_localisation_suffix("TECH_OUTPUT"), has_no_effect
);
good_modifier(
this_good_effects.artisan_goods_throughput, "artisan_goods_throughput", true,
- make_production_localisation_suffix("TECH_THROUGHPUT")
+ make_production_localisation_suffix("TECH_THROUGHPUT"), has_no_effect
);
good_modifier(
this_good_effects.factory_goods_input, "factory_goods_input", false,
diff --git a/src/openvic-simulation/economy/production/ProductionType.cpp b/src/openvic-simulation/economy/production/ProductionType.cpp
index 033026d..2e75291 100644
--- a/src/openvic-simulation/economy/production/ProductionType.cpp
+++ b/src/openvic-simulation/economy/production/ProductionType.cpp
@@ -273,7 +273,7 @@ bool ProductionTypeManager::load_production_types_file(
"bonus", ZERO_OR_MORE, [&bonuses](ast::NodeCPtr bonus_node) -> bool {
using enum scope_type_t;
- ConditionScript trigger { STATE, NO_SCOPE, NO_SCOPE };
+ ConditionScript trigger { PROVINCE, NO_SCOPE, NO_SCOPE };
fixed_point_t bonus_value {};
const bool ret = expect_dictionary_keys(
diff --git a/src/openvic-simulation/military/Wargoal.cpp b/src/openvic-simulation/military/Wargoal.cpp
index ce6b153..a465722 100644
--- a/src/openvic-simulation/military/Wargoal.cpp
+++ b/src/openvic-simulation/military/Wargoal.cpp
@@ -97,9 +97,9 @@ bool WargoalTypeManager::load_wargoal_file(ovdl::v2script::Parser const& parser)
WargoalType::peace_modifiers_t modifiers;
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_states { PROVINCE, COUNTRY, COUNTRY };
+ ConditionScript allowed_substate_regions { PROVINCE, COUNTRY, COUNTRY };
+ ConditionScript allowed_states_in_crisis { PROVINCE, COUNTRY, COUNTRY };
ConditionScript allowed_countries { COUNTRY, COUNTRY, COUNTRY };
EffectScript on_add, on_po_accepted; //country as default scope for both
diff --git a/src/openvic-simulation/misc/Event.cpp b/src/openvic-simulation/misc/Event.cpp
index 64b1f64..7f57ccc 100644
--- a/src/openvic-simulation/misc/Event.cpp
+++ b/src/openvic-simulation/misc/Event.cpp
@@ -140,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, NO_SCOPE };
- ConditionalWeight mean_time_to_happen { initial_scope, initial_scope, NO_SCOPE };
+ ConditionScript trigger { initial_scope, COUNTRY, NO_SCOPE };
+ ConditionalWeight mean_time_to_happen { initial_scope, COUNTRY, NO_SCOPE };
EffectScript immediate;
std::vector<Event::EventOption> options;
@@ -167,8 +167,8 @@ bool EventManager::load_event_file(IssueManager const& issue_manager, ast::NodeC
EffectScript effect;
ConditionalWeight ai_chance {
initial_scope,
- initial_scope,
- COUNTRY | PROVINCE // TODO - decide which to use?
+ COUNTRY,
+ COUNTRY
};
bool ret = expect_dictionary_keys_and_default(
diff --git a/src/openvic-simulation/scripts/Condition.cpp b/src/openvic-simulation/scripts/Condition.cpp
index ea565a7..47f63bd 100644
--- a/src/openvic-simulation/scripts/Condition.cpp
+++ b/src/openvic-simulation/scripts/Condition.cpp
@@ -10,6 +10,7 @@ using namespace OpenVic::NodeTools;
using no_argument_t = ConditionNode::no_argument_t;
using this_argument_t = ConditionNode::this_argument_t;
using from_argument_t = ConditionNode::from_argument_t;
+using special_argument_t = ConditionNode::special_argument_t;
using integer_t = ConditionNode::integer_t;
using argument_t = ConditionNode::argument_t;
@@ -19,6 +20,11 @@ using scope_t = ConditionNode::scope_t;
static constexpr std::string_view THIS_KEYWORD = "THIS";
static constexpr std::string_view FROM_KEYWORD = "FROM";
+// Used for this_culture_union
+static constexpr const char this_union_keyword[] = "this_union";
+// Used for controlled_by
+static constexpr const char owner_keyword[] = "owner";
+
ConditionNode::ConditionNode(
Condition const* new_condition,
argument_t&& new_argument
@@ -39,6 +45,126 @@ bool ConditionNode::execute(
);
}
+struct print_condition_node_visitor_t {
+ std::ostream& stream;
+ size_t indent = 0;
+ static constexpr size_t indent_width = 2;
+ Condition const* last_condition = nullptr;
+
+ void print(ConditionNode const& node) {
+ last_condition = node.get_condition();
+ stream << last_condition << " = ";
+ std::visit(*this, node.get_argument());
+ }
+ void print_newline_indent() {
+ stream << "\n" << std::setw(indent * indent_width) << "";
+ }
+ template<typename P1, typename P2>
+ void print_pair(
+ std::string_view first_key, std::string_view second_key, std::pair<P1, P2> const& values
+ ) {
+ stream << "{";
+ indent++;
+ print_newline_indent();
+ stream << first_key << " = " << values.first;
+ print_newline_indent();
+ stream << second_key << " = " << values.second;
+ indent--;
+ print_newline_indent();
+ stream << "}";
+ }
+ void operator()(no_argument_t const& arg) {
+ stream << "<NO_ARGUMENT>";
+ }
+ void operator()(this_argument_t const& arg) {
+ stream << THIS_KEYWORD;
+ }
+ void operator()(from_argument_t const& arg) {
+ stream << FROM_KEYWORD;
+ }
+ void operator()(special_argument_t const& arg) {
+ const std::string_view identifier =
+ last_condition != nullptr ? last_condition->get_identifier() : std::string_view {};
+ if (identifier == "this_culture_union") {
+ stream << this_union_keyword;
+ } else if (identifier == "controlled_by") {
+ stream << owner_keyword;
+ } else {
+ stream << "<SPECIAL_ARGUMENT>";
+ }
+ }
+ void operator()(std::vector<ConditionNode> const& arg) {
+ stream << "{";
+
+ if (!arg.empty()) {
+ indent++;
+
+ for (ConditionNode const& child : arg) {
+ print_newline_indent();
+ print(child);
+ }
+
+ indent--;
+ print_newline_indent();
+ }
+
+ stream << "}";
+ }
+ void operator()(bool const& arg) {
+ stream << (arg ? "yes" : "no");
+ }
+ void operator()(std::pair<PopType const*, fixed_point_t> const& arg) {
+ print_pair("type", "value", arg);
+ }
+ void operator()(std::pair<bool, bool> const& arg) {
+ print_pair(
+ "in_whole_capital_state", "limit_to_world_greatest_level",
+ std::pair { arg.first ? "yes" : "no", arg.second ? "yes" : "no" }
+ );
+ }
+ void operator()(std::pair<Ideology const*, fixed_point_t> const& arg) {
+ print_pair("ideology", "value", arg);
+ }
+ void operator()(std::vector<PopType const*> const& arg) {
+ stream << "{";
+
+ if (!arg.empty()) {
+ indent++;
+
+ for (PopType const* pop_type : arg) {
+ print_newline_indent();
+ stream << "worker = " << pop_type;
+ }
+
+ indent--;
+ print_newline_indent();
+ }
+
+ stream << "}";
+ }
+ void operator()(std::pair<CountryDefinition const*, fixed_point_t> const& arg) {
+ print_pair("who", "value", arg);
+ }
+ void operator()(std::pair<this_argument_t, fixed_point_t> const& arg) {
+ print_pair("who", "value", std::pair { THIS_KEYWORD, arg.second });
+ }
+ void operator()(std::pair<from_argument_t, fixed_point_t> const& arg) {
+ print_pair("who", "value", std::pair { FROM_KEYWORD, arg.second });
+ }
+ void operator()(std::pair<std::string, fixed_point_t> const& arg) {
+ print_pair("which", "value", arg);
+ }
+ void operator()(auto const& arg) {
+ stream << arg;
+ }
+};
+
+std::ostream& OpenVic::operator<<(std::ostream& stream, ConditionNode const& node) {
+ print_condition_node_visitor_t { stream }.print(node);
+
+ return stream;
+}
+
Condition::Condition(
std::string_view new_identifier,
parse_callback_t&& new_parse_callback,
@@ -199,9 +325,63 @@ bool ConditionManager::_parse_condition_node_list_callback(
return ret;
}
+/* Callback for conditions with a special case as well as a regular value type:
+ * - special_case_triggered(condition, definition_manager, callback, str, ret)
+ * - str is the condition's value parsed as an identifier or string
+ * - special_case_triggered is the bool return value which determines whether to return ret or continue with the regular
+ * value parsing */
+using special_callback_t = bool (*)(
+ Condition const&, DefinitionManager const&, callback_t<argument_t&&>, std::string_view, bool&
+);
+
+static bool _parse_condition_node_special_callback_bool(
+ Condition const& condition, DefinitionManager const& definition_manager, callback_t<argument_t&&> callback,
+ std::string_view str, bool& ret
+) {
+ if (StringUtils::strings_equal_case_insensitive(str, "yes")) {
+ ret = callback(true);
+ return true;
+ }
+
+ if (StringUtils::strings_equal_case_insensitive(str, "no")) {
+ ret = callback(false);
+ return true;
+ }
+
+ return false;
+}
+
+template<char const* KEYWORD>
+static bool _parse_condition_node_special_callback_keyword(
+ Condition const& condition, DefinitionManager const& definition_manager, callback_t<argument_t&&> callback,
+ std::string_view str, bool& ret
+) {
+ if (StringUtils::strings_equal_case_insensitive(str, KEYWORD)) {
+ ret = callback(special_argument_t {});
+ return true;
+ }
+
+ return false;
+}
+
+static bool _parse_condition_node_special_callback_country(
+ Condition const& condition, DefinitionManager const& definition_manager, callback_t<argument_t&&> callback,
+ std::string_view str, bool& ret
+) {
+ CountryDefinition const* country =
+ definition_manager.get_country_definition_manager().get_country_definition_by_identifier(str);
+
+ if (country != nullptr) {
+ ret = callback(country);
+ return true;
+ }
+
+ return false;
+}
+
// ALLOWED_SCOPES is a bitfield indicating valid values of current_scope, as well as whether the value is allowed to be
// THIS or FROM corresponding to the special argument types this_argument_t and from_argument_t respectively.
-template<typename T, scope_type_t ALLOWED_SCOPES = scope_type_t::ALL_SCOPES>
+template<typename T, scope_type_t ALLOWED_SCOPES = scope_type_t::ALL_SCOPES, special_callback_t SPECIAL_CALLBACK = nullptr>
static bool _parse_condition_node_value_callback(
Condition const& condition, DefinitionManager const& definition_manager, scope_type_t current_scope,
scope_type_t this_scope, scope_type_t from_scope, ast::NodeCPtr node, callback_t<argument_t&&> callback
@@ -215,9 +395,16 @@ static bool _parse_condition_node_value_callback(
std::same_as<T, CountryDefinition const*> || std::same_as<T, ProvinceDefinition const*> ||
std::same_as<T, GoodDefinition const*> || std::same_as<T, Continent const*> || std::same_as<T, BuildingType const*> ||
std::same_as<T, Issue const*> || std::same_as<T, WargoalType const*> || std::same_as<T, PopType const*> ||
- std::same_as<T, Culture const*> || std::same_as<T, Religion const*> || std::same_as<T, GovernmentType const*> ||
- std::same_as<T, Ideology const*> || std::same_as<T, Reform const*> || std::same_as<T, NationalValue const*> ||
- std::same_as<T, Invention const*> || std::same_as<T, TechnologySchool const*>
+ std::same_as<T, CultureGroup const*> || std::same_as<T, Culture const*> || std::same_as<T, Religion const*> ||
+ std::same_as<T, GovernmentType const*> || std::same_as<T, Ideology const*> || std::same_as<T, Reform const*> ||
+ std::same_as<T, NationalValue const*> || std::same_as<T, Invention const*> ||
+ std::same_as<T, TechnologySchool const*> || std::same_as<T, Crime const*> || std::same_as<T, Region const*> ||
+ std::same_as<T, TerrainType const*> || std::same_as<T, Strata const*> ||
+
+ // Multi-value arguments
+ std::same_as<T, std::pair<PopType const*, fixed_point_t>> || std::same_as<T, std::pair<bool, bool>> ||
+ std::same_as<T, std::pair<Ideology const*, fixed_point_t>> || std::same_as<T, std::vector<PopType const*>> ||
+ std::same_as<T, std::pair<std::string, fixed_point_t>>
);
using enum scope_type_t;
@@ -230,18 +417,14 @@ static bool _parse_condition_node_value_callback(
return false;
}
- bool ret = true;
-
// All possible value types can also be interpreted as an identifier or string, so we shouldn't get any unwanted error
// messages if the value is a regular value rather than THIS or FROM. In fact if expect_identifier_or_string returns false
// when checking for THIS or FROM then we can be confident that it would also return false when parsing a regular value.
- if constexpr (share_scope_type(ALLOWED_SCOPES, THIS | FROM)) {
+ if constexpr (share_scope_type(ALLOWED_SCOPES, THIS | FROM) || SPECIAL_CALLBACK != nullptr) {
std::string_view str;
- ret &= expect_identifier_or_string(assign_variable_callback(str))(node);
-
- if (!ret) {
+ if (!expect_identifier_or_string(assign_variable_callback(str))(node)) {
Logger::error(
"Error parsing condition \"", condition.get_identifier(),
"\": failed to parse identifier or string when checking for THIS and/or FROM condition argument!"
@@ -251,19 +434,25 @@ static bool _parse_condition_node_value_callback(
if constexpr (share_scope_type(ALLOWED_SCOPES, THIS)) {
if (StringUtils::strings_equal_case_insensitive(str, THIS_KEYWORD)) {
- ret &= callback(this_argument_t {});
- return ret;
+ return callback(this_argument_t {});
}
}
if constexpr (share_scope_type(ALLOWED_SCOPES, FROM)) {
if (StringUtils::strings_equal_case_insensitive(str, FROM_KEYWORD)) {
- ret &= callback(from_argument_t {});
+ return callback(from_argument_t {});
+ }
+ }
+
+ if constexpr (SPECIAL_CALLBACK != nullptr) {
+ bool ret = true;
+ if ((*SPECIAL_CALLBACK)(condition, definition_manager, callback, str, ret)) {
return ret;
}
}
}
+ bool ret = true;
T value {};
if constexpr (std::same_as<T, bool>) {
@@ -307,6 +496,10 @@ static bool _parse_condition_node_value_callback(
ret = definition_manager.get_pop_manager().expect_pop_type_identifier_or_string(
assign_variable_callback_pointer(value)
)(node);
+ } else if constexpr (std::same_as<T, CultureGroup const*>) {
+ ret = definition_manager.get_pop_manager().get_culture_manager().expect_culture_group_identifier_or_string(
+ assign_variable_callback_pointer(value)
+ )(node);
} else if constexpr (std::same_as<T, Culture const*>) {
ret = definition_manager.get_pop_manager().get_culture_manager().expect_culture_identifier_or_string(
assign_variable_callback_pointer(value)
@@ -336,6 +529,53 @@ static bool _parse_condition_node_value_callback(
ret = definition_manager.get_research_manager().get_technology_manager().expect_technology_school_identifier_or_string(
assign_variable_callback_pointer(value)
)(node);
+ } else if constexpr (std::same_as<T, Crime const*>) {
+ ret = definition_manager.get_crime_manager().expect_crime_modifier_identifier_or_string(
+ assign_variable_callback_pointer(value)
+ )(node);
+ } else if constexpr (std::same_as<T, Region const*>) {
+ ret = definition_manager.get_map_definition().expect_region_identifier_or_string(
+ assign_variable_callback_pointer(value)
+ )(node);
+ } else if constexpr (std::same_as<T, TerrainType const*>) {
+ ret = definition_manager.get_map_definition().get_terrain_type_manager().expect_terrain_type_identifier_or_string(
+ assign_variable_callback_pointer(value)
+ )(node);
+ } else if constexpr (std::same_as<T, Strata const*>) {
+ ret = definition_manager.get_pop_manager().expect_strata_identifier_or_string(
+ assign_variable_callback_pointer(value)
+ )(node);
+ } else if constexpr (std::same_as<T, std::pair<PopType const*, fixed_point_t>>) {
+ ret = expect_dictionary_keys(
+ "type", ONE_EXACTLY, definition_manager.get_pop_manager().expect_pop_type_identifier_or_string(
+ assign_variable_callback_pointer(value.first)
+ ),
+ "value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(value.second))
+ )(node);
+ } else if constexpr (std::same_as<T, std::pair<bool, bool>>) {
+ ret = expect_dictionary_keys(
+ "in_whole_capital_state", ONE_EXACTLY, assign_variable_callback(value.first),
+ "limit_to_world_greatest_level", ONE_EXACTLY, assign_variable_callback(value.second)
+ )(node);
+ } else if constexpr (std::same_as<T, std::pair<Ideology const*, fixed_point_t>>) {
+ ret = expect_dictionary_keys(
+ "ideology", ONE_EXACTLY,
+ definition_manager.get_politics_manager().get_ideology_manager().expect_ideology_identifier_or_string(
+ assign_variable_callback_pointer(value.first)
+ ),
+ "value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(value.second))
+ )(node);
+ } else if constexpr (std::same_as<T, std::vector<PopType const*>>) {
+ ret = expect_dictionary_keys(
+ "worker", ONE_OR_MORE, definition_manager.get_pop_manager().expect_pop_type_identifier_or_string(
+ vector_callback_pointer(value)
+ )
+ )(node);
+ } else if constexpr (std::same_as<T, std::pair<std::string, fixed_point_t>>) {
+ ret = expect_dictionary_keys(
+ "which", ONE_EXACTLY, expect_identifier_or_string(assign_variable_callback_string(value.first)),
+ "value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(value.second))
+ )(node);
}
if (ret) {
@@ -345,6 +585,52 @@ static bool _parse_condition_node_value_callback(
return ret;
}
+static bool _parse_condition_node_who_value_callback(
+ Condition const& condition, DefinitionManager const& definition_manager, scope_type_t current_scope,
+ scope_type_t this_scope, scope_type_t from_scope, ast::NodeCPtr node, callback_t<argument_t&&> callback
+) {
+ using enum scope_type_t;
+
+ if (!share_scope_type(current_scope, COUNTRY)) {
+ Logger::error(
+ "Error parsing condition \"", condition.get_identifier(),
+ "\": scope mismatch - expected ", COUNTRY, ", got ", current_scope
+ );
+ return false;
+ }
+
+ std::string_view str;
+ fixed_point_t value;
+
+ if (
+ expect_dictionary_keys(
+ "who", ONE_EXACTLY, expect_identifier_or_string(assign_variable_callback(str)),
+ "value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(value))
+ )(node)
+ ) {
+ if (StringUtils::strings_equal_case_insensitive(str, THIS_KEYWORD)) {
+ return callback(std::pair { this_argument_t {}, value });
+ }
+
+ if (StringUtils::strings_equal_case_insensitive(str, FROM_KEYWORD)) {
+ return callback(std::pair { from_argument_t {}, value });
+ }
+
+ CountryDefinition const* country =
+ definition_manager.get_country_definition_manager().get_country_definition_by_identifier(str);
+
+ if (country != nullptr) {
+ return callback(std::pair { country, value });
+ }
+
+ Logger::error(
+ "Error parsing condition \"", condition.get_identifier(), "\": unknown country \"", str, "\""
+ );
+ }
+
+ return false;
+}
+
// EXECUTE CALLBACK HELPERS
static constexpr bool _execute_condition_node_unimplemented(
@@ -766,7 +1052,12 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
}
)
);
- // ret &= add_condition("independence", GROUP, COUNTRY, COUNTRY); //only from rebels!
+ // Only from RebelType demands_enforced_trigger, changes scope to the country getting independence
+ ret &= add_condition(
+ "independence",
+ _parse_condition_node_list_callback<COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
/* Trigger Country Scopes */
static const auto get_core_scopes =
@@ -880,7 +1171,7 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
);
ret &= add_condition(
"any_state",
- _parse_condition_node_list_callback<STATE, COUNTRY>,
+ _parse_condition_node_list_callback<PROVINCE, COUNTRY>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -999,7 +1290,7 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
);
ret &= add_condition(
"state_scope",
- _parse_condition_node_list_callback<STATE, PROVINCE>,
+ _parse_condition_node_list_callback<PROVINCE, PROVINCE>,
_execute_condition_node_unimplemented
);
@@ -1306,23 +1597,12 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
);
ret &= add_condition(
"can_build_fort_in_capital",
- /* TODO - complex:
- * - used at COUNTRY scope, specifically in westernisation reform on_execute trigger conditions
- * - value is a dictionary with two entries:
- * - in_whole_capital_state = <bool>
- * - yes = build in all provinces in capital state
- * - no = just in main capital province
- * - limit_to_world_greatest_level = <bool>
- * - yes = build at level of world's greatest fort (greatest researched or greatest built?)
- * - no = either build level 1 or highest level this country can build (in practice 1 as the country will only
- * just have gotten the first fort tech, should be tested in other scenarios) */
- _parse_condition_node_unimplemented,
+ _parse_condition_node_value_callback<std::pair<bool, bool>, COUNTRY>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
"can_build_railway_in_capital",
- // TODO - same complex structure as can_build_fort_in_capital, with two dictionary entries
- _parse_condition_node_unimplemented,
+ _parse_condition_node_value_callback<std::pair<bool, bool>, COUNTRY>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1361,7 +1641,6 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
);
ret &= add_condition(
"check_variable",
- //COMPLEX, COUNTRY, NO_SCOPE, NO_IDENTIFIER, VARIABLE
/* TODO - complex:
* - does this have any scope restrictions, and does it affect scope in any way? The wiki warns that this doesn't
* work from province scope.
@@ -1374,7 +1653,7 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
* - The number to compare the current variable value against. Returns true if the variable has been previously
* set and has a value greater than or equal to the number.
* - Can values be negative? Can they be non-integers? How big can they get? */
- _parse_condition_node_unimplemented,
+ _parse_condition_node_value_callback<std::pair<std::string, fixed_point_t>, COUNTRY>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1479,18 +1758,6 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
_parse_condition_node_value_callback<bool>,
_execute_condition_node_unimplemented
);
- /*
-culture
-Syntax:
-
-culture = [culture name]
-Use:
-Province Scope Effects: Returns true if there is a majority of the specified culture in the specified province.
-POP Scope Effects: Warning! Only returns true if there is a majority of the specified culture in the POP's province.
-To check if the POP itself has the culture, use "has_pop_culture" instead.
-
-
- */
ret &= add_condition(
"culture",
/* TODO - wiki says this can also be used at PROVINCE scope, and even at POP scope it checks that the majority
@@ -1498,7 +1765,7 @@ To check if the POP itself has the culture, use "has_pop_culture" instead.
* has_pop_culture should be used to check a specific pop's culture. The tooltips aren't very clear, with
* "culture = <culture>" showing up as "Culture is <culture>" and "has_pop_culture = <culture>" showing up as
* "<Pop type plural> in <province> have <culture>". */
- _parse_condition_node_value_callback<Culture const*, PROVINCE | POP>,
+ _parse_condition_node_value_callback<Culture const*, PROVINCE | POP | THIS | FROM>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1531,23 +1798,9 @@ To check if the POP itself has the culture, use "has_pop_culture" instead.
)
)
);
-/*
-diplomatic_influence
-Syntax:
-
-diplomatic_influence = {
- who = [THIS/FROM/TAG]
- value = x
-}
-Use:
-Returns true if country has more than x diplomatic influence in the country in scope.
-
-*/
- /* TODO - complex:
- * - */
ret &= add_condition(
"diplomatic_influence",
- _parse_condition_node_unimplemented,
+ _parse_condition_node_who_value_callback,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1560,18 +1813,11 @@ Returns true if country has more than x diplomatic influence in the country in s
_parse_condition_node_value_callback<bool, COUNTRY>,
_execute_condition_node_unimplemented
);
- /*
-exists
-Syntax:
-
-exists = [tag]
-Use:
-Returns true if the specified country exists. May also be used with [yes/no] to determine if the country in scope actually exists.
- */
ret &= add_condition(
- "exists",// IDENTIFIER | BOOLEAN, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG
- // bool or tag or THIS or FROM
- _parse_condition_node_unimplemented,
+ "exists",
+ _parse_condition_node_value_callback<
+ CountryDefinition const*, COUNTRY | THIS | FROM, _parse_condition_node_special_callback_bool
+ >,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1623,7 +1869,7 @@ Returns true if the specified country exists. May also be used with [yes/no] to
"has_country_modifier",
// TODO - which modifiers work here? just country event (+ specially handled debt statics)?
// - should this be parsed into a Modifier const* or kept as a std::string?
- _parse_condition_node_unimplemented,
+ _parse_condition_node_value_callback<std::string, COUNTRY>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1651,12 +1897,12 @@ Returns true if the specified country exists. May also be used with [yes/no] to
);
ret &= add_condition(
"has_pop_culture",
- _parse_condition_node_value_callback<Culture const*, POP>,
+ _parse_condition_node_value_callback<Culture const*, POP | THIS | FROM>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
"has_pop_religion",
- _parse_condition_node_value_callback<Religion const*, POP>,
+ _parse_condition_node_value_callback<Religion const*, POP | THIS | FROM>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -1675,7 +1921,7 @@ Returns true if the specified country exists. May also be used with [yes/no] to
_execute_condition_node_unimplemented
);
// "ideology = <ideology>"" doesn't seem to work as a country condition?
- // ret &= add_condition("ideology", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, IDEOLOGY);
+ // NOT FOUND - ret &= add_condition("ideology", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, IDEOLOGY);
ret &= add_condition(
"industrial_score",
// This doesn't seem to work with regular country identifiers, they're treated as 0
@@ -1715,8 +1961,13 @@ Returns true if the specified country exists. May also be used with [yes/no] to
_parse_condition_node_value_callback<bool, COUNTRY>,
_execute_condition_node_unimplemented
);
- // is_cultural_union can take bools and country identifiers, probably also THIS and FROM
- // ret &= add_condition("is_cultural_union", IDENTIFIER | BOOLEAN, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
+ ret &= add_condition(
+ "is_cultural_union",
+ _parse_condition_node_value_callback<
+ CountryDefinition const*, COUNTRY | THIS | FROM, _parse_condition_node_special_callback_bool
+ >,
+ _execute_condition_node_unimplemented
+ );
ret &= add_condition(
"is_disarmed",
_parse_condition_node_value_callback<bool, COUNTRY>,
@@ -1729,16 +1980,24 @@ Returns true if the specified country exists. May also be used with [yes/no] to
);
ret &= add_condition(
"is_colonial",
- _parse_condition_node_value_callback<bool, STATE>,
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_core",
+ // TODO - ensure ProvinceDefinition const* can only be used at COUNTRY scope and CountryDefinition const* at PROVINCE scope
+ _parse_condition_node_value_callback<
+ ProvinceDefinition const*, COUNTRY | PROVINCE | THIS | FROM, _parse_condition_node_special_callback_country
+ >,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_culture_group",
+ _parse_condition_node_value_callback<
+ CultureGroup const*, COUNTRY | POP | THIS | FROM, _parse_condition_node_special_callback_country
+ >,
_execute_condition_node_unimplemented
);
- /* is_core can be used:
- * - at COUNTRY scope with a province identifier (maybe THIS or FROM too)
- * - at PROVINCE scope with a country identifier or THIS or FROM
- */
- // ret &= add_condition("is_core", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG | PROVINCE_ID);
- // is_culture_group can be used at COUNTRY or POP scope with a culture, country, THIS or FROM
- // ret &= add_condition("is_culture_group", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG | CULTURE_GROUP);
ret &= add_condition(
"is_ideology_enabled",
// The wiki says this can only be used at COUNTRY and PROVINCE scopes but I see no reason why it can't be global
@@ -1811,11 +2070,6 @@ Returns true if the specified country exists. May also be used with [yes/no] to
_parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
_execute_condition_node_unimplemented
);
- // ret &= add_condition("middle_strata_militancy", REAL, COUNTRY);
- // ret &= add_condition("middle_strata_everyday_needs", REAL, COUNTRY);
- // ret &= add_condition("middle_strata_life_needs", REAL, COUNTRY);
- // ret &= add_condition("middle_strata_luxury_needs", REAL, COUNTRY);
- // ret &= add_condition("middle_tax", REAL, COUNTRY);
ret &= add_condition(
"military_access",
_parse_condition_node_value_callback<CountryDefinition const*, COUNTRY | THIS | FROM>,
@@ -1944,11 +2198,6 @@ Returns true if the specified country exists. May also be used with [yes/no] to
_parse_condition_node_value_callback<fixed_point_t, PROVINCE>,
_execute_condition_node_unimplemented
);
- // ret &= add_condition("poor_strata_militancy", REAL, COUNTRY);
- // ret &= add_condition("poor_strata_everyday_needs", REAL, COUNTRY);
- // ret &= add_condition("poor_strata_life_needs", REAL, COUNTRY);
- // ret &= add_condition("poor_strata_luxury_needs", REAL, COUNTRY);
- // ret &= add_condition("poor_tax", REAL, COUNTRY);
ret &= add_condition(
"prestige",
_parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
@@ -1984,18 +2233,14 @@ Returns true if the specified country exists. May also be used with [yes/no] to
_parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
_execute_condition_node_unimplemented
);
-/*
-relation
-Syntax:
-
-relation = { who = [tag/this/from] value = x }
-Use:
-Returns true if the specified country has a relation value equal to x or higher with the specified country.
-*/
- // ret &= add_condition("relation", COMPLEX, COUNTRY);
+ ret &= add_condition(
+ "relation",
+ _parse_condition_node_who_value_callback,
+ _execute_condition_node_unimplemented
+ );
ret &= add_condition(
"religion",
- _parse_condition_node_value_callback<Religion const*, POP>,
+ _parse_condition_node_value_callback<Religion const*, POP | THIS | FROM>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -2008,11 +2253,7 @@ Returns true if the specified country has a relation value equal to x or higher
_parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
_execute_condition_node_unimplemented
);
- // ret &= add_condition("rich_strata_militancy", REAL, COUNTRY);
- // ret &= add_condition("rich_strata_everyday_needs", REAL, COUNTRY);
- // ret &= add_condition("rich_strata_life_needs", REAL, COUNTRY);
- // ret &= add_condition("rich_strata_luxury_needs", REAL, COUNTRY);
- // ret &= add_condition("rich_tax", REAL, COUNTRY);
+ // Doesn't appear in vanilla or test mods
// ret &= add_condition("rich_tax_above_poor", BOOLEAN, COUNTRY);
ret &= add_condition(
"ruling_party",
@@ -2048,7 +2289,7 @@ Returns true if the specified country has a relation value equal to x or higher
);
ret &= add_condition(
"tag",
- _parse_condition_node_value_callback<CountryDefinition const*, COUNTRY>,
+ _parse_condition_node_value_callback<CountryDefinition const*, COUNTRY | THIS | FROM>,
_execute_condition_node_unimplemented
);
ret &= add_condition(
@@ -2056,15 +2297,13 @@ Returns true if the specified country has a relation value equal to x or higher
_parse_condition_node_value_callback<TechnologySchool const*, COUNTRY>,
_execute_condition_node_unimplemented
);
-/*
-this_culture_union *HOD ONLY*
-Syntax:
-
-this_culture_union = [country tag] / THIS / FROM / this_union
-Use:
-Returns true if the nation specified has the same cultural union as the country in scope.
-*/
- // ret &= add_condition("this_culture_union", IDENTIFIER, COUNTRY, NO_SCOPE, NO_IDENTIFIER, CULTURE_UNION);
+ ret &= add_condition(
+ "this_culture_union",
+ _parse_condition_node_value_callback<
+ CountryDefinition const*, COUNTRY | THIS | FROM, _parse_condition_node_special_callback_keyword<this_union_keyword>
+ >,
+ _execute_condition_node_unimplemented
+ );
ret &= add_condition(
"total_amount_of_divisions",
_parse_condition_node_value_callback<integer_t, COUNTRY>,
@@ -2094,6 +2333,11 @@ Returns true if the nation specified has the same cultural union as the country
// Doesn't show up or work in allow decision tooltips
// ret &= add_condition("total_sunk_by_us", INTEGER, COUNTRY);
ret &= add_condition(
+ "treasury",
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
"truce_with",
_parse_condition_node_value_callback<CountryDefinition const*, COUNTRY | THIS | FROM>,
_execute_condition_node_unimplemented
@@ -2110,19 +2354,11 @@ Returns true if the nation specified has the same cultural union as the country
_parse_condition_node_value_callback<bool, COUNTRY>,
_execute_condition_node_unimplemented
);
-/*
-upper_house
-Syntax:
-
-upper_house = {
- ideology = name
- value = 0.x
- }
-where value is a fraction 0.0 to 1.0, so value 0.4 = 40% has that ideology
-Use:
-Returns true if the country's upper house has the required characteristics
-*/
- // ret &= add_condition("upper_house", COMPLEX, COUNTRY);
+ ret &= add_condition(
+ "upper_house",
+ _parse_condition_node_value_callback<std::pair<Ideology const*, fixed_point_t>, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
ret &= add_condition(
"vassal_of",
_parse_condition_node_value_callback<CountryDefinition const*, COUNTRY | THIS | FROM>,
@@ -2150,88 +2386,316 @@ Returns true if the country's upper house has the required characteristics
);
/* State Scope Conditions */
- // ret &= add_condition("controlled_by", IDENTIFIER, STATE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
- // ret &= add_condition("empty", BOOLEAN, STATE);
- // ret &= add_condition("flashpoint_tension", REAL, STATE);
- // ret &= add_condition("has_building", IDENTIFIER, STATE, NO_SCOPE, NO_IDENTIFIER, BUILDING);
- // ret &= add_condition("has_factories", BOOLEAN, STATE);
- // ret &= add_condition("has_flashpoint", BOOLEAN, STATE);
- // ret &= add_condition("is_slave", BOOLEAN, STATE);
- // ret &= add_condition("owned_by", IDENTIFIER, STATE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
- // ret &= add_condition("trade_goods_in_state", IDENTIFIER, STATE, NO_SCOPE, NO_IDENTIFIER, TRADE_GOOD);
- // ret &= add_condition("work_available", COMPLEX, STATE);
+ ret &= add_condition(
+ "controlled_by",
+ _parse_condition_node_value_callback<
+ CountryDefinition const*, PROVINCE | THIS | FROM, _parse_condition_node_special_callback_keyword<owner_keyword>
+ >,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "empty",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "flashpoint_tension",
+ _parse_condition_node_value_callback<fixed_point_t, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_building",
+ _parse_condition_node_value_callback<
+ BuildingType const*, PROVINCE,
+ [](
+ Condition const& condition, DefinitionManager const& definition_manager, callback_t<argument_t&&> callback,
+ std::string_view str, bool& ret
+ ) -> bool {
+ if (
+ definition_manager.get_economy_manager().get_building_type_manager().get_building_type_types()
+ .contains(str)
+ ) {
+ ret = callback(std::string { str });
+ return true;
+ }
+
+ return false;
+ }
+ >,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_factories",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_flashpoint",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_slave",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "owned_by",
+ _parse_condition_node_value_callback<CountryDefinition const*, PROVINCE | THIS | FROM>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "trade_goods_in_state",
+ _parse_condition_node_value_callback<GoodDefinition const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "work_available",
+ _parse_condition_node_value_callback<std::vector<PopType const*>, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
/* Province Scope Conditions */
- // ret &= add_condition("can_build_factory", BOOLEAN, PROVINCE);
- // ret &= add_condition("controlled_by_rebels", BOOLEAN, PROVINCE);
- // ret &= add_condition("country_units_in_province", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
+ ret &= add_condition(
+ "can_build_factory",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "controlled_by_rebels",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "country_units_in_province",
+ _parse_condition_node_value_callback<CountryDefinition const*, PROVINCE | THIS | FROM>,
+ _execute_condition_node_unimplemented
+ );
+ // Doesn't appear in vanilla or any test mods
// ret &= add_condition("country_units_in_state", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
- // ret &= add_condition("has_crime", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, CRIME);
- // ret &= add_condition("has_culture_core", BOOLEAN, PROVINCE);
- // ret &= add_condition("has_empty_adjacent_province", BOOLEAN, PROVINCE);
+ ret &= add_condition(
+ "has_crime",
+ _parse_condition_node_value_callback<Crime const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_culture_core",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_empty_adjacent_province",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ // Doesn't appear in vanilla or any test mods
// ret &= add_condition("has_empty_adjacent_state", BOOLEAN, PROVINCE);
- // ret &= add_condition("has_national_minority", BOOLEAN, PROVINCE);
- // ret &= add_condition("has_province_flag", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, PROVINCE_FLAG);
- // ret &= add_condition("has_province_modifier", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, PROVINCE_EVENT_MODIFIER);
- // ret &= add_condition("has_recent_imigration", INTEGER, PROVINCE); //paradox typo
- // ret &= add_condition("is_blockaded", BOOLEAN, PROVINCE);
- // ret &= add_condition("is_accepted_culture", IDENTIFIER | BOOLEAN, PROVINCE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
- // ret &= add_condition("is_capital", BOOLEAN, PROVINCE);
- // ret &= add_condition("is_coastal", BOOLEAN, PROVINCE);
- // ret &= add_condition("is_overseas", BOOLEAN, PROVINCE);
- // ret &= add_condition("is_primary_culture", IDENTIFIER | BOOLEAN, PROVINCE, NO_SCOPE, NO_IDENTIFIER, COUNTRY_TAG);
- // ret &= add_condition("is_state_capital", BOOLEAN, PROVINCE);
- // ret &= add_condition("is_state_religion", BOOLEAN, PROVINCE);
- // ret &= add_condition("life_rating", REAL, PROVINCE);
- // ret &= add_condition("minorities", BOOLEAN, PROVINCE);
- // ret &= add_condition("port", BOOLEAN, PROVINCE);
- // ret &= add_condition("province_control_days", INTEGER, PROVINCE);
- // ret &= add_condition("province_id", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, PROVINCE_ID);
- // ret &= add_condition("region", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, REGION);
- // ret &= add_condition("state_id", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, PROVINCE_ID);
- // ret &= add_condition("terrain", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, TERRAIN);
- // ret &= add_condition("trade_goods", IDENTIFIER, PROVINCE, NO_SCOPE, NO_IDENTIFIER, TRADE_GOOD);
- // ret &= add_condition("unemployment_by_type", COMPLEX, PROVINCE);
- // ret &= add_condition("units_in_province", INTEGER, PROVINCE);
+ ret &= add_condition(
+ "has_national_minority",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_province_flag",
+ _parse_condition_node_value_callback<std::string, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_province_modifier",
+ // TODO - parse as Modifier const*? Depends what types of modifiers can go here
+ _parse_condition_node_value_callback<std::string, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "has_recent_imigration", // paradox typo
+ _parse_condition_node_value_callback<integer_t, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_blockaded",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_accepted_culture",
+ _parse_condition_node_value_callback<
+ CountryDefinition const*, PROVINCE | POP | THIS | FROM, _parse_condition_node_special_callback_bool
+ >,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_capital",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_coastal",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_overseas",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_primary_culture",
+ _parse_condition_node_value_callback<
+ CountryDefinition const*, PROVINCE | POP | THIS | FROM, _parse_condition_node_special_callback_bool
+ >,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_state_capital",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "is_state_religion",
+ _parse_condition_node_value_callback<bool, PROVINCE | POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "life_rating",
+ _parse_condition_node_value_callback<fixed_point_t, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "minorities",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "port",
+ _parse_condition_node_value_callback<bool, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "province_control_days",
+ _parse_condition_node_value_callback<integer_t, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "province_id",
+ _parse_condition_node_value_callback<ProvinceDefinition const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "region",
+ _parse_condition_node_value_callback<Region const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "state_id",
+ _parse_condition_node_value_callback<ProvinceDefinition const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "terrain",
+ _parse_condition_node_value_callback<TerrainType const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "trade_goods",
+ _parse_condition_node_value_callback<GoodDefinition const*, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "unemployment_by_type",
+ _parse_condition_node_value_callback<std::pair<PopType const*, fixed_point_t>, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "units_in_province",
+ _parse_condition_node_value_callback<integer_t, PROVINCE>,
+ _execute_condition_node_unimplemented
+ );
/* Pop Scope Conditions */
- // ret &= add_condition("agree_with_ruling_party", REAL, POP);
- // ret &= add_condition("cash_reserves", REAL, POP);
- // ret &= add_condition("everyday_needs", REAL, POP);
- // ret &= add_condition("life_needs", REAL, POP);
- // ret &= add_condition("luxury_needs", REAL, POP);
- // ret &= add_condition("political_movement", BOOLEAN, POP);
+ ret &= add_condition(
+ "agree_with_ruling_party",
+ _parse_condition_node_value_callback<fixed_point_t, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "cash_reserves",
+ _parse_condition_node_value_callback<fixed_point_t, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "life_needs",
+ _parse_condition_node_value_callback<fixed_point_t, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "everyday_needs",
+ _parse_condition_node_value_callback<fixed_point_t, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "luxury_needs",
+ _parse_condition_node_value_callback<fixed_point_t, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "political_movement",
+ _parse_condition_node_value_callback<bool, POP>,
+ _execute_condition_node_unimplemented
+ );
+ // Doesn't appear in vanilla or any test mods
// ret &= add_condition("pop_majority_issue", IDENTIFIER, POP, NO_SCOPE, NO_IDENTIFIER, ISSUE);
- // ret &= add_condition("pop_type", IDENTIFIER, POP, NO_SCOPE, NO_IDENTIFIER, POP_TYPE);
- // ret &= add_condition("social_movement", BOOLEAN, POP);
- // ret &= add_condition("strata", IDENTIFIER, POP, NO_SCOPE, NO_IDENTIFIER, POP_STRATA);
- // ret &= add_condition("type", IDENTIFIER, POP, NO_SCOPE, NO_IDENTIFIER, POP_TYPE);
-
- // const auto import_identifiers = [this, &ret](
- // std::vector<std::string_view> const& identifiers,
- // value_type_t value_type,
- // 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 {
- // for (std::string_view const& identifier : identifiers) {
- // ret &= add_condition(
- // identifier, value_type, scope, scope_change,
- // key_identifier_type, value_identifier_type
- // );
- // }
- // };
+ ret &= add_condition(
+ "pop_type",
+ _parse_condition_node_value_callback<PopType const*, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "social_movement",
+ _parse_condition_node_value_callback<bool, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "strata",
+ _parse_condition_node_value_callback<Strata const*, POP>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ "type",
+ _parse_condition_node_value_callback<PopType const*, POP>,
+ _execute_condition_node_unimplemented
+ );
+
+ for (Strata const& strata : definition_manager.get_pop_manager().get_stratas()) {
+ const std::string_view identifier = strata.get_identifier();
+
+ ret &= add_condition(
+ StringUtils::append_string_views(identifier, "_tax"),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ StringUtils::append_string_views(identifier, "_strata_life_needs"),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ StringUtils::append_string_views(identifier, "_strata_everyday_needs"),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ StringUtils::append_string_views(identifier, "_strata_luxury_needs"),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ ret &= add_condition(
+ StringUtils::append_string_views(identifier, "_strata_militancy"),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
/* Scopes from other registries */
- // import_identifiers(
- // definition_manager.get_country_definition_manager().get_country_definition_identifiers(),
- // GROUP,
- // COUNTRY,
- // COUNTRY,
- // COUNTRY_TAG,
- // NO_IDENTIFIER
- // );
for (CountryDefinition const& country : definition_manager.get_country_definition_manager().get_country_definitions()) {
ret &= add_condition(
country.get_identifier(),
@@ -2247,23 +2711,32 @@ Returns true if the country's upper house has the required characteristics
);
}
- // import_identifiers(
- // definition_manager.get_map_definition().get_region_identifiers(),
- // GROUP,
- // COUNTRY,
- // STATE,
- // REGION,
- // NO_IDENTIFIER
- // );
-
- // import_identifiers(
- // definition_manager.get_map_definition().get_province_definition_identifiers(),
- // GROUP,
- // COUNTRY,
- // PROVINCE,
- // PROVINCE_ID,
- // NO_IDENTIFIER
- // );
+ for (Region const& region : definition_manager.get_map_definition().get_regions()) {
+ ret &= add_condition(
+ region.get_identifier(),
+ _parse_condition_node_list_callback<PROVINCE>,
+ _execute_condition_node_list_multi_scope_callback<expect_true, require_all>(
+ [&region](
+ Condition const& condition, InstanceManager const& instance_manager, scope_t const& current_scope,
+ scope_t const& this_scope, scope_t const& from_scope
+ ) -> std::vector<scope_t> {
+ std::vector<ProvinceDefinition const*> const& region_provinces = region.get_provinces();
+
+ std::vector<scope_t> region_province_scopes;
+ region_province_scopes.reserve(region_provinces.size());
+
+ for (ProvinceDefinition const* province : region_provinces) {
+ region_province_scopes.push_back(
+ &instance_manager.get_map_instance().get_province_instance_from_definition(*province)
+ );
+ }
+
+ return region_province_scopes;
+ }
+ )
+ );
+ }
+
for (ProvinceDefinition const& province : definition_manager.get_map_definition().get_province_definitions()) {
ret &= add_condition(
province.get_identifier(),
@@ -2280,41 +2753,29 @@ Returns true if the country's upper house has the required characteristics
}
/* Conditions from other registries */
- // import_identifiers(
- // definition_manager.get_politics_manager().get_ideology_manager().get_ideology_identifiers(),
- // REAL,
- // COUNTRY,
- // NO_SCOPE,
- // IDEOLOGY,
- // NO_IDENTIFIER
- // );
-
- // import_identifiers(
- // definition_manager.get_politics_manager().get_issue_manager().get_reform_group_identifiers(),
- // IDENTIFIER,
- // COUNTRY,
- // NO_SCOPE,
- // REFORM_GROUP,
- // REFORM
- // );
-
- // import_identifiers(
- // definition_manager.get_politics_manager().get_issue_manager().get_reform_identifiers(),
- // REAL,
- // COUNTRY,
- // NO_SCOPE,
- // REFORM,
- // NO_IDENTIFIER
- // );
-
- // import_identifiers(
- // definition_manager.get_politics_manager().get_issue_manager().get_issue_identifiers(),
- // REAL,
- // COUNTRY,
- // NO_SCOPE,
- // ISSUE,
- // NO_IDENTIFIER
- // );
+ for (Ideology const& ideology : definition_manager.get_politics_manager().get_ideology_manager().get_ideologies()) {
+ ret &= add_condition(
+ ideology.get_identifier(),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
+
+ for (ReformGroup const& reform_group : definition_manager.get_politics_manager().get_issue_manager().get_reform_groups()) {
+ ret &= add_condition(
+ reform_group.get_identifier(),
+ _parse_condition_node_value_callback<Reform const*, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
+
+ for (Reform const& reform : definition_manager.get_politics_manager().get_issue_manager().get_reforms()) {
+ ret &= add_condition(
+ reform.get_identifier(),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
for (IssueGroup const& issue_group : definition_manager.get_politics_manager().get_issue_manager().get_issue_groups()) {
ret &= add_condition(
@@ -2339,32 +2800,43 @@ Returns true if the country's upper house has the required characteristics
);
}
- // import_identifiers(
- // definition_manager.get_pop_manager().get_pop_type_identifiers(),
- // REAL,
- // COUNTRY,
- // NO_SCOPE,
- // POP_TYPE,
- // NO_IDENTIFIER
- // );
-
- // import_identifiers(
- // definition_manager.get_research_manager().get_technology_manager().get_technology_identifiers(),
- // BOOLEAN_INT,
- // COUNTRY,
- // NO_SCOPE,
- // TECHNOLOGY,
- // NO_IDENTIFIER
- // );
-
- // import_identifiers(
- // definition_manager.get_economy_manager().get_good_definition_manager().get_good_definition_identifiers(),
- // INTEGER,
- // COUNTRY,
- // NO_SCOPE,
- // TRADE_GOOD,
- // NO_IDENTIFIER
- // );
+ for (Issue const& issue : definition_manager.get_politics_manager().get_issue_manager().get_issues()) {
+ ret &= add_condition(
+ issue.get_identifier(),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
+
+ for (PopType const& pop_type : definition_manager.get_pop_manager().get_pop_types()) {
+ ret &= add_condition(
+ pop_type.get_identifier(),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
+
+ for (
+ Technology const& technology : definition_manager.get_research_manager().get_technology_manager().get_technologies()
+ ) {
+ ret &= add_condition(
+ technology.get_identifier(),
+ // TODO - Could convert integer to bool?
+ _parse_condition_node_value_callback<integer_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
+
+ for (
+ GoodDefinition const& good :
+ definition_manager.get_economy_manager().get_good_definition_manager().get_good_definitions()
+ ) {
+ ret &= add_condition(
+ good.get_identifier(),
+ _parse_condition_node_value_callback<fixed_point_t, COUNTRY>,
+ _execute_condition_node_unimplemented
+ );
+ }
if (
add_condition(
diff --git a/src/openvic-simulation/scripts/Condition.hpp b/src/openvic-simulation/scripts/Condition.hpp
index 0acdcc3..78d1b6d 100644
--- a/src/openvic-simulation/scripts/Condition.hpp
+++ b/src/openvic-simulation/scripts/Condition.hpp
@@ -59,12 +59,11 @@ namespace OpenVic {
NO_SCOPE = 0,
POP = 1 << 0,
PROVINCE = 1 << 1,
- STATE = 1 << 2,
- COUNTRY = 1 << 3,
- THIS = 1 << 4, // Indicator bit for scope switching ("use the THIS scope", not a scope in and of itself)
- FROM = 1 << 5, // Indicator bit for scope switching ("use the FROM scope", not a scope in and of itself)
- FULL_SCOPE_MASK = (1 << 6) - 1, // All possible scope bits (including THIS and FROM)
- ALL_SCOPES = POP | PROVINCE | STATE | COUNTRY // All real scopes (without THIS and FROM)
+ COUNTRY = 1 << 2,
+ THIS = 1 << 3, // Indicator bit for scope switching ("use the THIS scope", not a scope in and of itself)
+ FROM = 1 << 4, // Indicator bit for scope switching ("use the FROM scope", not a scope in and of itself)
+ FULL_SCOPE_MASK = (1 << 5) - 1, // All possible scope bits (including THIS and FROM)
+ ALL_SCOPES = POP | PROVINCE | COUNTRY // All real scopes (without THIS and FROM)
};
/* Allows enum types to be used with bitwise operators. */
@@ -96,10 +95,9 @@ namespace OpenVic {
stream << '[';
- BUILD_STRING(COUNTRY);
- BUILD_STRING(STATE);
- BUILD_STRING(PROVINCE);
BUILD_STRING(POP);
+ BUILD_STRING(PROVINCE);
+ BUILD_STRING(COUNTRY);
BUILD_STRING(THIS);
BUILD_STRING(FROM);
@@ -116,7 +114,6 @@ namespace OpenVic {
struct ConditionScript;
struct CountryDefinition;
struct CountryInstance;
- struct State;
struct ProvinceDefinition;
struct ProvinceInstance;
struct Pop;
@@ -127,6 +124,7 @@ namespace OpenVic {
struct Issue;
struct WargoalType;
struct PopType;
+ struct CultureGroup;
struct Culture;
struct Religion;
struct GovernmentType;
@@ -135,6 +133,10 @@ namespace OpenVic {
struct NationalValue;
struct Invention;
struct TechnologySchool;
+ struct Crime;
+ struct Region;
+ struct TerrainType;
+ struct Strata;
struct Condition;
struct DefinitionManager;
struct InstanceManager;
@@ -149,20 +151,29 @@ namespace OpenVic {
struct no_argument_t {};
struct this_argument_t {};
struct from_argument_t {};
+ struct special_argument_t {};
using integer_t = int64_t;
using argument_t = std::variant<
// No argument
no_argument_t,
// Script reference arguments
this_argument_t, from_argument_t,
+ // Special argument
+ special_argument_t,
// List argument
std::vector<ConditionNode>,
// Value arguments
bool, std::string, integer_t, fixed_point_t,
// Game object arguments
CountryDefinition const*, ProvinceDefinition const*, GoodDefinition const*, Continent const*, BuildingType const*,
- Issue const*, WargoalType const*, PopType const*, Culture const*, Religion const*, GovernmentType const*,
- Ideology const*, Reform const*, NationalValue const*, Invention const*, TechnologySchool const*
+ Issue const*, WargoalType const*, PopType const*, CultureGroup const*, Culture const*, Religion const*,
+ GovernmentType const*, Ideology const*, Reform const*, NationalValue const*, Invention const*,
+ TechnologySchool const*, Crime const*, Region const*, TerrainType const*, Strata const*,
+ // Multi-value arguments
+ std::pair<PopType const*, fixed_point_t>, std::pair<bool, bool>, std::pair<Ideology const*, fixed_point_t>,
+ std::vector<PopType const*>, std::pair<CountryDefinition const*, fixed_point_t>,
+ std::pair<this_argument_t, fixed_point_t>, std::pair<from_argument_t, fixed_point_t>,
+ std::pair<std::string, fixed_point_t>
>;
static constexpr bool is_this_argument(argument_t const& argument) {
@@ -173,11 +184,14 @@ namespace OpenVic {
return std::holds_alternative<from_argument_t>(argument);
}
+ static constexpr bool is_special_argument(argument_t const& argument) {
+ return std::holds_alternative<special_argument_t>(argument);
+ }
+
struct no_scope_t {};
using scope_t = std::variant<
no_scope_t,
CountryInstance const*,
- State const*, // Should State scope exist, or should it just be a list of provinces?
ProvinceInstance const*,
Pop const*
>;
@@ -208,6 +222,8 @@ namespace OpenVic {
) const;
};
+ std::ostream& operator<<(std::ostream& stream, ConditionNode const& node);
+
struct Condition : HasIdentifier {
friend struct ConditionManager;
@@ -279,6 +295,9 @@ namespace OpenVic {
bool setup_conditions(DefinitionManager const& definition_manager);
+ // TODO - way to call with a state as the starting scope (or rather the list of provinces making up a state)
+ // For: ProductionType bonus trigger, WargoalType allowed_states, allowed_substate_regions and allowed_states_in_crisis
+
NodeTools::node_callback_t expect_condition_script(
DefinitionManager const& definition_manager, scope_type_t initial_scope, scope_type_t this_scope,
scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback
diff --git a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
index 7752226..bc74d1c 100644
--- a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
+++ b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
@@ -38,6 +38,11 @@ namespace OpenVic {
#include "openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp"
static_assert(SIN_LUT_PRECISION == PRECISION);
+
+ // Doesn't account for sign, so -n.abc -> 1 - 0.abc
+ constexpr fixed_point_t get_frac() const {
+ return value & FRAC_MASK;
+ }
public:
constexpr fixed_point_t() : value { 0 } {}
@@ -74,110 +79,22 @@ namespace OpenVic {
return 2;
}
- static constexpr fixed_point_t _3() {
- return 3;
- }
-
static constexpr fixed_point_t _4() {
return 4;
}
- static constexpr fixed_point_t _5() {
- return 5;
- }
-
- static constexpr fixed_point_t _6() {
- return 6;
- }
-
- static constexpr fixed_point_t _7() {
- return 7;
- }
-
- static constexpr fixed_point_t _8() {
- return 8;
- }
-
- static constexpr fixed_point_t _9() {
- return 9;
- }
-
- static constexpr fixed_point_t _10() {
- return 10;
- }
-
- static constexpr fixed_point_t _50() {
- return 50;
- }
-
static constexpr fixed_point_t _100() {
return 100;
}
- static constexpr fixed_point_t _200() {
- return 200;
- }
-
- static constexpr fixed_point_t _0_01() {
- return _1() / _100();
- }
-
- static constexpr fixed_point_t _0_02() {
- return _0_01() * 2;
- }
-
- static constexpr fixed_point_t _0_03() {
- return _0_01() * 3;
- }
-
- static constexpr fixed_point_t _0_04() {
- return _0_01() * 4;
- }
-
- static constexpr fixed_point_t _0_05() {
- return _0_01() * 5;
- }
-
- static constexpr fixed_point_t _0_10() {
- return _1() / 10;
- }
-
static constexpr fixed_point_t _0_20() {
- return _0_10() * 2;
- }
-
- static constexpr fixed_point_t _0_25() {
- return _1() / 4;
- }
-
- static constexpr fixed_point_t _0_33() {
- return _1() / 3;
+ return _1() / 5;
}
static constexpr fixed_point_t _0_50() {
return _1() / 2;
}
- static constexpr fixed_point_t _0_75() {
- return _1() - _0_25();
- }
-
- static constexpr fixed_point_t _0_95() {
- return _1() - _0_05();
- }
-
- static constexpr fixed_point_t _0_99() {
- return _1() - _0_01();
- }
-
- static constexpr fixed_point_t _1_01() {
- return _1() + _0_01();
- }
-
- static constexpr fixed_point_t _1_10() {
- return _1() + _0_10();
- }
-
static constexpr fixed_point_t _1_50() {
return _1() + _0_50();
}
@@ -253,11 +170,6 @@ namespace OpenVic {
: 0;
}
- // Doesn't account for sign, so -n.abc -> 1 - 0.abc
- constexpr fixed_point_t get_frac() const {
- return value & FRAC_MASK;
- }
-
constexpr bool is_integer() const {
return get_frac() == 0;
}