aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation')
-rw-r--r--src/openvic-simulation/DefinitionManager.hpp2
-rw-r--r--src/openvic-simulation/economy/BuildingType.cpp11
-rw-r--r--src/openvic-simulation/economy/BuildingType.hpp4
-rw-r--r--src/openvic-simulation/economy/EconomyManager.hpp5
-rw-r--r--src/openvic-simulation/economy/GoodDefinition.cpp38
-rw-r--r--src/openvic-simulation/economy/GoodDefinition.hpp2
-rw-r--r--src/openvic-simulation/economy/production/ArtisanalProducer.cpp (renamed from src/openvic-simulation/economy/ArtisanalProducer.cpp)0
-rw-r--r--src/openvic-simulation/economy/production/ArtisanalProducer.hpp (renamed from src/openvic-simulation/economy/ArtisanalProducer.hpp)8
-rw-r--r--src/openvic-simulation/economy/production/FactoryProducer.cpp (renamed from src/openvic-simulation/economy/FactoryProducer.cpp)0
-rw-r--r--src/openvic-simulation/economy/production/FactoryProducer.hpp (renamed from src/openvic-simulation/economy/FactoryProducer.hpp)27
-rw-r--r--src/openvic-simulation/economy/production/ProductionType.cpp (renamed from src/openvic-simulation/economy/ProductionType.cpp)0
-rw-r--r--src/openvic-simulation/economy/production/ProductionType.hpp (renamed from src/openvic-simulation/economy/ProductionType.hpp)0
-rw-r--r--src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp (renamed from src/openvic-simulation/economy/ResourceGatheringOperation.cpp)0
-rw-r--r--src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp (renamed from src/openvic-simulation/economy/ResourceGatheringOperation.hpp)9
-rw-r--r--src/openvic-simulation/map/Crime.cpp12
-rw-r--r--src/openvic-simulation/map/Crime.hpp4
-rw-r--r--src/openvic-simulation/map/MapDefinition.cpp40
-rw-r--r--src/openvic-simulation/map/MapDefinition.hpp9
-rw-r--r--src/openvic-simulation/map/Region.cpp12
-rw-r--r--src/openvic-simulation/map/Region.hpp4
-rw-r--r--src/openvic-simulation/map/TerrainType.cpp22
-rw-r--r--src/openvic-simulation/map/TerrainType.hpp2
-rw-r--r--src/openvic-simulation/military/LeaderTrait.cpp2
-rw-r--r--src/openvic-simulation/military/LeaderTrait.hpp2
-rw-r--r--src/openvic-simulation/military/UnitType.cpp45
-rw-r--r--src/openvic-simulation/military/UnitType.hpp2
-rw-r--r--src/openvic-simulation/modifier/Modifier.cpp (renamed from src/openvic-simulation/misc/Modifier.cpp)355
-rw-r--r--src/openvic-simulation/modifier/Modifier.hpp (renamed from src/openvic-simulation/misc/Modifier.hpp)57
-rw-r--r--src/openvic-simulation/modifier/ModifierSum.cpp58
-rw-r--r--src/openvic-simulation/modifier/ModifierSum.hpp30
-rw-r--r--src/openvic-simulation/politics/Issue.cpp26
-rw-r--r--src/openvic-simulation/politics/Issue.hpp6
-rw-r--r--src/openvic-simulation/politics/NationalFocus.cpp60
-rw-r--r--src/openvic-simulation/politics/NationalFocus.hpp16
-rw-r--r--src/openvic-simulation/politics/NationalValue.cpp2
-rw-r--r--src/openvic-simulation/politics/NationalValue.hpp2
-rw-r--r--src/openvic-simulation/politics/Rebel.cpp13
-rw-r--r--src/openvic-simulation/politics/Rebel.hpp2
-rw-r--r--src/openvic-simulation/politics/Rule.cpp84
-rw-r--r--src/openvic-simulation/politics/Rule.hpp15
-rw-r--r--src/openvic-simulation/pop/Pop.cpp10
-rw-r--r--src/openvic-simulation/pop/Pop.hpp2
-rw-r--r--src/openvic-simulation/research/Invention.cpp6
-rw-r--r--src/openvic-simulation/research/Invention.hpp2
-rw-r--r--src/openvic-simulation/research/Technology.cpp12
-rw-r--r--src/openvic-simulation/research/Technology.hpp2
-rw-r--r--src/openvic-simulation/types/HasIdentifier.hpp3
-rw-r--r--src/openvic-simulation/types/IndexedMap.hpp2
-rw-r--r--src/openvic-simulation/utility/StringUtils.hpp16
49 files changed, 725 insertions, 318 deletions
diff --git a/src/openvic-simulation/DefinitionManager.hpp b/src/openvic-simulation/DefinitionManager.hpp
index f38beb0..887cc1b 100644
--- a/src/openvic-simulation/DefinitionManager.hpp
+++ b/src/openvic-simulation/DefinitionManager.hpp
@@ -12,9 +12,9 @@
#include "openvic-simulation/misc/Decision.hpp"
#include "openvic-simulation/misc/Define.hpp"
#include "openvic-simulation/misc/Event.hpp"
-#include "openvic-simulation/misc/Modifier.hpp"
#include "openvic-simulation/misc/SongChance.hpp"
#include "openvic-simulation/misc/SoundEffect.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/politics/PoliticsManager.hpp"
#include "openvic-simulation/pop/Pop.hpp"
#include "openvic-simulation/research/ResearchManager.hpp"
diff --git a/src/openvic-simulation/economy/BuildingType.cpp b/src/openvic-simulation/economy/BuildingType.cpp
index f0fc8a8..e7c0d59 100644
--- a/src/openvic-simulation/economy/BuildingType.cpp
+++ b/src/openvic-simulation/economy/BuildingType.cpp
@@ -5,7 +5,7 @@ using namespace OpenVic::NodeTools;
BuildingType::BuildingType(
std::string_view identifier, building_type_args_t& building_type_args
-) : Modifier { identifier, std::move(building_type_args.modifier) },
+) : Modifier { identifier, std::move(building_type_args.modifier), modifier_type_t::BUILDING },
type { building_type_args.type },
on_completion { building_type_args.on_completion },
completion_size { building_type_args.completion_size },
@@ -113,13 +113,17 @@ bool BuildingTypeManager::load_buildings_file(
lock_building_types();
for (BuildingType const& building_type : building_types.get_items()) {
+ using enum ModifierEffect::format_t;
+
static constexpr std::string_view max_prefix = "max_";
static constexpr std::string_view min_prefix = "min_build_";
ret &= modifier_manager.add_modifier_effect(
- StringUtils::append_string_views(max_prefix, building_type.get_identifier()), true, ModifierEffect::format_t::INT
+ StringUtils::append_string_views(max_prefix, building_type.get_identifier()), true, INT,
+ StringUtils::append_string_views("$", building_type.get_identifier(), "$ $TECH_MAX_LEVEL$")
);
+ // TODO - add custom localisation for "min_build_$building_type$" modifiers
ret &= modifier_manager.add_modifier_effect(
- StringUtils::append_string_views(min_prefix, building_type.get_identifier()), false, ModifierEffect::format_t::INT
+ StringUtils::append_string_views(min_prefix, building_type.get_identifier()), false, INT
);
if (building_type.is_in_province()) {
@@ -150,6 +154,7 @@ bool BuildingTypeManager::load_buildings_file(
Logger::error("No port building type found!");
ret = false;
}
+
if (province_building_types.empty()) {
Logger::error("No province building types found!");
ret = false;
diff --git a/src/openvic-simulation/economy/BuildingType.hpp b/src/openvic-simulation/economy/BuildingType.hpp
index ab999cd..b8cfecf 100644
--- a/src/openvic-simulation/economy/BuildingType.hpp
+++ b/src/openvic-simulation/economy/BuildingType.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
#include "openvic-simulation/economy/GoodDefinition.hpp"
-#include "openvic-simulation/economy/ProductionType.hpp"
+#include "openvic-simulation/economy/production/ProductionType.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
diff --git a/src/openvic-simulation/economy/EconomyManager.hpp b/src/openvic-simulation/economy/EconomyManager.hpp
index 2464912..5257e6a 100644
--- a/src/openvic-simulation/economy/EconomyManager.hpp
+++ b/src/openvic-simulation/economy/EconomyManager.hpp
@@ -1,9 +1,10 @@
#pragma once
+#include <openvic-dataloader/v2script/Parser.hpp>
+
#include "openvic-simulation/economy/BuildingType.hpp"
#include "openvic-simulation/economy/GoodDefinition.hpp"
-#include "openvic-simulation/economy/ProductionType.hpp"
-#include "openvic-dataloader/v2script/Parser.hpp"
+#include "openvic-simulation/economy/production/ProductionType.hpp"
namespace OpenVic {
struct EconomyManager {
diff --git a/src/openvic-simulation/economy/GoodDefinition.cpp b/src/openvic-simulation/economy/GoodDefinition.cpp
index f21ea18..ed24549 100644
--- a/src/openvic-simulation/economy/GoodDefinition.cpp
+++ b/src/openvic-simulation/economy/GoodDefinition.cpp
@@ -88,30 +88,40 @@ bool GoodDefinitionManager::load_goods_file(ast::NodeCPtr root) {
}
bool GoodDefinitionManager::generate_modifiers(ModifierManager& modifier_manager) const {
+ using enum ModifierEffect::format_t;
+
bool ret = true;
- const auto good_modifier = [this, &modifier_manager, &ret](std::string_view name, bool is_positive_good) -> void {
+ const auto good_modifier = [this, &modifier_manager, &ret](
+ std::string_view name, bool is_positive_good, auto make_localisation_suffix
+ ) -> void {
ret &= modifier_manager.register_complex_modifier(name);
+
for (GoodDefinition const& good : get_good_definitions()) {
ret &= modifier_manager.add_modifier_effect(
- ModifierManager::get_flat_identifier(name, good.get_identifier()), is_positive_good
+ ModifierManager::get_flat_identifier(name, good.get_identifier()), is_positive_good, PROPORTION_DECIMAL,
+ make_localisation_suffix(good.get_identifier())
);
}
};
- good_modifier("artisan_goods_input", false);
- good_modifier("artisan_goods_output", true);
- good_modifier("artisan_goods_throughput", true);
- good_modifier("factory_goods_input", false);
- good_modifier("factory_goods_output", true);
- good_modifier("factory_goods_throughput", true);
- good_modifier("rgo_goods_output", true);
- good_modifier("rgo_goods_throughput", true);
- good_modifier("rgo_size", true);
+ const auto make_production_localisation_suffix = [](std::string_view localisation_suffix) -> auto {
+ return [localisation_suffix](std::string_view good_identifier) -> std::string {
+ return StringUtils::append_string_views("$", good_identifier, "$ $", localisation_suffix, "$");
+ };
+ };
- for (GoodDefinition const& good : get_good_definitions()) {
- ret &= modifier_manager.add_modifier_effect(good.get_identifier(), true, ModifierEffect::format_t::PERCENTAGE_DECIMAL);
- }
+ good_modifier("artisan_goods_input", false, make_production_localisation_suffix("TECH_INPUT"));
+ good_modifier("artisan_goods_output", true, make_production_localisation_suffix("TECH_OUTPUT"));
+ good_modifier("artisan_goods_throughput", true, make_production_localisation_suffix("TECH_THROUGHPUT"));
+ good_modifier("factory_goods_input", false, make_production_localisation_suffix("TECH_INPUT"));
+ good_modifier("factory_goods_output", true, make_production_localisation_suffix("TECH_OUTPUT"));
+ good_modifier("factory_goods_throughput", true, make_production_localisation_suffix("TECH_THROUGHPUT"));
+ good_modifier("rgo_goods_output", true, make_production_localisation_suffix("TECH_OUTPUT"));
+ good_modifier("rgo_goods_throughput", true, make_production_localisation_suffix("TECH_THROUGHPUT"));
+ good_modifier("rgo_size", true, [](std::string_view good_identifier) -> std::string {
+ return StringUtils::append_string_views(good_identifier, "_RGO_SIZE");
+ });
return ret;
}
diff --git a/src/openvic-simulation/economy/GoodDefinition.hpp b/src/openvic-simulation/economy/GoodDefinition.hpp
index 15eb4e8..bc231cb 100644
--- a/src/openvic-simulation/economy/GoodDefinition.hpp
+++ b/src/openvic-simulation/economy/GoodDefinition.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
namespace OpenVic {
diff --git a/src/openvic-simulation/economy/ArtisanalProducer.cpp b/src/openvic-simulation/economy/production/ArtisanalProducer.cpp
index d5cc3d3..d5cc3d3 100644
--- a/src/openvic-simulation/economy/ArtisanalProducer.cpp
+++ b/src/openvic-simulation/economy/production/ArtisanalProducer.cpp
diff --git a/src/openvic-simulation/economy/ArtisanalProducer.hpp b/src/openvic-simulation/economy/production/ArtisanalProducer.hpp
index ed5b231..e5c0b80 100644
--- a/src/openvic-simulation/economy/ArtisanalProducer.hpp
+++ b/src/openvic-simulation/economy/production/ArtisanalProducer.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "openvic-simulation/economy/GoodDefinition.hpp"
-#include "openvic-simulation/economy/ProductionType.hpp"
+#include "openvic-simulation/economy/production/ProductionType.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/utility/Getters.hpp"
@@ -15,10 +15,8 @@ namespace OpenVic {
public:
ArtisanalProducer(
- ProductionType const& new_production_type,
- GoodDefinition::good_definition_map_t&& new_stockpile,
- fixed_point_t new_current_production,
- GoodDefinition::good_definition_map_t&& new_current_needs
+ ProductionType const& new_production_type, GoodDefinition::good_definition_map_t&& new_stockpile,
+ fixed_point_t new_current_production, GoodDefinition::good_definition_map_t&& new_current_needs
);
};
}
diff --git a/src/openvic-simulation/economy/FactoryProducer.cpp b/src/openvic-simulation/economy/production/FactoryProducer.cpp
index 2ef9fa8..2ef9fa8 100644
--- a/src/openvic-simulation/economy/FactoryProducer.cpp
+++ b/src/openvic-simulation/economy/production/FactoryProducer.cpp
diff --git a/src/openvic-simulation/economy/FactoryProducer.hpp b/src/openvic-simulation/economy/production/FactoryProducer.hpp
index ee658a5..54ddfb8 100644
--- a/src/openvic-simulation/economy/FactoryProducer.hpp
+++ b/src/openvic-simulation/economy/production/FactoryProducer.hpp
@@ -3,7 +3,7 @@
#include <cstdint>
#include "openvic-simulation/economy/GoodDefinition.hpp"
-#include "openvic-simulation/economy/ProductionType.hpp"
+#include "openvic-simulation/economy/production/ProductionType.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/utility/Getters.hpp"
@@ -34,24 +34,13 @@ namespace OpenVic {
public:
FactoryProducer(
- ProductionType const& new_production_type,
- fixed_point_t new_size_multiplier,
- fixed_point_t new_revenue_yesterday,
- fixed_point_t new_output_quantity_yesterday,
- fixed_point_t new_unsold_quantity_yesterday,
- ordered_map<Pop*, Pop::pop_size_t>&& new_employees,
- GoodDefinition::good_definition_map_t&& new_stockpile,
- fixed_point_t new_budget,
- fixed_point_t new_balance_yesterday,
- fixed_point_t new_received_investments_yesterday,
- fixed_point_t new_market_spendings_yesterday,
- fixed_point_t new_paychecks_yesterday,
- uint32_t new_unprofitable_days,
- uint32_t new_subsidised_days,
- uint32_t new_days_without_input,
- uint8_t new_hiring_priority,
- uint8_t new_profit_history_current,
- daily_profit_history_t&& new_daily_profit_history
+ ProductionType const& new_production_type, fixed_point_t new_size_multiplier, fixed_point_t new_revenue_yesterday,
+ fixed_point_t new_output_quantity_yesterday, fixed_point_t new_unsold_quantity_yesterday,
+ ordered_map<Pop*, Pop::pop_size_t>&& new_employees, GoodDefinition::good_definition_map_t&& new_stockpile,
+ fixed_point_t new_budget, fixed_point_t new_balance_yesterday, fixed_point_t new_received_investments_yesterday,
+ fixed_point_t new_market_spendings_yesterday, fixed_point_t new_paychecks_yesterday, uint32_t new_unprofitable_days,
+ uint32_t new_subsidised_days, uint32_t new_days_without_input, uint8_t new_hiring_priority,
+ uint8_t new_profit_history_current, daily_profit_history_t&& new_daily_profit_history
);
FactoryProducer(ProductionType const& new_production_type, fixed_point_t new_size_multiplier);
diff --git a/src/openvic-simulation/economy/ProductionType.cpp b/src/openvic-simulation/economy/production/ProductionType.cpp
index 65f3eba..65f3eba 100644
--- a/src/openvic-simulation/economy/ProductionType.cpp
+++ b/src/openvic-simulation/economy/production/ProductionType.cpp
diff --git a/src/openvic-simulation/economy/ProductionType.hpp b/src/openvic-simulation/economy/production/ProductionType.hpp
index 5394938..5394938 100644
--- a/src/openvic-simulation/economy/ProductionType.hpp
+++ b/src/openvic-simulation/economy/production/ProductionType.hpp
diff --git a/src/openvic-simulation/economy/ResourceGatheringOperation.cpp b/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp
index 9bf6f49..9bf6f49 100644
--- a/src/openvic-simulation/economy/ResourceGatheringOperation.cpp
+++ b/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp
diff --git a/src/openvic-simulation/economy/ResourceGatheringOperation.hpp b/src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp
index 73b4261..d71c569 100644
--- a/src/openvic-simulation/economy/ResourceGatheringOperation.hpp
+++ b/src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/economy/ProductionType.hpp"
+#include "openvic-simulation/economy/production/ProductionType.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/utility/Getters.hpp"
@@ -16,11 +16,8 @@ namespace OpenVic {
public:
ResourceGatheringOperation(
- ProductionType const& new_production_type,
- fixed_point_t new_size_multiplier,
- fixed_point_t new_revenue_yesterday,
- fixed_point_t new_output_quantity_yesterday,
- fixed_point_t new_unsold_quantity_yesterday,
+ ProductionType const& new_production_type, fixed_point_t new_size_multiplier, fixed_point_t new_revenue_yesterday,
+ fixed_point_t new_output_quantity_yesterday, fixed_point_t new_unsold_quantity_yesterday,
ordered_map<Pop*, Pop::pop_size_t>&& new_employees
);
ResourceGatheringOperation(ProductionType const& new_production_type, fixed_point_t new_size_multiplier);
diff --git a/src/openvic-simulation/map/Crime.cpp b/src/openvic-simulation/map/Crime.cpp
index 03da0fc..fb521ad 100644
--- a/src/openvic-simulation/map/Crime.cpp
+++ b/src/openvic-simulation/map/Crime.cpp
@@ -6,16 +6,18 @@ using namespace OpenVic::NodeTools;
Crime::Crime(
std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon, ConditionScript&& new_trigger,
bool new_default_active
-) : TriggeredModifier { new_identifier, std::move(new_values), new_icon, std::move(new_trigger) },
+) : TriggeredModifier { new_identifier, std::move(new_values), modifier_type_t::CRIME, new_icon, std::move(new_trigger) },
default_active { new_default_active } {}
bool CrimeManager::add_crime_modifier(
- std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon, ConditionScript&& trigger, bool default_active
+ std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger,
+ bool default_active
) {
if (identifier.empty()) {
Logger::error("Invalid crime modifier effect identifier - empty!");
return false;
}
+
return crime_modifiers.add_item(
{ identifier, std::move(values), icon, std::move(trigger), default_active }, duplicate_warning_callback
);
@@ -26,7 +28,7 @@ bool CrimeManager::load_crime_modifiers(ModifierManager const& modifier_manager,
crime_modifiers,
[this, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool {
ModifierValue modifier_value;
- Modifier::icon_t icon = 0;
+ IconModifier::icon_t icon = 0;
ConditionScript trigger { scope_t::PROVINCE, scope_t::NO_SCOPE, scope_t::NO_SCOPE };
bool default_active = false;
bool ret = modifier_manager.expect_modifier_value_and_keys(
@@ -39,14 +41,18 @@ bool CrimeManager::load_crime_modifiers(ModifierManager const& modifier_manager,
return ret;
}
)(root);
+
lock_crime_modifiers();
+
return ret;
}
bool CrimeManager::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
for (Crime& crime : crime_modifiers.get_items()) {
ret &= crime.parse_scripts(definition_manager);
}
+
return ret;
}
diff --git a/src/openvic-simulation/map/Crime.hpp b/src/openvic-simulation/map/Crime.hpp
index 6aaf12c..91fc88a 100644
--- a/src/openvic-simulation/map/Crime.hpp
+++ b/src/openvic-simulation/map/Crime.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
namespace OpenVic {
struct Crime final : TriggeredModifier {
@@ -24,7 +24,7 @@ namespace OpenVic {
public:
bool add_crime_modifier(
- std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon, ConditionScript&& trigger,
+ std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger,
bool default_active
);
diff --git a/src/openvic-simulation/map/MapDefinition.cpp b/src/openvic-simulation/map/MapDefinition.cpp
index 7ed2919..828a679 100644
--- a/src/openvic-simulation/map/MapDefinition.cpp
+++ b/src/openvic-simulation/map/MapDefinition.cpp
@@ -14,7 +14,8 @@ using namespace OpenVic::NodeTools;
MapDefinition::MapDefinition() : dims { 0, 0 }, max_provinces { ProvinceDefinition::MAX_INDEX } {}
-RiverSegment::RiverSegment(uint8_t new_size, std::vector<ivec2_t> new_points) : size { new_size }, points { std::move(new_points) } {}
+RiverSegment::RiverSegment(uint8_t new_size, std::vector<ivec2_t>&& new_points)
+ : size { new_size }, points { std::move(new_points) } {}
bool MapDefinition::add_province_definition(std::string_view identifier, colour_t colour) {
if (province_definitions.size() >= max_provinces) {
@@ -533,7 +534,7 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
}
BMP rivers_bmp;
- if (!(rivers_bmp.open(rivers_path) && rivers_bmp.read_header() && rivers_bmp.read_palette() && rivers_bmp.read_pixel_data())) {
+ if (!(rivers_bmp.open(rivers_path) && rivers_bmp.read_header() && rivers_bmp.read_pixel_data())) {
Logger::error("Failed to read BMP for compatibility mode river image: ", rivers_path);
return false;
}
@@ -674,7 +675,7 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
uint8_t const* river_data = rivers_bmp.get_pixel_data().data();
- /** Generating River Segments - Unoptimised & Unprofiled
+ /** Generating River Segments
1. check pixels up, right, down, and left from last_segment_end for a colour <12
2. add first point
3. set size of segment based on color value at first point
@@ -693,14 +694,14 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
size_t idx = last_segment_end.x + last_segment_end.y * rivers_bmp.get_width();
std::vector<ivec2_t> points;
- uint8_t direction;
+ uint8_t direction = 0;
// check pixel above
if (last_segment_end.y > 0 && last_segment_direction != 1) { // check for bounds & ignore direction
if (river_data[idx - rivers_bmp.get_width()] < 12) {
points.push_back({ last_segment_end.x, last_segment_end.y - 1 });
direction = 2;
- }
+ }
}
// check pixel to right
if (last_segment_end.x < rivers_bmp.get_width() - 1 && last_segment_direction != 4) {
@@ -724,6 +725,10 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
}
}
+ if (points.empty()) {
+ Logger::error("River analysis failed: single-pixel river @ (", last_segment_end.x, ", ", last_segment_end.y, ").");
+ return;
+ }
uint8_t size = river_data[points.front().x + points.front().y * rivers_bmp.get_width()] - 1; // size of river from 1 - 10 determined by colour
bool river_complete = false;
@@ -742,7 +747,7 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
idx = points.back().x + points.back().y * rivers_bmp.get_width();
ivec2_t merge_location;
- bool merge;
+ bool merge = false;
// check pixel above
if (points.back().y > 0 && direction != 1) { // check for bounds & ignore direction
@@ -811,17 +816,26 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
break;
}
- // TODO: implement optimisation algorithm to remove irrelevant points. Ramer-Douglas-Peucker?
+ // save memory & simplify by storing only start, corner, and end points.
+ const auto is_corner_point = [](ivec2_t previous, ivec2_t current, ivec2_t next) {
+ return ((current.x - previous.x) * (next.y - current.y)) != ((current.y - previous.y) * (next.x - current.x)); // slope is fun
+ };
+ std::vector<ivec2_t> simplified_points;
+ simplified_points.push_back(points.front()); // add starting point
+ for (int i = 1; i < points.size()-1; ++i) {
+ if (is_corner_point(points[i-1], points[i], points[i+1])) { // add corner points
+ simplified_points.push_back(points[i]);
+ }
+ }
+ simplified_points.push_back(points.back());
// add segment then recursively call if neeeded
- river.push_back({ size, points });
-
+ river.push_back({ size, std::move(simplified_points) });
if (river_complete) return;
next_segment(new_point, direction, river);
};
// find every river source and then run the segment algorithm.
- int temp = 0;
for (int y = 0; y < rivers_bmp.get_height(); ++y) {
for (int x = 0; x < rivers_bmp.get_width(); ++x) {
if (river_data[x + y * rivers_bmp.get_width()] == START_COLOUR) { // start of a river
@@ -829,7 +843,7 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
next_segment({ x, y }, 0, river);
- rivers.push_back(river);
+ rivers.push_back(std::move(river));
}
}
}
@@ -942,7 +956,7 @@ bool MapDefinition::load_climate_file(ModifierManager const& modifier_manager, a
if (cur_climate == nullptr) {
ModifierValue values;
ret &= modifier_manager.expect_modifier_value(move_variable_callback(values))(node);
- ret &= climates.add_item({ identifier, std::move(values) });
+ ret &= climates.add_item({ identifier, std::move(values), Modifier::modifier_type_t::CLIMATE });
} else {
ret &= expect_list_reserve_length(*cur_climate, expect_province_definition_identifier(
[cur_climate, &identifier](ProvinceDefinition& province) {
@@ -1005,7 +1019,7 @@ bool MapDefinition::load_continent_file(ModifierManager const& modifier_manager,
))
)(node);
- Continent continent = { identifier, std::move(values) };
+ Continent continent { identifier, std::move(values), Modifier::modifier_type_t::CONTINENT };
continent.add_provinces(prov_list);
continent.lock();
diff --git a/src/openvic-simulation/map/MapDefinition.hpp b/src/openvic-simulation/map/MapDefinition.hpp
index bd3b5ae..e835da8 100644
--- a/src/openvic-simulation/map/MapDefinition.hpp
+++ b/src/openvic-simulation/map/MapDefinition.hpp
@@ -25,10 +25,13 @@ namespace OpenVic {
friend struct MapDefinition;
private:
- const uint8_t PROPERTY(size);
- const std::vector<ivec2_t> PROPERTY(points);
+ const uint8_t PROPERTY(size);
+ std::vector<ivec2_t> PROPERTY(points);
- RiverSegment(uint8_t new_size, std::vector<ivec2_t> new_points);
+ RiverSegment(uint8_t new_size, std::vector<ivec2_t>&& new_points);
+
+ public:
+ RiverSegment(RiverSegment&&) = default;
};
/* REQUIREMENTS:
diff --git a/src/openvic-simulation/map/Region.cpp b/src/openvic-simulation/map/Region.cpp
index d8c5fc1..d35ff56 100644
--- a/src/openvic-simulation/map/Region.cpp
+++ b/src/openvic-simulation/map/Region.cpp
@@ -10,15 +10,19 @@ bool ProvinceSet::add_province(ProvinceDefinition const* province) {
Logger::error("Cannot add province to province set - locked!");
return false;
}
+
if (province == nullptr) {
Logger::error("Cannot add province to province set - null province!");
return false;
}
+
if (contains_province(province)) {
Logger::warning("Cannot add province ", province->get_identifier(), " to province set - already in the set!");
return false;
}
+
provinces.push_back(province);
+
return true;
}
@@ -27,16 +31,20 @@ bool ProvinceSet::remove_province(ProvinceDefinition const* province) {
Logger::error("Cannot remove province from province set - locked!");
return false;
}
+
if (province == nullptr) {
Logger::error("Cannot remove province from province set - null province!");
return false;
}
+
const decltype(provinces)::const_iterator it = std::find(provinces.begin(), provinces.end(), province);
if (it == provinces.end()) {
Logger::warning("Cannot remove province ", province->get_identifier(), " from province set - already not in the set!");
return false;
}
+
provinces.erase(it);
+
return true;
}
@@ -84,8 +92,8 @@ bool ProvinceSet::contains_province(ProvinceDefinition const* province) const {
return province != nullptr && std::find(provinces.begin(), provinces.end(), province) != provinces.end();
}
-ProvinceSetModifier::ProvinceSetModifier(std::string_view new_identifier, ModifierValue&& new_values)
- : Modifier { new_identifier, std::move(new_values) } {}
+ProvinceSetModifier::ProvinceSetModifier(std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type)
+ : Modifier { new_identifier, std::move(new_values), new_type } {}
Region::Region(std::string_view new_identifier, colour_t new_colour, bool new_meta)
: HasIdentifierAndColour { new_identifier, new_colour, false }, meta { new_meta } {}
diff --git a/src/openvic-simulation/map/Region.hpp b/src/openvic-simulation/map/Region.hpp
index 1152dab..d08ccc4 100644
--- a/src/openvic-simulation/map/Region.hpp
+++ b/src/openvic-simulation/map/Region.hpp
@@ -4,7 +4,7 @@
#include <string_view>
#include <vector>
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
namespace OpenVic {
@@ -48,7 +48,7 @@ namespace OpenVic {
struct ProvinceSetModifier : Modifier, ProvinceSet {
friend struct MapDefinition;
private:
- ProvinceSetModifier(std::string_view new_identifier, ModifierValue&& new_values);
+ ProvinceSetModifier(std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type);
public:
ProvinceSetModifier(ProvinceSetModifier&&) = default;
};
diff --git a/src/openvic-simulation/map/TerrainType.cpp b/src/openvic-simulation/map/TerrainType.cpp
index 704e79e..b4cc430 100644
--- a/src/openvic-simulation/map/TerrainType.cpp
+++ b/src/openvic-simulation/map/TerrainType.cpp
@@ -7,7 +7,8 @@ using namespace OpenVic::NodeTools;
TerrainType::TerrainType(
std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_modifier, bool new_is_water
-) : Modifier { new_identifier, std::move(new_modifier) }, HasColour { new_colour, false }, is_water { new_is_water } {}
+) : Modifier { new_identifier, std::move(new_modifier), modifier_type_t::TERRAIN }, HasColour { new_colour, false },
+ is_water { new_is_water } {}
TerrainTypeMapping::TerrainTypeMapping(
std::string_view new_identifier, TerrainType const& new_type, std::vector<index_t>&& new_terrain_indicies,
@@ -22,6 +23,7 @@ bool TerrainTypeManager::add_terrain_type(
Logger::error("Invalid terrain type identifier - empty!");
return false;
}
+
return terrain_types.add_item({ identifier, colour, std::move(values), is_water });
}
@@ -33,17 +35,22 @@ bool TerrainTypeManager::add_terrain_type_mapping(
Logger::error("Cannot register terrain type mappings until terrain types are locked!");
return false;
}
+
if (identifier.empty()) {
Logger::error("Invalid terrain type mapping identifier - empty!");
return false;
}
+
if (type == nullptr) {
Logger::error("Null terrain type for mapping ", identifier);
return false;
}
+
bool ret = true;
+
for (TerrainTypeMapping::index_t idx : terrain_indicies) {
const terrain_type_mappings_map_t::const_iterator it = terrain_type_mappings_map.find(idx);
+
if (it == terrain_type_mappings_map.end()) {
terrain_type_mappings_map.emplace(idx, terrain_type_mappings.size());
} else {
@@ -54,7 +61,9 @@ bool TerrainTypeManager::add_terrain_type_mapping(
ret = false;
}
}
+
ret &= terrain_type_mappings.add_item({ identifier, *type, std::move(terrain_indicies), priority, has_texture });
+
return ret;
}
@@ -73,7 +82,9 @@ node_callback_t TerrainTypeManager::_load_terrain_type_categories(ModifierManage
return ret;
}
)(root);
+
lock_terrain_types();
+
return ret;
};
}
@@ -83,10 +94,12 @@ bool TerrainTypeManager::_load_terrain_type_mapping(std::string_view mapping_key
Logger::error("Cannot define terrain type mapping before terrain texture limit: ", mapping_key);
return false;
}
+
if (!terrain_types_are_locked()) {
Logger::error("Cannot define terrain type mapping before categories: ", mapping_key);
return false;
}
+
TerrainType const* type = nullptr;
std::vector<TerrainTypeMapping::index_t> terrain_indicies;
TerrainTypeMapping::index_t priority = 0;
@@ -107,18 +120,23 @@ bool TerrainTypeManager::_load_terrain_type_mapping(std::string_view mapping_key
"priority", ZERO_OR_ONE, expect_uint(assign_variable_callback(priority)),
"has_texture", ZERO_OR_ONE, expect_bool(assign_variable_callback(has_texture))
)(mapping_value);
+
if (has_texture && ++terrain_texture_count == terrain_texture_limit + 1) {
Logger::warning("More terrain textures than limit!");
}
+
ret &= add_terrain_type_mapping(mapping_key, type, std::move(terrain_indicies), priority, has_texture);
+
return true;
}
TerrainTypeMapping const* TerrainTypeManager::get_terrain_type_mapping_for(TerrainTypeMapping::index_t idx) const {
const terrain_type_mappings_map_t::const_iterator it = terrain_type_mappings_map.find(idx);
+
if (it != terrain_type_mappings_map.end()) {
return terrain_type_mappings.get_item_by_index(it->second);
}
+
return nullptr;
}
@@ -135,6 +153,8 @@ bool TerrainTypeManager::load_terrain_types(ModifierManager const& modifier_mana
"terrain", ONE_EXACTLY, expect_uint(assign_variable_callback(terrain_texture_limit)),
"categories", ONE_EXACTLY, _load_terrain_type_categories(modifier_manager)
)(root);
+
lock_terrain_type_mappings();
+
return ret;
}
diff --git a/src/openvic-simulation/map/TerrainType.hpp b/src/openvic-simulation/map/TerrainType.hpp
index ec36363..3a88610 100644
--- a/src/openvic-simulation/map/TerrainType.hpp
+++ b/src/openvic-simulation/map/TerrainType.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/types/OrderedContainers.hpp"
namespace OpenVic {
diff --git a/src/openvic-simulation/military/LeaderTrait.cpp b/src/openvic-simulation/military/LeaderTrait.cpp
index e6c0227..da7331a 100644
--- a/src/openvic-simulation/military/LeaderTrait.cpp
+++ b/src/openvic-simulation/military/LeaderTrait.cpp
@@ -4,7 +4,7 @@ using namespace OpenVic;
using namespace OpenVic::NodeTools;
LeaderTrait::LeaderTrait(std::string_view new_identifier, trait_type_t new_type, ModifierValue&& new_modifiers)
- : Modifier { new_identifier, std::move(new_modifiers) }, trait_type { new_type } {}
+ : Modifier { new_identifier, std::move(new_modifiers), modifier_type_t::LEADER }, trait_type { new_type } {}
bool LeaderTrait::is_personality_trait() const {
return trait_type == trait_type_t::PERSONALITY;
diff --git a/src/openvic-simulation/military/LeaderTrait.hpp b/src/openvic-simulation/military/LeaderTrait.hpp
index 65f45f8..cbc5b45 100644
--- a/src/openvic-simulation/military/LeaderTrait.hpp
+++ b/src/openvic-simulation/military/LeaderTrait.hpp
@@ -2,8 +2,8 @@
#include <string_view>
-#include "openvic-simulation/misc/Modifier.hpp"
#include "openvic-simulation/dataloader/NodeTools.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
namespace OpenVic {
diff --git a/src/openvic-simulation/military/UnitType.cpp b/src/openvic-simulation/military/UnitType.cpp
index d4ffbee..71bc5c3 100644
--- a/src/openvic-simulation/military/UnitType.cpp
+++ b/src/openvic-simulation/military/UnitType.cpp
@@ -318,12 +318,15 @@ bool UnitTypeManager::load_unit_type_file(
bool UnitTypeManager::generate_modifiers(ModifierManager& modifier_manager) const {
bool ret = true;
- const auto generate_stat_modifiers = [&modifier_manager, &ret](std::string_view identifier, UnitType::branch_t branch) -> void {
+ const auto generate_stat_modifiers = [&modifier_manager, &ret](
+ std::string_view identifier, UnitType::branch_t branch
+ ) -> void {
const auto stat_modifier = [&modifier_manager, &ret, &identifier](
- std::string_view suffix, bool is_positive_good, ModifierEffect::format_t format
+ std::string_view suffix, bool is_positive_good, ModifierEffect::format_t format, std::string_view localisation_key
) -> void {
ret &= modifier_manager.add_modifier_effect(
- ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format
+ ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format,
+ StringUtils::append_string_views("$", identifier, "$: $", localisation_key, "$")
);
};
@@ -331,29 +334,29 @@ bool UnitTypeManager::generate_modifiers(ModifierManager& modifier_manager) cons
ret &= modifier_manager.register_complex_modifier(identifier);
- stat_modifier("attack", true, RAW_DECIMAL);
- stat_modifier("defence", true, RAW_DECIMAL);
- stat_modifier("default_organisation", true, RAW_DECIMAL);
- stat_modifier("maximum_speed", true, RAW_DECIMAL);
- stat_modifier("build_time", false, INT);
- stat_modifier("supply_consumption", false, PROPORTION_DECIMAL);
+ stat_modifier("attack", true, RAW_DECIMAL, "ATTACK");
+ stat_modifier("defence", true, RAW_DECIMAL, "DEFENCE");
+ stat_modifier("default_organisation", true, RAW_DECIMAL, "DEFAULT_ORG");
+ stat_modifier("maximum_speed", true, RAW_DECIMAL, "MAXIMUM_SPEED");
+ stat_modifier("build_time", false, INT, "BUILD_TIME");
+ stat_modifier("supply_consumption", false, PROPORTION_DECIMAL, "SUPPLY_CONSUMPTION");
switch (branch) {
case LAND:
- stat_modifier("reconnaissance", true, RAW_DECIMAL);
- stat_modifier("discipline", true, PROPORTION_DECIMAL);
- stat_modifier("support", true, PROPORTION_DECIMAL);
- stat_modifier("maneuver", true, INT);
- stat_modifier("siege", true, RAW_DECIMAL);
+ stat_modifier("reconnaissance", true, RAW_DECIMAL, "RECONAISSANCE");
+ stat_modifier("discipline", true, PROPORTION_DECIMAL, "DISCIPLINE");
+ stat_modifier("support", true, PROPORTION_DECIMAL, "SUPPORT");
+ stat_modifier("maneuver", true, INT, "Maneuver");
+ stat_modifier("siege", true, RAW_DECIMAL, "SIEGE");
break;
case NAVAL:
- stat_modifier("colonial_points", true, INT);
- stat_modifier("supply_consumption_score", false, INT);
- stat_modifier("hull", true, RAW_DECIMAL);
- stat_modifier("gun_power", true, RAW_DECIMAL);
- stat_modifier("fire_range", true, RAW_DECIMAL);
- stat_modifier("evasion", true, PROPORTION_DECIMAL);
- stat_modifier("torpedo_attack", true, RAW_DECIMAL);
+ stat_modifier("colonial_points", true, INT, "COLONIAL_POINTS_TECH");
+ stat_modifier("supply_consumption_score", false, INT, "SUPPLY_LOAD");
+ stat_modifier("hull", true, RAW_DECIMAL, "HULL");
+ stat_modifier("gun_power", true, RAW_DECIMAL, "GUN_POWER");
+ stat_modifier("fire_range", true, RAW_DECIMAL, "FIRE_RANGE");
+ stat_modifier("evasion", true, PROPORTION_DECIMAL, "EVASION");
+ stat_modifier("torpedo_attack", true, RAW_DECIMAL, "TORPEDO_ATTACK");
break;
default:
/* Unreachable - unit types are only added via add_regiment_type or add_ship_type which set branch to LAND or NAVAL. */
diff --git a/src/openvic-simulation/military/UnitType.hpp b/src/openvic-simulation/military/UnitType.hpp
index 6bbaca7..3fa9af5 100644
--- a/src/openvic-simulation/military/UnitType.hpp
+++ b/src/openvic-simulation/military/UnitType.hpp
@@ -7,7 +7,7 @@
#include "openvic-simulation/dataloader/NodeTools.hpp"
#include "openvic-simulation/economy/GoodDefinition.hpp"
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
diff --git a/src/openvic-simulation/misc/Modifier.cpp b/src/openvic-simulation/modifier/Modifier.cpp
index 9163af5..b26b8dd 100644
--- a/src/openvic-simulation/misc/Modifier.cpp
+++ b/src/openvic-simulation/modifier/Modifier.cpp
@@ -12,8 +12,16 @@
using namespace OpenVic;
using namespace OpenVic::NodeTools;
-ModifierEffect::ModifierEffect(std::string_view new_identifier, bool new_positive_good, format_t new_format)
- : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format } {}
+static std::string make_default_modifier_effect_localisation_key(std::string_view identifier) {
+ return "MODIFIER_" + StringUtils::string_toupper(identifier);
+}
+
+ModifierEffect::ModifierEffect(
+ std::string_view new_identifier, bool new_positive_good, format_t new_format, std::string_view new_localisation_key
+) : HasIdentifier { new_identifier }, positive_good { new_positive_good }, format { new_format },
+ localisation_key {
+ new_localisation_key.empty() ? make_default_modifier_effect_localisation_key(new_identifier) : new_localisation_key
+ } {}
ModifierValue::ModifierValue() = default;
ModifierValue::ModifierValue(effect_map_t&& new_values) : values { std::move(new_values) } {}
@@ -41,22 +49,26 @@ bool ModifierValue::empty() const {
return values.empty();
}
-fixed_point_t ModifierValue::get_effect(ModifierEffect const* effect, bool* successful) {
- const effect_map_t::const_iterator it = values.find(effect);
+fixed_point_t ModifierValue::get_effect(ModifierEffect const& effect, bool* effect_found) const {
+ const effect_map_t::const_iterator it = values.find(&effect);
if (it != values.end()) {
- if (successful != nullptr) {
- *successful = true;
+ if (effect_found != nullptr) {
+ *effect_found = true;
}
return it->second;
}
- if (successful != nullptr) {
- *successful = false;
+ if (effect_found != nullptr) {
+ *effect_found = false;
}
return fixed_point_t::_0();
}
-bool ModifierValue::has_effect(ModifierEffect const* effect) const {
- return values.contains(effect);
+bool ModifierValue::has_effect(ModifierEffect const& effect) const {
+ return values.contains(&effect);
+}
+
+void ModifierValue::set_effect(ModifierEffect const& effect, fixed_point_t value) {
+ values[&effect] = value;
}
ModifierValue& ModifierValue::operator+=(ModifierValue const& right) {
@@ -67,16 +79,16 @@ ModifierValue& ModifierValue::operator+=(ModifierValue const& right) {
}
ModifierValue ModifierValue::operator+(ModifierValue const& right) const {
- ModifierValue ret = *this;
- return ret += right;
+ ModifierValue copy = *this;
+ return copy += right;
}
ModifierValue ModifierValue::operator-() const {
- ModifierValue ret = *this;
- for (auto value : mutable_iterator(ret.values)) {
+ ModifierValue copy = *this;
+ for (auto value : mutable_iterator(copy.values)) {
value.second = -value.second;
}
- return ret;
+ return copy;
}
ModifierValue& ModifierValue::operator-=(ModifierValue const& right) {
@@ -87,30 +99,63 @@ ModifierValue& ModifierValue::operator-=(ModifierValue const& right) {
}
ModifierValue ModifierValue::operator-(ModifierValue const& right) const {
- ModifierValue ret = *this;
- return ret -= right;
+ ModifierValue copy = *this;
+ return copy -= right;
+}
+
+ModifierValue& ModifierValue::operator*=(fixed_point_t const& right) {
+ for (auto value : mutable_iterator(values)) {
+ value.second *= right;
+ }
+ return *this;
+}
+
+ModifierValue ModifierValue::operator*(fixed_point_t const& right) const {
+ ModifierValue copy = *this;
+ return copy *= right;
+}
+
+fixed_point_t& ModifierValue::operator[](ModifierEffect const& effect) {
+ return values[&effect];
+}
+
+void ModifierValue::multiply_add(ModifierValue const& other, fixed_point_t multiplier) {
+ if (multiplier == fixed_point_t::_1()) {
+ *this += other;
+ } else if (multiplier != fixed_point_t::_0()) {
+ for (effect_map_t::value_type const& value : other.values) {
+ values[value.first] += value.second * multiplier;
+ }
+ }
}
-Modifier::Modifier(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon)
- : HasIdentifier { new_identifier }, ModifierValue { std::move(new_values) }, icon { new_icon } {}
+Modifier::Modifier(std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type)
+ : HasIdentifier { new_identifier }, ModifierValue { std::move(new_values) }, type { new_type } {}
+
+IconModifier::IconModifier(
+ std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type, icon_t new_icon
+) : Modifier { new_identifier, std::move(new_values), new_type }, icon { new_icon } {}
TriggeredModifier::TriggeredModifier(
- std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon, ConditionScript&& new_trigger
-) : Modifier { new_identifier, std::move(new_values), new_icon }, trigger { std::move(new_trigger) } {}
+ std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type, icon_t new_icon,
+ ConditionScript&& new_trigger
+) : IconModifier { new_identifier, std::move(new_values), new_type, new_icon }, trigger { std::move(new_trigger) } {}
bool TriggeredModifier::parse_scripts(DefinitionManager const& definition_manager) {
return trigger.parse_script(false, definition_manager);
}
-ModifierInstance::ModifierInstance(Modifier const& modifier, Date expiry_date)
- : modifier { modifier }, expiry_date { expiry_date } {}
+ModifierInstance::ModifierInstance(Modifier const& new_modifier, Date new_expiry_date)
+ : modifier { &new_modifier }, expiry_date { new_expiry_date } {}
-bool ModifierManager::add_modifier_effect(std::string_view identifier, bool positive_good, ModifierEffect::format_t format) {
+bool ModifierManager::add_modifier_effect(
+ std::string_view identifier, bool positive_good, ModifierEffect::format_t format, std::string_view localisation_key
+) {
if (identifier.empty()) {
Logger::error("Invalid modifier effect identifier - empty!");
return false;
}
- return modifier_effects.add_item({ std::move(identifier), positive_good, format });
+ return modifier_effects.add_item({ std::move(identifier), positive_good, format, localisation_key });
}
bool ModifierManager::setup_modifier_effects() {
@@ -118,88 +163,127 @@ bool ModifierManager::setup_modifier_effects() {
using enum ModifierEffect::format_t;
/* Tech/inventions only */
- ret &= add_modifier_effect("cb_creation_speed", true);
+ ret &= add_modifier_effect("cb_creation_speed", true, PROPORTION_DECIMAL, "CB_MANUFACTURE_TECH");
ret &= add_modifier_effect("combat_width", false);
- ret &= add_modifier_effect("plurality", true, PERCENTAGE_DECIMAL);
- ret &= add_modifier_effect("pop_growth", true);
- ret &= add_modifier_effect("regular_experience_level", true, RAW_DECIMAL);
- ret &= add_modifier_effect("reinforce_rate", true);
- ret &= add_modifier_effect("seperatism", false); // paradox typo
- ret &= add_modifier_effect("shared_prestige", true, RAW_DECIMAL);
- ret &= add_modifier_effect("tax_eff", true);
+ ret &= add_modifier_effect("plurality", true, PERCENTAGE_DECIMAL, "TECH_PLURALITY");
+ ret &= add_modifier_effect("pop_growth", true, PROPORTION_DECIMAL, "TECH_POP_GROWTH");
+ ret &= add_modifier_effect("regular_experience_level", true, RAW_DECIMAL, "REGULAR_EXP_TECH");
+ ret &= add_modifier_effect("reinforce_rate", true, PROPORTION_DECIMAL, "REINFORCE_TECH");
+ ret &= add_modifier_effect("seperatism", false, PROPORTION_DECIMAL, "SEPARATISM_TECH"); // paradox typo
+ ret &= add_modifier_effect("shared_prestige", true, RAW_DECIMAL, "SHARED_PRESTIGE_TECH");
+ ret &= add_modifier_effect("tax_eff", true, PROPORTION_DECIMAL, "TECH_TAX_EFF");
/* Country Modifier Effects */
ret &= add_modifier_effect("administrative_efficiency", true);
- ret &= add_modifier_effect("administrative_efficiency_modifier", true);
+ ret &= add_modifier_effect(
+ "administrative_efficiency_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("administrative_efficiency")
+ );
ret &= add_modifier_effect("artisan_input", false);
ret &= add_modifier_effect("artisan_output", true);
ret &= add_modifier_effect("artisan_throughput", true);
ret &= add_modifier_effect("badboy", false, RAW_DECIMAL);
ret &= add_modifier_effect("cb_generation_speed_modifier", true);
- ret &= add_modifier_effect("civilization_progress_modifier", true);
- ret &= add_modifier_effect("colonial_life_rating", false, INT);
- ret &= add_modifier_effect("colonial_migration", true);
- ret &= add_modifier_effect("colonial_points", true, INT);
- ret &= add_modifier_effect("colonial_prestige", true);
+ ret &= add_modifier_effect(
+ "civilization_progress_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("civilization_progress")
+ );
+ ret &= add_modifier_effect("colonial_life_rating", false, INT, "COLONIAL_LIFE_TECH");
+ ret &= add_modifier_effect("colonial_migration", true, PROPORTION_DECIMAL, "COLONIAL_MIGRATION_TECH");
+ ret &= add_modifier_effect("colonial_points", true, INT, "COLONIAL_POINTS_TECH");
+ ret &= add_modifier_effect("colonial_prestige", true, PROPORTION_DECIMAL, "COLONIAL_PRESTIGE_MODIFIER_TECH");
ret &= add_modifier_effect("core_pop_consciousness_modifier", false, RAW_DECIMAL);
ret &= add_modifier_effect("core_pop_militancy_modifier", false, RAW_DECIMAL);
- ret &= add_modifier_effect("dig_in_cap", true, INT);
- ret &= add_modifier_effect("diplomatic_points", true);
- ret &= add_modifier_effect("diplomatic_points_modifier", true);
+ ret &= add_modifier_effect("dig_in_cap", true, INT, "DIGIN_FROM_TECH");
+ ret &= add_modifier_effect("diplomatic_points", true, PROPORTION_DECIMAL, "DIPLOMATIC_POINTS_TECH");
+ ret &= add_modifier_effect(
+ "diplomatic_points_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("diplopoints_gain")
+ );
ret &= add_modifier_effect("education_efficiency", true);
- ret &= add_modifier_effect("education_efficiency_modifier", true);
+ ret &= add_modifier_effect(
+ "education_efficiency_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("education_efficiency")
+ );
ret &= add_modifier_effect("factory_cost", false);
ret &= add_modifier_effect("factory_input", false);
ret &= add_modifier_effect("factory_maintenance", false);
ret &= add_modifier_effect("factory_output", true);
ret &= add_modifier_effect("factory_owner_cost", false);
ret &= add_modifier_effect("factory_throughput", true);
- ret &= add_modifier_effect("global_assimilation_rate", true);
- ret &= add_modifier_effect("global_immigrant_attract", true);
+ ret &= add_modifier_effect(
+ "global_assimilation_rate", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("assimilation_rate")
+ );
+ ret &= add_modifier_effect(
+ "global_immigrant_attract", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("immigant_attract")
+ );
ret &= add_modifier_effect("global_pop_consciousness_modifier", false, RAW_DECIMAL);
ret &= add_modifier_effect("global_pop_militancy_modifier", false, RAW_DECIMAL);
- ret &= add_modifier_effect("global_population_growth", true);
+ ret &= add_modifier_effect(
+ "global_population_growth", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("population_growth")
+ );
ret &= add_modifier_effect("goods_demand", false);
ret &= add_modifier_effect("import_cost", false);
- ret &= add_modifier_effect("increase_research", true);
- ret &= add_modifier_effect("influence", true);
- ret &= add_modifier_effect("influence_modifier", true);
+ ret &= add_modifier_effect("increase_research", true, PROPORTION_DECIMAL, "INC_RES_TECH");
+ ret &= add_modifier_effect("influence", true, PROPORTION_DECIMAL, "TECH_GP_INFLUENCE");
+ ret &= add_modifier_effect(
+ "influence_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("greatpower_influence_gain")
+ );
ret &= add_modifier_effect("issue_change_speed", true);
- ret &= add_modifier_effect("land_attack_modifier", true);
- ret &= add_modifier_effect("land_attrition", false);
- ret &= add_modifier_effect("land_defense_modifier", true);
+ ret &= add_modifier_effect(
+ "land_attack_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("land_attack")
+ );
+ ret &= add_modifier_effect("land_attrition", false, PROPORTION_DECIMAL, "LAND_ATTRITION_TECH");
+ ret &= add_modifier_effect(
+ "land_defense_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("land_defense")
+ );
ret &= add_modifier_effect("land_organisation", true);
ret &= add_modifier_effect("land_unit_start_experience", true, RAW_DECIMAL);
- ret &= add_modifier_effect("leadership", true, RAW_DECIMAL);
- ret &= add_modifier_effect("leadership_modifier", true);
+ ret &= add_modifier_effect("leadership", true, RAW_DECIMAL, "LEADERSHIP");
+ ret &= add_modifier_effect(
+ "leadership_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("global_leadership_modifier")
+ );
ret &= add_modifier_effect("literacy_con_impact", false);
ret &= add_modifier_effect("loan_interest", false);
- ret &= add_modifier_effect("max_loan_modifier", true);
+ ret &= add_modifier_effect(
+ "max_loan_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("max_loan_amount")
+ );
ret &= add_modifier_effect("max_military_spending", true);
- ret &= add_modifier_effect("max_national_focus", true, INT);
+ ret &= add_modifier_effect("max_national_focus", true, INT, "TECH_MAX_FOCUS");
ret &= add_modifier_effect("max_social_spending", true);
ret &= add_modifier_effect("max_tariff", true);
ret &= add_modifier_effect("max_tax", true);
- ret &= add_modifier_effect("max_war_exhaustion", true, PERCENTAGE_DECIMAL);
- ret &= add_modifier_effect("military_tactics", true);
+ ret &= add_modifier_effect("max_war_exhaustion", true, PERCENTAGE_DECIMAL, "MAX_WAR_EXHAUSTION");
+ ret &= add_modifier_effect("military_tactics", true, PROPORTION_DECIMAL, "MIL_TACTICS_TECH");
ret &= add_modifier_effect("min_military_spending", true);
ret &= add_modifier_effect("min_social_spending", true);
ret &= add_modifier_effect("min_tariff", true);
ret &= add_modifier_effect("min_tax", true);
- ret &= add_modifier_effect("minimum_wage", true);
+ ret &= add_modifier_effect(
+ "minimum_wage", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("minimun_wage")
+ );
ret &= add_modifier_effect("mobilisation_economy_impact", false);
ret &= add_modifier_effect("mobilisation_size", true);
ret &= add_modifier_effect("mobilization_impact", false);
- ret &= add_modifier_effect("naval_attack_modifier", true);
- ret &= add_modifier_effect("naval_attrition", false);
- ret &= add_modifier_effect("naval_defense_modifier", true);
+ ret &= add_modifier_effect(
+ "naval_attack_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("naval_attack")
+ );
+ ret &= add_modifier_effect("naval_attrition", false, PROPORTION_DECIMAL, "NAVAL_ATTRITION_TECH");
+ ret &= add_modifier_effect(
+ "naval_defense_modifier", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("naval_defense")
+ );
ret &= add_modifier_effect("naval_organisation", true);
ret &= add_modifier_effect("naval_unit_start_experience", true, RAW_DECIMAL);
ret &= add_modifier_effect("non_accepted_pop_consciousness_modifier", false, RAW_DECIMAL);
ret &= add_modifier_effect("non_accepted_pop_militancy_modifier", false, RAW_DECIMAL);
ret &= add_modifier_effect("org_regain", true);
ret &= add_modifier_effect("pension_level", true);
- ret &= add_modifier_effect("permanent_prestige", true, RAW_DECIMAL);
+ ret &= add_modifier_effect("permanent_prestige", true, RAW_DECIMAL, "PERMANENT_PRESTIGE_TECH");
ret &= add_modifier_effect("political_reform_desire", false);
ret &= add_modifier_effect("poor_savings_modifier", true);
ret &= add_modifier_effect("prestige", true, RAW_DECIMAL);
@@ -210,47 +294,85 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("rgo_output", true);
ret &= add_modifier_effect("rgo_throughput", true);
ret &= add_modifier_effect("ruling_party_support", true);
- ret &= add_modifier_effect("self_unciv_economic_modifier", false);
- ret &= add_modifier_effect("self_unciv_military_modifier", false);
+ ret &= add_modifier_effect(
+ "self_unciv_economic_modifier", false, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("self_unciv_economic")
+ );
+ ret &= add_modifier_effect(
+ "self_unciv_military_modifier", false, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("self_unciv_military")
+ );
ret &= add_modifier_effect("social_reform_desire", false);
- ret &= add_modifier_effect("soldier_to_pop_loss", true);
+ ret &= add_modifier_effect("soldier_to_pop_loss", true, PROPORTION_DECIMAL, "SOLDIER_TO_POP_LOSS_TECH");
ret &= add_modifier_effect("supply_consumption", false);
- ret &= add_modifier_effect("supply_range", true);
- ret &= add_modifier_effect("suppression_points_modifier", true);
- ret &= add_modifier_effect("tariff_efficiency_modifier", true);
+ ret &= add_modifier_effect("supply_range", true, PROPORTION_DECIMAL, "SUPPLY_RANGE_TECH");
+ ret &= add_modifier_effect("suppression_points_modifier", true, PROPORTION_DECIMAL, "SUPPRESSION_TECH");
+ ret &= add_modifier_effect(
+ "tariff_efficiency_modifier", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("tariff_efficiency")
+ );
ret &= add_modifier_effect("tax_efficiency", true);
ret &= add_modifier_effect("unemployment_benefit", true);
- ret &= add_modifier_effect("unciv_economic_modifier", false);
- ret &= add_modifier_effect("unciv_military_modifier", false);
+ ret &= add_modifier_effect(
+ "unciv_economic_modifier", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("unciv_economic")
+ );
+ ret &= add_modifier_effect(
+ "unciv_military_modifier", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("unciv_military")
+ );
ret &= add_modifier_effect("unit_recruitment_time", false);
- ret &= add_modifier_effect("war_exhaustion", false);
-
- /* State only */
- ret &= add_modifier_effect("flashpoint_tension", true);
- ret &= add_modifier_effect("railroads", true); // capitalist likelihood for railroads vs factories
+ ret &= add_modifier_effect("war_exhaustion", false, PROPORTION_DECIMAL, "WAR_EXHAUST_BATTLES");
/* Province Modifier Effects */
ret &= add_modifier_effect("assimilation_rate", true);
ret &= add_modifier_effect("boost_strongest_party", false);
- ret &= add_modifier_effect("farm_rgo_eff", true);
- ret &= add_modifier_effect("farm_rgo_size", true);
- ret &= add_modifier_effect("immigrant_attract", true);
- ret &= add_modifier_effect("immigrant_push", false);
+ ret &= add_modifier_effect("farm_rgo_eff", true, PROPORTION_DECIMAL, "TECH_FARM_OUTPUT");
+ ret &= add_modifier_effect(
+ "farm_rgo_size", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("farm_size")
+ );
+ ret &= add_modifier_effect(
+ "immigrant_attract", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("immigant_attract")
+ );
+ ret &= add_modifier_effect(
+ "immigrant_push", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("immigant_push")
+ );
ret &= add_modifier_effect("life_rating", true);
- ret &= add_modifier_effect("local_artisan_input", false);
- ret &= add_modifier_effect("local_artisan_output", true);
- ret &= add_modifier_effect("local_artisan_throughput", true);
- ret &= add_modifier_effect("local_factory_input", false);
- ret &= add_modifier_effect("local_factory_output", true);
- ret &= add_modifier_effect("local_factory_throughput", true);
+ ret &= add_modifier_effect(
+ "local_artisan_input", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("artisan_input")
+ );
+ ret &= add_modifier_effect(
+ "local_artisan_output", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("artisan_output")
+ );
+ ret &= add_modifier_effect(
+ "local_artisan_throughput", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("artisan_throughput")
+ );
+ ret &= add_modifier_effect(
+ "local_factory_input", false, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("factory_input")
+ );
+ ret &= add_modifier_effect(
+ "local_factory_output", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("factory_output")
+ );
+ ret &= add_modifier_effect(
+ "local_factory_throughput", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("factory_throughput")
+ );
ret &= add_modifier_effect("local_repair", true);
- ret &= add_modifier_effect("local_rgo_output", true);
- ret &= add_modifier_effect("local_rgo_throughput", true);
- ret &= add_modifier_effect("local_ruling_party_support", true);
+ ret &= add_modifier_effect(
+ "local_rgo_output", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("rgo_output")
+ );
+ ret &= add_modifier_effect(
+ "local_rgo_throughput", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("rgo_throughput")
+ );
+ ret &= add_modifier_effect(
+ "local_ruling_party_support", true, PROPORTION_DECIMAL,
+ make_default_modifier_effect_localisation_key("ruling_party_support")
+ );
ret &= add_modifier_effect("local_ship_build", false);
ret &= add_modifier_effect("max_attrition", false, RAW_DECIMAL);
- ret &= add_modifier_effect("mine_rgo_eff", true);
- ret &= add_modifier_effect("mine_rgo_size", true);
+ ret &= add_modifier_effect("mine_rgo_eff", true, PROPORTION_DECIMAL, "TECH_MINE_OUTPUT");
+ ret &= add_modifier_effect(
+ "mine_rgo_size", true, PROPORTION_DECIMAL, make_default_modifier_effect_localisation_key("mine_size")
+ );
ret &= add_modifier_effect("movement_cost", false);
ret &= add_modifier_effect("number_of_voters", false);
ret &= add_modifier_effect("pop_consciousness_modifier", false, RAW_DECIMAL);
@@ -259,16 +381,15 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("supply_limit", true, RAW_DECIMAL);
/* Military Modifier Effects */
- ret &= add_modifier_effect("attack", true, INT);
- ret &= add_modifier_effect("attrition", false, RAW_DECIMAL);
- ret &= add_modifier_effect("defence", true, INT);
- ret &= add_modifier_effect("experience", true);
- ret &= add_modifier_effect("morale", true);
- ret &= add_modifier_effect("movement", true);
- ret &= add_modifier_effect("organisation", true);
- ret &= add_modifier_effect("reconnaissance", true);
- ret &= add_modifier_effect("reliability", true, RAW_DECIMAL);
- ret &= add_modifier_effect("speed", true);
+ ret &= add_modifier_effect("attack", true, INT, "TRAIT_ATTACK");
+ ret &= add_modifier_effect("attrition", false, RAW_DECIMAL, "ATTRITION");
+ ret &= add_modifier_effect("defence", true, INT, "TRAIT_DEFEND");
+ ret &= add_modifier_effect("experience", true, PROPORTION_DECIMAL, "TRAIT_EXPERIENCE");
+ ret &= add_modifier_effect("morale", true, PROPORTION_DECIMAL, "TRAIT_MORALE");
+ ret &= add_modifier_effect("organisation", true, PROPORTION_DECIMAL, "TRAIT_ORGANISATION");
+ ret &= add_modifier_effect("reconnaissance", true, PROPORTION_DECIMAL, "TRAIT_RECONAISSANCE");
+ ret &= add_modifier_effect("reliability", true, RAW_DECIMAL, "TRAIT_RELIABILITY");
+ ret &= add_modifier_effect("speed", true, PROPORTION_DECIMAL, "TRAIT_SPEED");
return ret;
}
@@ -288,12 +409,15 @@ std::string ModifierManager::get_flat_identifier(
return StringUtils::append_string_views(complex_modifier_identifier, " ", variant_identifier);
}
-bool ModifierManager::add_event_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon) {
+bool ModifierManager::add_event_modifier(std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon) {
if (identifier.empty()) {
Logger::error("Invalid event modifier effect identifier - empty!");
return false;
}
- return event_modifiers.add_item({ identifier, std::move(values), icon }, duplicate_warning_callback);
+
+ return event_modifiers.add_item(
+ { identifier, std::move(values), Modifier::modifier_type_t::EVENT, icon }, duplicate_warning_callback
+ );
}
bool ModifierManager::load_event_modifiers(ast::NodeCPtr root) {
@@ -301,7 +425,7 @@ bool ModifierManager::load_event_modifiers(ast::NodeCPtr root) {
event_modifiers,
[this](std::string_view key, ast::NodeCPtr value) -> bool {
ModifierValue modifier_value;
- Modifier::icon_t icon = 0;
+ IconModifier::icon_t icon = 0;
bool ret = expect_modifier_value_and_keys(
move_variable_callback(modifier_value),
"icon", ZERO_OR_ONE, expect_uint(assign_variable_callback(icon))
@@ -310,7 +434,9 @@ bool ModifierManager::load_event_modifiers(ast::NodeCPtr root) {
return ret;
}
)(root);
+
lock_event_modifiers();
+
return ret;
}
@@ -319,7 +445,10 @@ bool ModifierManager::add_static_modifier(std::string_view identifier, ModifierV
Logger::error("Invalid static modifier effect identifier - empty!");
return false;
}
- return static_modifiers.add_item({ identifier, std::move(values), 0 }, duplicate_warning_callback);
+
+ return static_modifiers.add_item(
+ { identifier, std::move(values), Modifier::modifier_type_t::STATIC }, duplicate_warning_callback
+ );
}
bool ModifierManager::load_static_modifiers(ast::NodeCPtr root) {
@@ -332,18 +461,24 @@ bool ModifierManager::load_static_modifiers(ast::NodeCPtr root) {
return ret;
}
)(root);
+
lock_static_modifiers();
+
return ret;
}
bool ModifierManager::add_triggered_modifier(
- std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon, ConditionScript&& trigger
+ std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger
) {
if (identifier.empty()) {
Logger::error("Invalid triggered modifier effect identifier - empty!");
return false;
}
- return triggered_modifiers.add_item({ identifier, std::move(values), icon, std::move(trigger) }, duplicate_warning_callback);
+
+ return triggered_modifiers.add_item(
+ { identifier, std::move(values), Modifier::modifier_type_t::TRIGGERED, icon, std::move(trigger) },
+ duplicate_warning_callback
+ );
}
bool ModifierManager::load_triggered_modifiers(ast::NodeCPtr root) {
@@ -351,7 +486,7 @@ bool ModifierManager::load_triggered_modifiers(ast::NodeCPtr root) {
triggered_modifiers,
[this](std::string_view key, ast::NodeCPtr value) -> bool {
ModifierValue modifier_value;
- Modifier::icon_t icon = 0;
+ IconModifier::icon_t icon = 0;
ConditionScript trigger { scope_t::COUNTRY, scope_t::COUNTRY, scope_t::NO_SCOPE };
bool ret = expect_modifier_value_and_keys(
@@ -363,15 +498,19 @@ bool ModifierManager::load_triggered_modifiers(ast::NodeCPtr root) {
return ret;
}
)(root);
+
lock_triggered_modifiers();
+
return ret;
}
bool ModifierManager::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
for (TriggeredModifier& modifier : triggered_modifiers.get_items()) {
ret &= modifier.parse_scripts(definition_manager);
}
+
return ret;
}
diff --git a/src/openvic-simulation/misc/Modifier.hpp b/src/openvic-simulation/modifier/Modifier.hpp
index bd72a1e..80d2db6 100644
--- a/src/openvic-simulation/misc/Modifier.hpp
+++ b/src/openvic-simulation/modifier/Modifier.hpp
@@ -22,10 +22,13 @@ namespace OpenVic {
*/
const bool PROPERTY_CUSTOM_PREFIX(positive_good, is);
const format_t PROPERTY(format);
+ 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);
+ ModifierEffect(
+ std::string_view new_identifier, bool new_positive_good, format_t new_format, std::string_view new_localisation_key
+ );
public:
ModifierEffect(ModifierEffect&&) = default;
@@ -54,14 +57,21 @@ namespace OpenVic {
void clear();
bool empty() const;
- fixed_point_t get_effect(ModifierEffect const* effect, bool* successful = nullptr);
- bool has_effect(ModifierEffect const* effect) const;
+ fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const;
+ bool has_effect(ModifierEffect const& effect) const;
+ void set_effect(ModifierEffect const& effect, fixed_point_t value);
ModifierValue& operator+=(ModifierValue const& right);
ModifierValue operator+(ModifierValue const& right) const;
ModifierValue operator-() const;
ModifierValue& operator-=(ModifierValue const& right);
ModifierValue operator-(ModifierValue const& right) const;
+ ModifierValue& operator*=(fixed_point_t const& right);
+ ModifierValue operator*(fixed_point_t const& right) const;
+
+ fixed_point_t& operator[](ModifierEffect const& effect);
+
+ void multiply_add(ModifierValue const& other, fixed_point_t multiplier);
friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value);
};
@@ -69,6 +79,24 @@ namespace OpenVic {
struct Modifier : HasIdentifier, ModifierValue {
friend struct ModifierManager;
+ enum struct modifier_type_t : uint8_t {
+ EVENT, STATIC, TRIGGERED, CRIME, TERRAIN, CLIMATE, CONTINENT, BUILDING, LEADER, NATIONAL_VALUE, NATIONAL_FOCUS,
+ ISSUE, REFORM, TECHNOLOGY, INVENTION, TECH_SCHOOL
+ };
+
+ private:
+ const modifier_type_t PROPERTY(type);
+
+ protected:
+ Modifier(std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type);
+
+ public:
+ Modifier(Modifier&&) = default;
+ };
+
+ struct IconModifier : Modifier {
+ friend struct ModifierManager;
+
using icon_t = uint8_t;
private:
@@ -76,13 +104,13 @@ namespace OpenVic {
const icon_t PROPERTY(icon);
protected:
- Modifier(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon = 0);
+ IconModifier(std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type, icon_t new_icon);
public:
- Modifier(Modifier&&) = default;
+ IconModifier(IconModifier&&) = default;
};
- struct TriggeredModifier : Modifier {
+ struct TriggeredModifier : IconModifier {
friend struct ModifierManager;
private:
@@ -90,7 +118,8 @@ namespace OpenVic {
protected:
TriggeredModifier(
- std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon, ConditionScript&& new_trigger
+ std::string_view new_identifier, ModifierValue&& new_values, modifier_type_t new_type, icon_t new_icon,
+ ConditionScript&& new_trigger
);
bool parse_scripts(DefinitionManager const& definition_manager);
@@ -102,10 +131,11 @@ namespace OpenVic {
struct ModifierInstance {
private:
- Modifier const& PROPERTY(modifier);
+ Modifier const* PROPERTY(modifier); // We can assume this is never null
Date PROPERTY(expiry_date);
- ModifierInstance(Modifier const& modifier, Date expiry_date);
+ public:
+ ModifierInstance(Modifier const& new_modifier, Date new_expiry_date);
};
template<typename Fn>
@@ -120,7 +150,7 @@ namespace OpenVic {
CaseInsensitiveIdentifierRegistry<ModifierEffect, RegistryStorageInfoDeque> IDENTIFIER_REGISTRY(modifier_effect);
case_insensitive_string_set_t complex_modifiers;
- IdentifierRegistry<Modifier> IDENTIFIER_REGISTRY(event_modifier);
+ IdentifierRegistry<IconModifier> IDENTIFIER_REGISTRY(event_modifier);
IdentifierRegistry<Modifier> IDENTIFIER_REGISTRY(static_modifier);
IdentifierRegistry<TriggeredModifier> IDENTIFIER_REGISTRY(triggered_modifier);
@@ -133,7 +163,8 @@ namespace OpenVic {
public:
bool add_modifier_effect(
std::string_view identifier, bool positive_good,
- ModifierEffect::format_t format = ModifierEffect::format_t::PROPORTION_DECIMAL
+ ModifierEffect::format_t format = ModifierEffect::format_t::PROPORTION_DECIMAL,
+ std::string_view localisation_key = {}
);
bool register_complex_modifier(std::string_view identifier);
@@ -143,14 +174,14 @@ namespace OpenVic {
bool setup_modifier_effects();
- bool add_event_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon);
+ 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, Modifier::icon_t icon, ConditionScript&& trigger
+ std::string_view identifier, ModifierValue&& values, IconModifier::icon_t icon, ConditionScript&& trigger
);
bool load_triggered_modifiers(ast::NodeCPtr root);
diff --git a/src/openvic-simulation/modifier/ModifierSum.cpp b/src/openvic-simulation/modifier/ModifierSum.cpp
new file mode 100644
index 0000000..8e5ce48
--- /dev/null
+++ b/src/openvic-simulation/modifier/ModifierSum.cpp
@@ -0,0 +1,58 @@
+#include "ModifierSum.hpp"
+
+using namespace OpenVic;
+
+void ModifierSum::clear() {
+ modifiers.clear();
+ value_sum.clear();
+}
+
+bool ModifierSum::empty() {
+ return modifiers.empty();
+}
+
+fixed_point_t ModifierSum::get_effect(ModifierEffect const& effect, bool* effect_found) const {
+ return value_sum.get_effect(effect, effect_found);
+}
+
+bool ModifierSum::has_effect(ModifierEffect const& effect) const {
+ return value_sum.has_effect(effect);
+}
+
+void ModifierSum::add_modifier(Modifier const& modifier, fixed_point_t multiplier) {
+ modifiers[&modifier] += multiplier;
+ value_sum.multiply_add(modifier, multiplier);
+}
+
+void ModifierSum::add_modifier_sum(ModifierSum const& modifier_sum) {
+ modifiers += modifier_sum.modifiers;
+ value_sum += modifier_sum.value_sum;
+}
+
+ModifierSum& ModifierSum::operator+=(Modifier const& modifier) {
+ add_modifier(modifier);
+ return *this;
+}
+
+ModifierSum& ModifierSum::operator+=(ModifierSum const& modifier_sum) {
+ add_modifier_sum(modifier_sum);
+ return *this;
+}
+
+// TODO - include value_sum[effect] in result? Early return if lookup in value_sum fails?
+std::vector<std::pair<Modifier const*, fixed_point_t>> ModifierSum::get_contributing_modifiers(
+ ModifierEffect const& effect
+) const {
+ std::vector<std::pair<Modifier const*, fixed_point_t>> ret;
+
+ for (auto const& [modifier, multiplier] : modifiers) {
+ bool effect_found = false;
+ const fixed_point_t value = modifier->get_effect(effect, &effect_found);
+
+ if (effect_found) {
+ ret.emplace_back(modifier, value * multiplier);
+ }
+ }
+
+ return ret;
+}
diff --git a/src/openvic-simulation/modifier/ModifierSum.hpp b/src/openvic-simulation/modifier/ModifierSum.hpp
new file mode 100644
index 0000000..957ffab
--- /dev/null
+++ b/src/openvic-simulation/modifier/ModifierSum.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "openvic-simulation/modifier/Modifier.hpp"
+#include "openvic-simulation/types/fixed_point/FixedPointMap.hpp"
+
+namespace OpenVic {
+ struct ModifierSum {
+ private:
+ fixed_point_map_t<Modifier const*> PROPERTY(modifiers);
+ ModifierValue PROPERTY(value_sum);
+
+ public:
+ ModifierSum() = default;
+ ModifierSum(ModifierSum&&) = default;
+
+ void clear();
+ bool empty();
+
+ fixed_point_t get_effect(ModifierEffect const& effect, bool* effect_found = nullptr) const;
+ bool has_effect(ModifierEffect const& effect) const;
+
+ void add_modifier(Modifier const& modifier, fixed_point_t multiplier = fixed_point_t::_1());
+ void add_modifier_sum(ModifierSum const& modifier_sum);
+
+ ModifierSum& operator+=(Modifier const& modifier);
+ ModifierSum& operator+=(ModifierSum const& modifier_sum);
+
+ std::vector<std::pair<Modifier const*, fixed_point_t>> get_contributing_modifiers(ModifierEffect const& effect) const;
+ };
+}
diff --git a/src/openvic-simulation/politics/Issue.cpp b/src/openvic-simulation/politics/Issue.cpp
index 1dca176..3174e23 100644
--- a/src/openvic-simulation/politics/Issue.cpp
+++ b/src/openvic-simulation/politics/Issue.cpp
@@ -7,9 +7,9 @@ IssueGroup::IssueGroup(std::string_view new_identifier) : HasIdentifier { new_id
Issue::Issue(
std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_values, IssueGroup const& new_group,
- RuleSet&& new_rules, bool new_jingoism
-) : HasIdentifierAndColour { new_identifier, new_colour, false }, ModifierValue { std::move(new_values) },
- group { new_group }, rules { std::move(new_rules) }, jingoism { new_jingoism } {}
+ RuleSet&& new_rules, bool new_jingoism, modifier_type_t new_type
+) : Modifier { new_identifier, std::move(new_values), new_type }, HasColour { new_colour, false }, group { new_group },
+ rules { std::move(new_rules) }, jingoism { new_jingoism } {}
ReformType::ReformType(std::string_view new_identifier, bool new_uncivilised)
: HasIdentifier { new_identifier }, uncivilised { new_uncivilised } {}
@@ -21,16 +21,19 @@ Reform::Reform(
std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_values, ReformGroup const& new_group,
size_t new_ordinal, fixed_point_t new_administrative_multiplier, RuleSet&& new_rules, tech_cost_t new_technology_cost,
ConditionScript&& new_allow, ConditionScript&& new_on_execute_trigger, EffectScript&& new_on_execute_effect
-) : Issue { new_identifier, new_colour, std::move(new_values), new_group, std::move(new_rules), false },
- reform_group { new_group }, ordinal { new_ordinal }, administrative_multiplier { new_administrative_multiplier },
+) : Issue {
+ new_identifier, new_colour, std::move(new_values), new_group, std::move(new_rules), false, modifier_type_t::REFORM
+ }, reform_group { new_group }, ordinal { new_ordinal }, administrative_multiplier { new_administrative_multiplier },
technology_cost { new_technology_cost }, allow { std::move(new_allow) },
on_execute_trigger { std::move(new_on_execute_trigger) }, on_execute_effect { std::move(new_on_execute_effect) } {}
bool Reform::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
ret &= allow.parse_script(true, definition_manager);
ret &= on_execute_trigger.parse_script(true, definition_manager);
ret &= on_execute_effect.parse_script(true, definition_manager);
+
return ret;
}
@@ -176,14 +179,17 @@ bool IssueManager::_load_issue(
ModifierValue values;
RuleSet rules;
bool jingoism = false;
+
bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(values),
"is_jingoism", ZERO_OR_ONE, expect_bool(assign_variable_callback(jingoism)),
"rules", ZERO_OR_ONE, rule_manager.expect_rule_set(move_variable_callback(rules))
)(node);
+
ret &= add_issue(
identifier, create_issue_reform_colour(get_issue_count() + get_reform_count()), std::move(values), group,
std::move(rules), jingoism
);
+
return ret;
}
@@ -191,12 +197,15 @@ bool IssueManager::_load_reform_group(
size_t& expected_reforms, std::string_view identifier, ReformType const* type, ast::NodeCPtr node
) {
bool ordered = false, administrative = false;
+
bool ret = expect_dictionary_keys_and_default(
increment_callback(expected_reforms),
"next_step_only", ZERO_OR_ONE, expect_bool(assign_variable_callback(ordered)),
"administrative", ZERO_OR_ONE, expect_bool(assign_variable_callback(administrative))
)(node);
+
ret &= add_reform_group(identifier, type, ordered, administrative);
+
return ret;
}
@@ -223,11 +232,13 @@ bool IssueManager::_load_reform(
"effect", ONE_EXACTLY, on_execute_effect.expect_script()
)
)(node);
+
ret &= add_reform(
identifier, create_issue_reform_colour(get_issue_count() + get_reform_count()), std::move(values), group, ordinal,
administrative_multiplier, std::move(rules), technology_cost, std::move(allow), std::move(on_execute_trigger),
std::move(on_execute_effect)
);
+
return ret;
}
@@ -272,6 +283,7 @@ bool IssueManager::load_issues_file(
}
}
)(root);
+
lock_reform_types();
reserve_more_issue_groups(expected_issue_groups);
@@ -306,6 +318,7 @@ bool IssueManager::load_issues_file(
}
}
)(root);
+
lock_issue_groups();
lock_reform_groups();
@@ -356,6 +369,7 @@ bool IssueManager::load_issues_file(
}
}
)(root);
+
lock_issues();
lock_reforms();
@@ -364,8 +378,10 @@ bool IssueManager::load_issues_file(
bool IssueManager::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
for (Reform& reform : reforms.get_items()) {
ret &= reform.parse_scripts(definition_manager);
}
+
return ret;
}
diff --git a/src/openvic-simulation/politics/Issue.hpp b/src/openvic-simulation/politics/Issue.hpp
index d49f897..c0ab86c 100644
--- a/src/openvic-simulation/politics/Issue.hpp
+++ b/src/openvic-simulation/politics/Issue.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/politics/Rule.hpp"
#include "openvic-simulation/scripts/ConditionScript.hpp"
#include "openvic-simulation/scripts/EffectScript.hpp"
@@ -21,7 +21,7 @@ namespace OpenVic {
};
// Issue (i.e. protectionism)
- struct Issue : HasIdentifierAndColour, ModifierValue {
+ struct Issue : Modifier, HasColour {
friend struct IssueManager;
private:
@@ -32,7 +32,7 @@ namespace OpenVic {
protected:
Issue(
std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_values, IssueGroup const& new_group,
- RuleSet&& new_rules, bool new_jingoism
+ RuleSet&& new_rules, bool new_jingoism, modifier_type_t new_type = modifier_type_t::ISSUE
);
public:
diff --git a/src/openvic-simulation/politics/NationalFocus.cpp b/src/openvic-simulation/politics/NationalFocus.cpp
index 3132c3e..4887ed6 100644
--- a/src/openvic-simulation/politics/NationalFocus.cpp
+++ b/src/openvic-simulation/politics/NationalFocus.cpp
@@ -1,6 +1,8 @@
#include "NationalFocus.hpp"
+#include "openvic-simulation/economy/GoodDefinition.hpp"
#include "openvic-simulation/politics/Ideology.hpp"
+#include "openvic-simulation/pop/Pop.hpp"
using namespace OpenVic;
using namespace OpenVic::NodeTools;
@@ -12,20 +14,28 @@ NationalFocus::NationalFocus(
NationalFocusGroup const& new_group,
uint8_t new_icon,
bool new_has_flashpoint,
+ fixed_point_t new_flashpoint_tension,
bool new_own_provinces,
bool new_outliner_show_as_percent,
ModifierValue&& new_modifiers,
Ideology const* new_loyalty_ideology,
fixed_point_t new_loyalty_value,
+ fixed_point_t new_encourage_railroads,
+ fixed_point_map_t<GoodDefinition const*>&& new_encourage_goods,
+ fixed_point_map_t<PopType const*>&& new_encourage_pop_types,
ConditionScript&& new_limit
-) : Modifier { new_identifier, std::move(new_modifiers) },
+) : Modifier { new_identifier, std::move(new_modifiers), modifier_type_t::NATIONAL_FOCUS },
group { new_group },
icon { new_icon },
has_flashpoint { new_has_flashpoint },
+ flashpoint_tension { new_flashpoint_tension },
own_provinces { new_own_provinces },
outliner_show_as_percent { new_outliner_show_as_percent },
loyalty_ideology { new_loyalty_ideology },
loyalty_value { new_loyalty_value },
+ encourage_railroads { new_encourage_railroads },
+ encourage_goods { std::move(new_encourage_goods) },
+ encourage_pop_types { std::move(new_encourage_pop_types) },
limit { std::move(new_limit) } {}
bool NationalFocus::parse_scripts(DefinitionManager const& definition_manager) {
@@ -37,6 +47,7 @@ inline bool NationalFocusManager::add_national_focus_group(std::string_view iden
Logger::error("No identifier for national focus group!");
return false;
}
+
return national_focus_groups.add_item({ identifier });
}
@@ -45,30 +56,38 @@ inline bool NationalFocusManager::add_national_focus(
NationalFocusGroup const& group,
uint8_t icon,
bool has_flashpoint,
+ fixed_point_t flashpoint_tension,
bool own_provinces,
bool outliner_show_as_percent,
ModifierValue&& modifiers,
Ideology const* loyalty_ideology,
fixed_point_t loyalty_value,
+ fixed_point_t encourage_railroads,
+ fixed_point_map_t<GoodDefinition const*>&& encourage_goods,
+ fixed_point_map_t<PopType const*>&& encourage_pop_types,
ConditionScript&& limit
) {
if (identifier.empty()) {
Logger::error("No identifier for national focus!");
return false;
}
+
if (icon < 1) {
Logger::error("Invalid icon ", icon, " for national focus ", identifier);
return false;
}
+
if ((loyalty_ideology == nullptr) != (loyalty_value == 0)) {
Logger::warning(
"Party loyalty incorrectly defined for national focus ", identifier, ": ideology = ", loyalty_ideology,
", value = ", loyalty_value
);
}
+
return national_foci.add_item({
- identifier, group, icon, has_flashpoint, own_provinces, outliner_show_as_percent, std::move(modifiers),
- loyalty_ideology, loyalty_value, std::move(limit)
+ identifier, group, icon, has_flashpoint, flashpoint_tension, own_provinces, outliner_show_as_percent,
+ std::move(modifiers), loyalty_ideology, loyalty_value, encourage_railroads, std::move(encourage_goods),
+ std::move(encourage_pop_types), std::move(limit)
});
}
@@ -77,12 +96,14 @@ bool NationalFocusManager::load_national_foci_file(
GoodDefinitionManager const& good_definition_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root
) {
size_t expected_national_foci = 0;
+
bool ret = expect_dictionary_reserve_length(
national_focus_groups,
[this, &expected_national_foci](std::string_view identifier, ast::NodeCPtr node) -> bool {
return expect_length(add_variable_callback(expected_national_foci))(node) & add_national_focus_group(identifier);
}
)(root);
+
lock_national_focus_groups();
reserve_more_national_foci(expected_national_foci);
@@ -97,29 +118,51 @@ bool NationalFocusManager::load_national_foci_file(
) -> bool {
uint8_t icon = 0;
bool has_flashpoint = false, own_provinces = true, outliner_show_as_percent = false;
+ fixed_point_t flashpoint_tension = 0;
ModifierValue modifiers;
Ideology const* loyalty_ideology = nullptr;
fixed_point_t loyalty_value = 0;
+ fixed_point_t encourage_railroads = 0;
+ fixed_point_map_t<GoodDefinition const*> encourage_goods;
+ fixed_point_map_t<PopType const*> encourage_pop_types;
ConditionScript limit {
scope_t::PROVINCE | scope_t::COUNTRY, scope_t::PROVINCE | scope_t::COUNTRY, scope_t::NO_SCOPE
};
- bool ret = modifier_manager.expect_modifier_value_and_keys(
+ bool ret = modifier_manager.expect_modifier_value_and_keys_and_default(
move_variable_callback(modifiers),
+ [&good_definition_manager, &encourage_goods, &pop_manager, &encourage_pop_types](
+ std::string_view key, ast::NodeCPtr value
+ ) -> bool {
+ GoodDefinition const* good = good_definition_manager.get_good_definition_by_identifier(key);
+ if (good != nullptr) {
+ return expect_fixed_point(map_callback(encourage_goods, good))(value);
+ }
+
+ PopType const* pop_type = pop_manager.get_pop_type_by_identifier(key);
+ if (pop_type != nullptr) {
+ return expect_fixed_point(map_callback(encourage_pop_types, pop_type))(value);
+ }
+
+ return key_value_invalid_callback(key, value);
+ },
"icon", ONE_EXACTLY, expect_uint(assign_variable_callback(icon)),
"ideology", ZERO_OR_ONE,
ideology_manager.expect_ideology_identifier(assign_variable_callback_pointer(loyalty_ideology)),
"loyalty_value", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(loyalty_value)),
"limit", ZERO_OR_ONE, limit.expect_script(),
"has_flashpoint", ZERO_OR_ONE, expect_bool(assign_variable_callback(has_flashpoint)),
+ "flashpoint_tension", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(flashpoint_tension)),
"own_provinces", ZERO_OR_ONE, expect_bool(assign_variable_callback(own_provinces)),
"outliner_show_as_percent", ZERO_OR_ONE,
- expect_bool(assign_variable_callback(outliner_show_as_percent))
+ expect_bool(assign_variable_callback(outliner_show_as_percent)),
+ "railroads", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(encourage_railroads))
)(node);
ret &= add_national_focus(
- identifier, group, icon, has_flashpoint, own_provinces, outliner_show_as_percent, std::move(modifiers),
- loyalty_ideology, loyalty_value, std::move(limit)
+ identifier, group, icon, has_flashpoint, flashpoint_tension, own_provinces, outliner_show_as_percent,
+ std::move(modifiers), loyalty_ideology, loyalty_value, encourage_railroads,
+ std::move(encourage_goods), std::move(encourage_pop_types), std::move(limit)
);
return ret;
@@ -127,6 +170,7 @@ bool NationalFocusManager::load_national_foci_file(
)(group_node);
}
)(root);
+
lock_national_foci();
return ret;
@@ -134,8 +178,10 @@ bool NationalFocusManager::load_national_foci_file(
bool NationalFocusManager::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
for (NationalFocus& national_focus : national_foci.get_items()) {
ret &= national_focus.parse_scripts(definition_manager);
}
+
return ret;
}
diff --git a/src/openvic-simulation/politics/NationalFocus.hpp b/src/openvic-simulation/politics/NationalFocus.hpp
index 04a4100..e046c7a 100644
--- a/src/openvic-simulation/politics/NationalFocus.hpp
+++ b/src/openvic-simulation/politics/NationalFocus.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/scripts/ConditionScript.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/utility/Getters.hpp"
@@ -16,6 +16,8 @@ namespace OpenVic {
};
struct Ideology;
+ struct GoodDefinition;
+ struct PopType;
struct NationalFocus : Modifier {
friend struct NationalFocusManager;
@@ -24,10 +26,14 @@ namespace OpenVic {
NationalFocusGroup const& PROPERTY(group);
uint8_t PROPERTY(icon);
bool PROPERTY(has_flashpoint);
+ fixed_point_t PROPERTY(flashpoint_tension);
bool PROPERTY(own_provinces);
bool PROPERTY(outliner_show_as_percent);
Ideology const* PROPERTY(loyalty_ideology);
fixed_point_t PROPERTY(loyalty_value);
+ fixed_point_t PROPERTY(encourage_railroads);
+ fixed_point_map_t<GoodDefinition const*> PROPERTY(encourage_goods);
+ fixed_point_map_t<PopType const*> PROPERTY(encourage_pop_types);
ConditionScript PROPERTY(limit);
NationalFocus(
@@ -35,11 +41,15 @@ namespace OpenVic {
NationalFocusGroup const& new_group,
uint8_t new_icon,
bool new_has_flashpoint,
+ fixed_point_t new_flashpoint_tension,
bool new_own_provinces,
bool new_outliner_show_as_percent,
ModifierValue&& new_modifiers,
Ideology const* new_loyalty_ideology,
fixed_point_t new_loyalty_value,
+ fixed_point_t new_encourage_railroads,
+ fixed_point_map_t<GoodDefinition const*>&& new_encourage_goods,
+ fixed_point_map_t<PopType const*>&& new_encourage_pop_types,
ConditionScript&& new_limit
);
@@ -66,11 +76,15 @@ namespace OpenVic {
NationalFocusGroup const& group,
uint8_t icon,
bool has_flashpoint,
+ fixed_point_t flashpoint_tension,
bool own_provinces,
bool outliner_show_as_percent,
ModifierValue&& modifiers,
Ideology const* loyalty_ideology,
fixed_point_t loyalty_value,
+ fixed_point_t encourage_railroads,
+ fixed_point_map_t<GoodDefinition const*>&& encourage_goods,
+ fixed_point_map_t<PopType const*>&& encourage_pop_types,
ConditionScript&& limit
);
diff --git a/src/openvic-simulation/politics/NationalValue.cpp b/src/openvic-simulation/politics/NationalValue.cpp
index b780195..e9f7f2a 100644
--- a/src/openvic-simulation/politics/NationalValue.cpp
+++ b/src/openvic-simulation/politics/NationalValue.cpp
@@ -4,7 +4,7 @@ using namespace OpenVic;
using namespace OpenVic::NodeTools;
NationalValue::NationalValue(std::string_view new_identifier, ModifierValue&& new_modifiers)
- : Modifier { new_identifier, std::move(new_modifiers) } {}
+ : Modifier { new_identifier, std::move(new_modifiers), modifier_type_t::NATIONAL_VALUE } {}
bool NationalValueManager::add_national_value(std::string_view identifier, ModifierValue&& modifiers) {
if (identifier.empty()) {
diff --git a/src/openvic-simulation/politics/NationalValue.hpp b/src/openvic-simulation/politics/NationalValue.hpp
index b896fd7..e69aa28 100644
--- a/src/openvic-simulation/politics/NationalValue.hpp
+++ b/src/openvic-simulation/politics/NationalValue.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
namespace OpenVic {
diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp
index fcb08c9..fef61c0 100644
--- a/src/openvic-simulation/politics/Rebel.cpp
+++ b/src/openvic-simulation/politics/Rebel.cpp
@@ -2,8 +2,6 @@
#include <string_view>
-#include "openvic-simulation/misc/Modifier.hpp"
-
using namespace OpenVic;
using namespace OpenVic::NodeTools;
@@ -176,16 +174,23 @@ bool RebelManager::load_rebels_file(
}
bool RebelManager::generate_modifiers(ModifierManager& modifier_manager) const {
+ using enum ModifierEffect::format_t;
+
bool ret = true;
+
static constexpr std::string_view identifier = "rebel_org_gain";
static constexpr bool is_positive_good = false;
+
ret &= modifier_manager.register_complex_modifier(identifier);
- ret &= modifier_manager.add_modifier_effect(ModifierManager::get_flat_identifier(identifier, "all"), is_positive_good);
+ ret &= modifier_manager.add_modifier_effect(
+ ModifierManager::get_flat_identifier(identifier, "all"), is_positive_good, PROPORTION_DECIMAL, "TECH_REBEL_ORG_GAIN"
+ );
for (RebelType const& rebel_type : get_rebel_types()) {
ret &= modifier_manager.add_modifier_effect(
- ModifierManager::get_flat_identifier(identifier, rebel_type.get_identifier()), is_positive_good
+ ModifierManager::get_flat_identifier(identifier, rebel_type.get_identifier()), is_positive_good, PROPORTION_DECIMAL,
+ StringUtils::append_string_views("$", rebel_type.get_identifier(), "_title$ $TECH_REBEL_ORG_GAIN$")
);
}
return ret;
diff --git a/src/openvic-simulation/politics/Rebel.hpp b/src/openvic-simulation/politics/Rebel.hpp
index 7aeb31b..fc82c84 100644
--- a/src/openvic-simulation/politics/Rebel.hpp
+++ b/src/openvic-simulation/politics/Rebel.hpp
@@ -2,7 +2,7 @@
#include <cstdint>
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/politics/Government.hpp"
#include "openvic-simulation/politics/Ideology.hpp"
#include "openvic-simulation/scripts/ConditionalWeight.hpp"
diff --git a/src/openvic-simulation/politics/Rule.cpp b/src/openvic-simulation/politics/Rule.cpp
index 1d61652..64d06f1 100644
--- a/src/openvic-simulation/politics/Rule.cpp
+++ b/src/openvic-simulation/politics/Rule.cpp
@@ -6,8 +6,15 @@
using namespace OpenVic;
using namespace OpenVic::NodeTools;
-Rule::Rule(std::string_view new_identifier, rule_group_t new_group, index_t new_index)
- : HasIdentifier { new_identifier }, HasIndex { new_index }, group { new_group } {}
+static std::string make_default_rule_localisation_key(std::string_view identifier) {
+ return "RULE_" + StringUtils::string_toupper(identifier);
+}
+
+Rule::Rule(std::string_view new_identifier, rule_group_t new_group, index_t new_index, std::string_view new_localisation_key)
+ : HasIdentifier { new_identifier }, HasIndex { new_index }, group { new_group },
+ localisation_key {
+ new_localisation_key.empty() ? make_default_rule_localisation_key(new_identifier) : new_localisation_key
+ } {}
RuleSet::RuleSet(rule_group_map_t&& new_rule_groups) : rule_groups { std::move(new_rule_groups) } {}
@@ -76,54 +83,42 @@ bool RuleSet::empty() const {
return true;
}
-RuleSet::rule_map_t const& RuleSet::get_rule_group(Rule::rule_group_t group, bool* successful) const {
+RuleSet::rule_map_t const& RuleSet::get_rule_group(Rule::rule_group_t group, bool* rule_group_found) const {
const rule_group_map_t::const_iterator it = rule_groups.find(group);
if (it != rule_groups.end()) {
- if (successful != nullptr) {
- *successful = true;
+ if (rule_group_found != nullptr) {
+ *rule_group_found = true;
}
return it->second;
}
- if (successful != nullptr) {
- *successful = false;
+ if (rule_group_found != nullptr) {
+ *rule_group_found = false;
}
static const rule_map_t empty_map {};
return empty_map;
}
-bool RuleSet::get_rule(Rule const* rule, bool* successful) const {
- if (rule == nullptr) {
- Logger::error("Invalid rule - null!");
- return false;
- }
- rule_map_t const& rule_map = get_rule_group(rule->get_group());
- const rule_map_t::const_iterator it = rule_map.find(rule);
+bool RuleSet::get_rule(Rule const& rule, bool* rule_found) const {
+ rule_map_t const& rule_map = get_rule_group(rule.get_group());
+ const rule_map_t::const_iterator it = rule_map.find(&rule);
if (it != rule_map.end()) {
- if (successful != nullptr) {
- *successful = true;
+ if (rule_found != nullptr) {
+ *rule_found = true;
}
return it->second;
}
- if (successful != nullptr) {
- *successful = false;
+ if (rule_found != nullptr) {
+ *rule_found = false;
}
- return Rule::is_default_enabled(rule->get_group());
+ return Rule::is_default_enabled(rule.get_group());
}
-bool RuleSet::has_rule(Rule const* rule) const {
- if (rule == nullptr) {
- Logger::error("Invalid rule - null!");
- return false;
- }
- return get_rule_group(rule->get_group()).contains(rule);
+bool RuleSet::has_rule(Rule const& rule) const {
+ return get_rule_group(rule.get_group()).contains(&rule);
}
-bool RuleSet::set_rule(Rule const* rule, bool value) {
- if (rule == nullptr) {
- Logger::error("Invalid rule - null!");
- return false;
- }
- rule_groups[rule->get_group()][rule] = value;
+bool RuleSet::set_rule(Rule const& rule, bool value) {
+ rule_groups[rule.get_group()][&rule] = value;
return true;
}
@@ -137,16 +132,16 @@ RuleSet& RuleSet::operator|=(RuleSet const& right) {
}
RuleSet RuleSet::operator|(RuleSet const& right) const {
- RuleSet ret = *this;
- return ret |= right;
+ RuleSet copy = *this;
+ return copy |= right;
}
-bool RuleManager::add_rule(std::string_view identifier, Rule::rule_group_t group) {
+bool RuleManager::add_rule(std::string_view identifier, Rule::rule_group_t group, std::string_view localisation_key) {
if (identifier.empty()) {
Logger::error("Invalid rule identifier - empty!");
return false;
}
- return rules.add_item({ identifier, group, rule_group_sizes[group]++ });
+ return rules.add_item({ identifier, group, rule_group_sizes[group]++, localisation_key });
}
bool RuleManager::setup_rules(BuildingTypeManager const& building_type_manager) {
@@ -156,10 +151,11 @@ bool RuleManager::setup_rules(BuildingTypeManager const& building_type_manager)
static const ordered_map<Rule::rule_group_t, std::vector<std::string_view>> hardcoded_rules {
{ ECONOMY, {
- "expand_factory", "open_factory", "destroy_factory", "pop_build_factory", "pop_expand_factory", "pop_open_factory",
- "can_subsidise", "factory_priority", "delete_factory_if_no_input", "build_factory_invest", "expand_factory_invest",
- "open_factory_invest", "build_railway_invest", "pop_build_factory_invest", "pop_expand_factory_invest",
- "can_invest_in_pop_projects", "allow_foreign_investment"
+ "build_railway", "build_factory", "expand_factory", "open_factory", "destroy_factory", "pop_build_factory",
+ "pop_expand_factory", "pop_open_factory", "can_subsidise", "factory_priority", "delete_factory_if_no_input",
+ "build_factory_invest", "expand_factory_invest", "open_factory_invest", "build_railway_invest",
+ "pop_build_factory_invest", "pop_expand_factory_invest", "pop_open_factory_invest", "can_invest_in_pop_projects",
+ "allow_foreign_investment"
} },
{ CITIZENSHIP, { "primary_culture_voting", "culture_voting", "all_voting" } },
{ SLAVERY, { "slavery_allowed" } },
@@ -183,16 +179,6 @@ bool RuleManager::setup_rules(BuildingTypeManager const& building_type_manager)
}
}
- for (std::string const& type : building_type_manager.get_building_type_types()) {
- std::string build_rule_string = "build_";
- if (type != "infrastructure") {
- build_rule_string += type;
- } else {
- build_rule_string += "railway";
- }
- ret &= add_rule(build_rule_string, ECONOMY);
- }
-
lock_rules();
return ret;
diff --git a/src/openvic-simulation/politics/Rule.hpp b/src/openvic-simulation/politics/Rule.hpp
index db0c926..0bbac82 100644
--- a/src/openvic-simulation/politics/Rule.hpp
+++ b/src/openvic-simulation/politics/Rule.hpp
@@ -28,8 +28,11 @@ namespace OpenVic {
private:
const rule_group_t PROPERTY(group);
+ std::string PROPERTY(localisation_key);
- Rule(std::string_view new_identifier, rule_group_t new_group, index_t new_index);
+ Rule(
+ std::string_view new_identifier, rule_group_t new_group, index_t new_index, std::string_view new_localisation_key
+ );
public:
Rule(Rule&&) = default;
@@ -62,12 +65,12 @@ namespace OpenVic {
void clear();
bool empty() const;
- rule_map_t const& get_rule_group(Rule::rule_group_t group, bool* successful = nullptr) const;
- bool get_rule(Rule const* rule, bool* successful = nullptr) const;
- bool has_rule(Rule const* rule) const;
+ rule_map_t const& get_rule_group(Rule::rule_group_t group, bool* rule_group_found = nullptr) const;
+ bool get_rule(Rule const& rule, bool* rule_found = nullptr) const;
+ bool has_rule(Rule const& rule) const;
/* Sets the rule to the specified value. Returns false if there was an existing rule, regardless of its value. */
- bool set_rule(Rule const* rule, bool value);
+ bool set_rule(Rule const& rule, bool value);
RuleSet& operator|=(RuleSet const& right);
RuleSet operator|(RuleSet const& right) const;
@@ -81,7 +84,7 @@ namespace OpenVic {
ordered_map<Rule::rule_group_t, size_t> rule_group_sizes;
public:
- bool add_rule(std::string_view identifier, Rule::rule_group_t group);
+ bool add_rule(std::string_view identifier, Rule::rule_group_t group, std::string_view localisation_key = {});
bool setup_rules(BuildingTypeManager const& building_type_manager);
diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp
index 9221485..dd829d9 100644
--- a/src/openvic-simulation/pop/Pop.cpp
+++ b/src/openvic-simulation/pop/Pop.cpp
@@ -642,8 +642,8 @@ bool PopManager::load_pop_bases_into_vector(
*non_integer_size = true;
}
- if (culture != nullptr && religion != nullptr && size >= 1) {
- vec.emplace_back(PopBase { type, *culture, *religion, size.to_int64_t(), militancy, consciousness, rebel_type });
+ if (culture != nullptr && religion != nullptr && size >= 1 && size <= std::numeric_limits<Pop::pop_size_t>::max()) {
+ vec.emplace_back(PopBase { type, *culture, *religion, size.to_int32_t(), militancy, consciousness, rebel_type });
} else {
Logger::warning(
"Some pop arguments are invalid: culture = ", culture, ", religion = ", religion, ", size = ", size
@@ -653,6 +653,8 @@ bool PopManager::load_pop_bases_into_vector(
}
bool PopManager::generate_modifiers(ModifierManager& modifier_manager) const {
+ using enum ModifierEffect::format_t;
+
bool ret = true;
for (Strata const& strata : get_stratas()) {
@@ -672,10 +674,6 @@ bool PopManager::generate_modifiers(ModifierManager& modifier_manager) const {
strata_modifier("_luxury_needs", false);
}
- for (PopType const& pop_type : get_pop_types()) {
- ret &= modifier_manager.add_modifier_effect(pop_type.get_identifier(), true);
- }
-
return ret;
}
diff --git a/src/openvic-simulation/pop/Pop.hpp b/src/openvic-simulation/pop/Pop.hpp
index e8cab42..59a7794 100644
--- a/src/openvic-simulation/pop/Pop.hpp
+++ b/src/openvic-simulation/pop/Pop.hpp
@@ -32,7 +32,7 @@ namespace OpenVic {
struct PopBase {
friend struct PopManager;
- using pop_size_t = int64_t;
+ using pop_size_t = int32_t;
protected:
PopType const& PROPERTY_ACCESS(type, protected);
diff --git a/src/openvic-simulation/research/Invention.cpp b/src/openvic-simulation/research/Invention.cpp
index 5ecfcdc..299cefb 100644
--- a/src/openvic-simulation/research/Invention.cpp
+++ b/src/openvic-simulation/research/Invention.cpp
@@ -18,7 +18,7 @@ Invention::Invention(
bool new_unlock_gas_defence,
ConditionScript&& new_limit,
ConditionalWeight&& new_chance
-) : Modifier { new_identifier, std::move(new_values) },
+) : Modifier { new_identifier, std::move(new_values), modifier_type_t::INVENTION },
news { new_news },
activated_units { std::move(new_activated_units) },
activated_buildings { std::move(new_activated_buildings) },
@@ -30,8 +30,10 @@ Invention::Invention(
bool Invention::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
ret &= limit.parse_script(false, definition_manager);
ret &= chance.parse_scripts(definition_manager);
+
return ret;
}
@@ -104,8 +106,10 @@ bool InventionManager::load_inventions_file(
bool InventionManager::parse_scripts(DefinitionManager const& definition_manager) {
bool ret = true;
+
for (Invention& invention : inventions.get_items()) {
ret &= invention.parse_scripts(definition_manager);
}
+
return ret;
}
diff --git a/src/openvic-simulation/research/Invention.hpp b/src/openvic-simulation/research/Invention.hpp
index 7c6c07b..58e4030 100644
--- a/src/openvic-simulation/research/Invention.hpp
+++ b/src/openvic-simulation/research/Invention.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/scripts/ConditionalWeight.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/types/OrderedContainers.hpp"
diff --git a/src/openvic-simulation/research/Technology.cpp b/src/openvic-simulation/research/Technology.cpp
index 89c4a71..a5256f3 100644
--- a/src/openvic-simulation/research/Technology.cpp
+++ b/src/openvic-simulation/research/Technology.cpp
@@ -19,7 +19,7 @@ Technology::Technology(
building_set_t&& new_activated_buildings,
ModifierValue&& new_values,
ConditionalWeight&& new_ai_chance
-) : Modifier { new_identifier, std::move(new_values) },
+) : Modifier { new_identifier, std::move(new_values), modifier_type_t::TECHNOLOGY },
area { new_area },
year { new_year },
cost { new_cost },
@@ -34,7 +34,7 @@ bool Technology::parse_scripts(DefinitionManager const& definition_manager) {
}
TechnologySchool::TechnologySchool(std::string_view new_identifier, ModifierValue&& new_values)
- : Modifier { new_identifier, std::move(new_values) } {}
+ : Modifier { new_identifier, std::move(new_values), modifier_type_t::TECH_SCHOOL } {}
bool TechnologyManager::add_technology_folder(std::string_view identifier) {
if (identifier.empty()) {
@@ -196,12 +196,14 @@ bool TechnologyManager::load_technologies_file(
}
bool TechnologyManager::generate_modifiers(ModifierManager& modifier_manager) const {
+ using enum ModifierEffect::format_t;
+
bool ret = true;
for (TechnologyFolder const& folder : get_technology_folders()) {
- ret &= modifier_manager.add_modifier_effect(
- StringUtils::append_string_views(folder.get_identifier(), "_research_bonus"), true
- );
+ const std::string modifier_identifier = StringUtils::append_string_views(folder.get_identifier(), "_research_bonus");
+
+ ret &= modifier_manager.add_modifier_effect(modifier_identifier, true, PROPORTION_DECIMAL, modifier_identifier);
}
return ret;
diff --git a/src/openvic-simulation/research/Technology.hpp b/src/openvic-simulation/research/Technology.hpp
index 3afeb0b..3d0a438 100644
--- a/src/openvic-simulation/research/Technology.hpp
+++ b/src/openvic-simulation/research/Technology.hpp
@@ -5,7 +5,7 @@
#include "openvic-simulation/country/CountryInstance.hpp"
#include "openvic-simulation/economy/BuildingType.hpp"
#include "openvic-simulation/military/UnitType.hpp"
-#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/modifier/Modifier.hpp"
#include "openvic-simulation/scripts/ConditionalWeight.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/OrderedContainers.hpp"
diff --git a/src/openvic-simulation/types/HasIdentifier.hpp b/src/openvic-simulation/types/HasIdentifier.hpp
index 74961e3..bbd9771 100644
--- a/src/openvic-simulation/types/HasIdentifier.hpp
+++ b/src/openvic-simulation/types/HasIdentifier.hpp
@@ -102,6 +102,9 @@ namespace OpenVic {
using HasIdentifierAndColour = _HasIdentifierAndColour<colour_t>;
using HasIdentifierAndAlphaColour = _HasIdentifierAndColour<colour_argb_t>;
+ template<typename T>
+ concept HasGetIdentifierAndGetColour = HasGetIdentifier<T> && HasGetColour<T>;
+
template<std::unsigned_integral T = size_t>
class HasIndex {
public:
diff --git a/src/openvic-simulation/types/IndexedMap.hpp b/src/openvic-simulation/types/IndexedMap.hpp
index 5682c0e..73ff313 100644
--- a/src/openvic-simulation/types/IndexedMap.hpp
+++ b/src/openvic-simulation/types/IndexedMap.hpp
@@ -18,6 +18,8 @@ namespace OpenVic {
using value_const_ref_t = container_t::const_reference;
using keys_t = std::vector<key_t>;
+ using key_type = key_t; // To match tsl::ordered_map's key_type
+
using container_t::operator[];
using container_t::size;
using container_t::begin;
diff --git a/src/openvic-simulation/utility/StringUtils.hpp b/src/openvic-simulation/utility/StringUtils.hpp
index bec11ec..53feb9d 100644
--- a/src/openvic-simulation/utility/StringUtils.hpp
+++ b/src/openvic-simulation/utility/StringUtils.hpp
@@ -160,6 +160,22 @@ namespace OpenVic::StringUtils {
return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), ichar_equals);
}
+ inline constexpr std::string string_tolower(std::string_view str) {
+ std::string result { str };
+ std::transform(result.begin(), result.end(), result.begin(),
+ [](unsigned char c) -> unsigned char { return std::tolower(c); }
+ );
+ return result;
+ }
+
+ inline constexpr std::string string_toupper(std::string_view str) {
+ std::string result { str };
+ std::transform(result.begin(), result.end(), result.begin(),
+ [](unsigned char c) -> unsigned char { return std::toupper(c); }
+ );
+ return result;
+ }
+
inline constexpr std::string_view get_filename(std::string_view path) {
size_t pos = path.size();
while (pos > 0 && path[pos - 1] != '/' && path[pos - 1] != '\\') {