aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author hop311 <hop3114@gmail.com>2023-12-02 16:48:08 +0100
committer hop311 <hop3114@gmail.com>2023-12-02 20:14:29 +0100
commit4a899c1a9e83ab9476b85522751081be434caa35 (patch)
treef1f6276c91beceecdfd9b09083d1c91ea8b41b60
parentcd6875d5e0ca5e2545fd0e1647678cd18a6c81c2 (diff)
Crime+event modifier loading + misc UI backend
-rw-r--r--src/openvic-simulation/GameManager.cpp2
-rw-r--r--src/openvic-simulation/GameManager.hpp2
-rw-r--r--src/openvic-simulation/country/Country.hpp2
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp132
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.hpp10
-rw-r--r--src/openvic-simulation/economy/Good.cpp9
-rw-r--r--src/openvic-simulation/economy/Good.hpp8
-rw-r--r--src/openvic-simulation/economy/ProductionType.cpp9
-rw-r--r--src/openvic-simulation/economy/ProductionType.hpp1
-rw-r--r--src/openvic-simulation/history/DiplomaticHistory.cpp4
-rw-r--r--src/openvic-simulation/interface/GFX.cpp13
-rw-r--r--src/openvic-simulation/interface/GFX.hpp3
-rw-r--r--src/openvic-simulation/map/Map.cpp12
-rw-r--r--src/openvic-simulation/map/Map.hpp7
-rw-r--r--src/openvic-simulation/map/Province.cpp3
-rw-r--r--src/openvic-simulation/map/Province.hpp1
-rw-r--r--src/openvic-simulation/map/TerrainType.cpp1
-rw-r--r--src/openvic-simulation/military/Deployment.hpp2
-rw-r--r--src/openvic-simulation/military/Unit.cpp16
-rw-r--r--src/openvic-simulation/military/Wargoal.hpp36
-rw-r--r--src/openvic-simulation/misc/GameAdvancementHook.cpp (renamed from src/openvic-simulation/GameAdvancementHook.cpp)4
-rw-r--r--src/openvic-simulation/misc/GameAdvancementHook.hpp (renamed from src/openvic-simulation/GameAdvancementHook.hpp)0
-rw-r--r--src/openvic-simulation/misc/Modifier.cpp124
-rw-r--r--src/openvic-simulation/misc/Modifier.hpp45
-rw-r--r--src/openvic-simulation/politics/Government.cpp11
-rw-r--r--src/openvic-simulation/politics/Government.hpp1
-rw-r--r--src/openvic-simulation/politics/PoliticsManager.hpp3
-rw-r--r--src/openvic-simulation/politics/Rebel.cpp109
-rw-r--r--src/openvic-simulation/politics/Rebel.hpp16
-rw-r--r--src/openvic-simulation/pop/Pop.cpp74
-rw-r--r--src/openvic-simulation/pop/Pop.hpp19
-rw-r--r--src/openvic-simulation/tech/Technology.cpp77
-rw-r--r--src/openvic-simulation/tech/Technology.hpp25
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp4
-rw-r--r--src/openvic-simulation/types/Date.cpp15
-rw-r--r--src/openvic-simulation/types/Date.hpp5
-rw-r--r--src/openvic-simulation/types/IdentifierRegistry.hpp86
-rw-r--r--src/openvic-simulation/utility/Getters.hpp14
38 files changed, 573 insertions, 332 deletions
diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp
index 397b729..04e680d 100644
--- a/src/openvic-simulation/GameManager.cpp
+++ b/src/openvic-simulation/GameManager.cpp
@@ -74,7 +74,7 @@ bool GameManager::expand_building(Province::index_t province_index, std::string_
return province->expand_building(building_type_identifier);
}
-static constexpr colour_t ALPHA_VALUE = float_to_alpha_value(0.5f);
+static constexpr colour_t ALPHA_VALUE = float_to_alpha_value(0.7f);
static constexpr Mapmode::base_stripe_t combine_base_stripe(colour_t base, colour_t stripe) {
return (static_cast<Mapmode::base_stripe_t>(stripe) << (sizeof(colour_t) * 8)) | base;
diff --git a/src/openvic-simulation/GameManager.hpp b/src/openvic-simulation/GameManager.hpp
index 1755900..ed17c30 100644
--- a/src/openvic-simulation/GameManager.hpp
+++ b/src/openvic-simulation/GameManager.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "openvic-simulation/GameAdvancementHook.hpp"
+#include "openvic-simulation/misc/GameAdvancementHook.hpp"
#include "openvic-simulation/misc/Modifier.hpp"
#include "openvic-simulation/country/Country.hpp"
#include "openvic-simulation/economy/EconomyManager.hpp"
diff --git a/src/openvic-simulation/country/Country.hpp b/src/openvic-simulation/country/Country.hpp
index fb58dff..5d25b33 100644
--- a/src/openvic-simulation/country/Country.hpp
+++ b/src/openvic-simulation/country/Country.hpp
@@ -73,6 +73,8 @@ namespace OpenVic {
Country(Country&&) = default;
IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(party, parties)
+
+ // TODO - get_colour including alternative colours
};
struct CountryManager {
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp
index 7715104..6bf43f6 100644
--- a/src/openvic-simulation/dataloader/Dataloader.cpp
+++ b/src/openvic-simulation/dataloader/Dataloader.cpp
@@ -407,17 +407,15 @@ fs::path Dataloader::lookup_file(std::string_view path, bool print_error) const
return {};
}
-fs::path Dataloader::lookup_image_file_or_dds(std::string_view path) const {
- fs::path ret = lookup_file(path, false);
- if (ret.empty()) {
- // TODO - change search order so root order takes priority over extension replacement order
- ret = lookup_file(append_string_views(StringUtils::remove_extension(path), ".dds"), false);
+fs::path Dataloader::lookup_image_file(std::string_view path) const {
+ const std::string_view path_without_extension = StringUtils::remove_extension(path);
+ if (path.substr(path_without_extension.size()) == ".tga") {
+ const fs::path ret = lookup_file(append_string_views(path_without_extension, ".dds"), false);
if (!ret.empty()) {
return ret;
}
- Logger::error("Image lookup for ", path, " failed!");
}
- return ret;
+ return lookup_file(path);
}
template<typename _DirIterator, typename _UniqueKey>
@@ -618,37 +616,41 @@ bool Dataloader::_load_pop_types(
bool Dataloader::_load_units(GameManager& game_manager) const {
static constexpr std::string_view units_directory = "units";
- UnitManager& unit_manager = game_manager.get_military_manager().get_unit_manager();
+ UnitManager& unit_manager = game_manager.get_military_manager().get_unit_manager();
bool ret = apply_to_files(
lookup_files_in_dir(units_directory, ".txt"),
[&game_manager, &unit_manager](fs::path const& file) -> bool {
return unit_manager.load_unit_file(game_manager.get_economy_manager().get_good_manager(), parse_defines(file).get_file_node());
}
);
-
+
unit_manager.lock_units();
-
+
if(!unit_manager.generate_modifiers(game_manager.get_modifier_manager())) {
Logger::error("Failed to generate unit-based modifiers!");
- ret &= false;
+ ret = false;
}
return ret;
}
-bool Dataloader::_load_goods(GameManager& game_manager, std::string_view goods_file) const {
+bool Dataloader::_load_goods(GameManager& game_manager) const {
+ static constexpr std::string_view goods_file = "common/goods.txt";
+
GoodManager& good_manager = game_manager.get_economy_manager().get_good_manager();
bool ret = good_manager.load_goods_file(parse_defines(lookup_file(goods_file)).get_file_node());
if(!good_manager.generate_modifiers(game_manager.get_modifier_manager())) {
Logger::error("Failed to generate good-based modifiers!");
- ret &= false;
+ ret = false;
}
-
+
return ret;
}
-bool Dataloader::_load_technologies(GameManager& game_manager, std::string_view technology_file) const {
+bool Dataloader::_load_technologies(GameManager& game_manager) const {
+ static constexpr std::string_view technology_file = "common/technology.txt";
+
TechnologyManager& technology_manager = game_manager.get_technology_manager();
bool ret = true;
@@ -889,28 +891,26 @@ bool Dataloader::_load_map_dir(GameManager& game_manager) const {
}
bool Dataloader::load_defines(GameManager& game_manager) const {
- static const std::string defines_file = "common/defines.lua";
- static const std::string buildings_file = "common/buildings.txt";
- static const std::string bookmark_file = "common/bookmarks.txt";
- static const std::string countries_file = "common/countries.txt";
- static const std::string culture_file = "common/cultures.txt";
- static const std::string goods_file = "common/goods.txt";
- static const std::string governments_file = "common/governments.txt";
- static const std::string graphical_culture_type_file = "common/graphicalculturetype.txt";
- static const std::string ideology_file = "common/ideologies.txt";
- static const std::string issues_file = "common/issues.txt";
- static const std::string national_foci_file = "common/national_focus.txt";
- static const std::string national_values_file = "common/nationalvalues.txt";
- static const std::string production_types_file = "common/production_types.txt";
- static const std::string religion_file = "common/religion.txt";
- static const std::string technology_file = "common/technology.txt";
- static const std::string leader_traits_file = "common/traits.txt";
- static const std::string cb_types_file = "common/cb_types.txt";
- static const std::string crime_modifiers_file = "common/crime.txt";
- static const std::string event_modifiers_file = "common/event_modifiers.txt";
- static const std::string static_modifiers_file = "common/static_modifiers.txt";
- static const std::string triggered_modifiers_file = "common/triggered_modifiers.txt";
- static const std::string rebel_types_file = "common/rebel_types.txt";
+ static constexpr std::string_view defines_file = "common/defines.lua";
+ static constexpr std::string_view buildings_file = "common/buildings.txt";
+ static constexpr std::string_view bookmark_file = "common/bookmarks.txt";
+ static constexpr std::string_view countries_file = "common/countries.txt";
+ static constexpr std::string_view culture_file = "common/cultures.txt";
+ static constexpr std::string_view governments_file = "common/governments.txt";
+ static constexpr std::string_view graphical_culture_type_file = "common/graphicalculturetype.txt";
+ static constexpr std::string_view ideology_file = "common/ideologies.txt";
+ static constexpr std::string_view issues_file = "common/issues.txt";
+ static constexpr std::string_view national_foci_file = "common/national_focus.txt";
+ static constexpr std::string_view national_values_file = "common/nationalvalues.txt";
+ static constexpr std::string_view production_types_file = "common/production_types.txt";
+ static constexpr std::string_view religion_file = "common/religion.txt";
+ static constexpr std::string_view leader_traits_file = "common/traits.txt";
+ static constexpr std::string_view cb_types_file = "common/cb_types.txt";
+ static constexpr std::string_view crime_modifiers_file = "common/crime.txt";
+ static constexpr std::string_view event_modifiers_file = "common/event_modifiers.txt";
+ static constexpr std::string_view static_modifiers_file = "common/static_modifiers.txt";
+ static constexpr std::string_view triggered_modifiers_file = "common/triggered_modifiers.txt";
+ static constexpr std::string_view rebel_types_file = "common/rebel_types.txt";
bool ret = true;
@@ -922,35 +922,11 @@ bool Dataloader::load_defines(GameManager& game_manager) const {
Logger::error("Failed to set up modifier effects!");
ret = false;
}
- if (!game_manager.get_modifier_manager().load_crime_modifiers(
- parse_defines(lookup_file(crime_modifiers_file)).get_file_node()
- )) {
- Logger::error("Failed to load crime modifiers!");
- ret = false;
- }
- if (!game_manager.get_modifier_manager().load_event_modifiers(
- parse_defines(lookup_file(event_modifiers_file)).get_file_node()
- )) {
- Logger::error("Failed to load event modifiers!");
- ret = false;
- }
- if (!game_manager.get_modifier_manager().load_static_modifiers(
- parse_defines(lookup_file(static_modifiers_file)).get_file_node()
- )) {
- Logger::error("Failed to load static modifiers!");
- ret = false;
- }
- if (!game_manager.get_modifier_manager().load_triggered_modifiers(
- parse_defines(lookup_file(triggered_modifiers_file)).get_file_node()
- )) {
- Logger::error("Failed to load triggered modifiers!");
- ret = false;
- }
if (!game_manager.get_define_manager().load_defines_file(parse_lua_defines(lookup_file(defines_file)).get_file_node())) {
Logger::error("Failed to load defines!");
ret = false;
}
- if (!_load_goods(game_manager, goods_file)) {
+ if (!_load_goods(game_manager)) {
Logger::error("Failed to load goods!");
ret = false;
}
@@ -1025,7 +1001,31 @@ bool Dataloader::load_defines(GameManager& game_manager) const {
Logger::error("Failed to load buildings!");
ret = false;
}
- if (!_load_technologies(game_manager, technology_file)) {
+ if (!_load_technologies(game_manager)) {
+ ret = false;
+ }
+ if (!game_manager.get_modifier_manager().load_crime_modifiers(
+ parse_defines(lookup_file(crime_modifiers_file)).get_file_node()
+ )) {
+ Logger::error("Failed to load crime modifiers!");
+ ret = false;
+ }
+ if (!game_manager.get_modifier_manager().load_event_modifiers(
+ parse_defines(lookup_file(event_modifiers_file)).get_file_node()
+ )) {
+ Logger::error("Failed to load event modifiers!");
+ ret = false;
+ }
+ if (!game_manager.get_modifier_manager().load_static_modifiers(
+ parse_defines(lookup_file(static_modifiers_file)).get_file_node()
+ )) {
+ Logger::error("Failed to load static modifiers!");
+ ret = false;
+ }
+ if (!game_manager.get_modifier_manager().load_triggered_modifiers(
+ parse_defines(lookup_file(triggered_modifiers_file)).get_file_node()
+ )) {
+ Logger::error("Failed to load triggered modifiers!");
ret = false;
}
if (!_load_map_dir(game_manager)) {
@@ -1056,11 +1056,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const {
Logger::error("Failed to load countries!");
ret = false;
}
- if (!game_manager.get_politics_manager().get_rebel_manager().load_rebels_file(
- game_manager.get_politics_manager().get_ideology_manager(),
- game_manager.get_politics_manager().get_government_type_manager(),
- parse_defines(lookup_file(rebel_types_file)).get_file_node()
- )) {
+ if (!game_manager.get_politics_manager().load_rebels_file(parse_defines(lookup_file(rebel_types_file)).get_file_node())) {
Logger::error("Failed to load rebel types!");
ret = false;
}
diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp
index b5ec553..a2e377b 100644
--- a/src/openvic-simulation/dataloader/Dataloader.hpp
+++ b/src/openvic-simulation/dataloader/Dataloader.hpp
@@ -27,8 +27,8 @@ namespace OpenVic {
bool _load_interface_files(UIManager& ui_manager) const;
bool _load_pop_types(PopManager& pop_manager, UnitManager const& unit_manager, GoodManager const& good_manager) const;
bool _load_units(GameManager& game_manager) const;
- bool _load_goods(GameManager& game_manager, std::string_view goods_file) const;
- bool _load_technologies(GameManager& game_manager, std::string_view technology_file) const;
+ bool _load_goods(GameManager& game_manager) const;
+ bool _load_technologies(GameManager& game_manager) const;
bool _load_map_dir(GameManager& game_manager) const;
bool _load_history(GameManager& game_manager, bool unused_history_file_warnings) const;
@@ -79,8 +79,10 @@ namespace OpenVic {
* DAT-24
*/
fs::path lookup_file(std::string_view path, bool print_error = true) const;
- /* Checks alternate file endings, e.g. if "*.tga" doesn't exist then try "*.dds" */
- fs::path lookup_image_file_or_dds(std::string_view path) const;
+ /* If the path ends with the extension ".tga", then this function will first try to load the file with the extension
+ * replaced with ".dds", and if that fails it will try the original ".tga" version. Paths not ending with ".tga" will
+ * just be passed to lookup_file. */
+ fs::path lookup_image_file(std::string_view path) const;
path_vector_t lookup_files_in_dir(std::string_view path, fs::path const& extension) const;
path_vector_t lookup_files_in_dir_recursive(std::string_view path, fs::path const& extension) const;
path_vector_t lookup_basic_indentifier_prefixed_files_in_dir(std::string_view path, fs::path const& extension) const;
diff --git a/src/openvic-simulation/economy/Good.cpp b/src/openvic-simulation/economy/Good.cpp
index 739374b..2aa5d42 100644
--- a/src/openvic-simulation/economy/Good.cpp
+++ b/src/openvic-simulation/economy/Good.cpp
@@ -8,9 +8,9 @@ using namespace OpenVic::NodeTools;
GoodCategory::GoodCategory(std::string_view new_identifier) : HasIdentifier { new_identifier } {}
Good::Good(
- std::string_view new_identifier, colour_t new_colour, GoodCategory const& new_category, price_t new_base_price,
- bool new_available_from_start, bool new_tradeable, bool new_money, bool new_overseas_penalty
-) : HasIdentifierAndColour { new_identifier, new_colour, false, false }, category { new_category },
+ std::string_view new_identifier, colour_t new_colour, index_t new_index, GoodCategory const& new_category,
+ price_t new_base_price, bool new_available_from_start, bool new_tradeable, bool new_money, bool new_overseas_penalty
+) : HasIdentifierAndColour { new_identifier, new_colour, false, false }, index { new_index }, category { new_category },
base_price { new_base_price }, available_from_start { new_available_from_start }, tradeable { new_tradeable },
money { new_money }, overseas_penalty { new_overseas_penalty } {
assert(base_price > NULL_PRICE);
@@ -48,7 +48,7 @@ bool GoodManager::add_good(
return false;
}
return goods.add_item({
- identifier, colour, category, base_price, available_from_start,
+ identifier, colour, get_good_count(), category, base_price, available_from_start,
tradeable, money, overseas_penalty
});
}
@@ -105,7 +105,6 @@ bool GoodManager::load_goods_file(ast::NodeCPtr root) {
ret &= modifier_manager.add_modifier_effect(modifier_name, true, ModifierEffect::format_t::PROPORTION_DECIMAL); \
}
-
bool GoodManager::generate_modifiers(ModifierManager& modifier_manager) {
bool ret = true;
GOOD_MODIFIER("factory_goods_output");
diff --git a/src/openvic-simulation/economy/Good.hpp b/src/openvic-simulation/economy/Good.hpp
index 8a239d5..1537514 100644
--- a/src/openvic-simulation/economy/Good.hpp
+++ b/src/openvic-simulation/economy/Good.hpp
@@ -31,12 +31,15 @@ namespace OpenVic {
struct Good : HasIdentifierAndColour {
friend struct GoodManager;
+ using index_t = size_t;
+
using price_t = fixed_point_t;
static constexpr price_t NULL_PRICE = fixed_point_t::_0();
using good_map_t = fixed_point_map_t<Good const*>;
private:
+ const index_t PROPERTY(index);
GoodCategory const& PROPERTY(category);
const price_t PROPERTY(base_price);
const bool PROPERTY_CUSTOM_PREFIX(available_from_start, is);
@@ -48,8 +51,9 @@ namespace OpenVic {
bool PROPERTY_RW(available);
Good(
- std::string_view new_identifier, colour_t new_colour, GoodCategory const& new_category, price_t new_base_price,
- bool new_available_from_start, bool new_tradeable, bool new_money, bool new_overseas_penalty
+ std::string_view new_identifier, colour_t new_colour, index_t new_index, GoodCategory const& new_category,
+ price_t new_base_price, bool new_available_from_start, bool new_tradeable, bool new_money,
+ bool new_overseas_penalty
);
public:
diff --git a/src/openvic-simulation/economy/ProductionType.cpp b/src/openvic-simulation/economy/ProductionType.cpp
index 6bd3858..a862b12 100644
--- a/src/openvic-simulation/economy/ProductionType.cpp
+++ b/src/openvic-simulation/economy/ProductionType.cpp
@@ -14,7 +14,7 @@ ProductionType::ProductionType(
input_goods { std::move(input_goods) }, output_goods { output_goods }, value { value }, bonuses { std::move(bonuses) },
efficiency { std::move(efficiency) }, coastal { coastal }, farm { farm }, mine { mine } {}
-ProductionTypeManager::ProductionTypeManager() : production_types { "production types" } {}
+ProductionTypeManager::ProductionTypeManager() : production_types { "production types" }, rgo_owner_sprite { 0 } {}
node_callback_t ProductionTypeManager::_expect_employed_pop(
GoodManager const& good_manager, PopManager const& pop_manager, callback_t<EmployedPop&&> cb
@@ -102,10 +102,15 @@ bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS) {
return false;
}
- return production_types.add_item({
+ const bool ret = production_types.add_item({
identifier, owner, employees, type, workforce, std::move(input_goods),
output_goods, value, std::move(bonuses), std::move(efficiency), coastal, farm, mine
});
+ if (rgo_owner_sprite <= 0 && ret && type == ProductionType::type_t::RGO && owner.get_pop_type() != nullptr) {
+ /* Set rgo owner sprite to that of the first RGO owner we find. */
+ rgo_owner_sprite = owner.get_pop_type()->get_sprite();
+ }
+ return ret;
}
#define PARSE_NODE \
diff --git a/src/openvic-simulation/economy/ProductionType.hpp b/src/openvic-simulation/economy/ProductionType.hpp
index dd0b2fd..bce3698 100644
--- a/src/openvic-simulation/economy/ProductionType.hpp
+++ b/src/openvic-simulation/economy/ProductionType.hpp
@@ -67,6 +67,7 @@ namespace OpenVic {
struct ProductionTypeManager {
private:
IdentifierRegistry<ProductionType> production_types;
+ PopType::sprite_t PROPERTY(rgo_owner_sprite);
NodeTools::node_callback_t _expect_employed_pop(
GoodManager const& good_manager, PopManager const& pop_manager, NodeTools::callback_t<EmployedPop&&> cb
diff --git a/src/openvic-simulation/history/DiplomaticHistory.cpp b/src/openvic-simulation/history/DiplomaticHistory.cpp
index 5c560ea..79ac907 100644
--- a/src/openvic-simulation/history/DiplomaticHistory.cpp
+++ b/src/openvic-simulation/history/DiplomaticHistory.cpp
@@ -186,7 +186,7 @@ bool DiplomaticHistoryManager::load_war_history_file(GameManager& game_manager,
}
if (participant_to_remove == nullptr) {
- Logger::error("In history of war ", name, " at date ", current_date.to_string(), ": Attempted to remove attacking country ", country.get_identifier(), " which was not present!");
+ Logger::error("In history of war ", name, " at date ", current_date.to_string(), ": Attempted to remove attacking country ", country.get_identifier(), " which was not present!");
return false;
}
@@ -204,7 +204,7 @@ bool DiplomaticHistoryManager::load_war_history_file(GameManager& game_manager,
}
if (participant_to_remove == nullptr) {
- Logger::error("In history of war ", name, " at date ", current_date.to_string(), ": Attempted to remove attacking country ", country.get_identifier(), " which was not present!");
+ Logger::error("In history of war ", name, " at date ", current_date.to_string(), ": Attempted to remove attacking country ", country.get_identifier(), " which was not present!");
return false;
}
diff --git a/src/openvic-simulation/interface/GFX.cpp b/src/openvic-simulation/interface/GFX.cpp
index f4e2074..927b832 100644
--- a/src/openvic-simulation/interface/GFX.cpp
+++ b/src/openvic-simulation/interface/GFX.cpp
@@ -42,18 +42,15 @@ bool TextureSprite::_fill_key_map(key_map_t& key_map) {
return ret;
}
-ProgressBar::ProgressBar()
-: back_colour {}, back_texture_file {},
- progress_colour {}, progress_texture_file {},
- size {} {}
+ProgressBar::ProgressBar() : back_colour {}, progress_colour {} {}
bool ProgressBar::_fill_key_map(key_map_t& key_map) {
bool ret = Sprite::_fill_key_map(key_map);
ret &= add_key_map_entries(key_map,
"color", ONE_EXACTLY, expect_colour(assign_variable_callback(back_colour)),
"colortwo", ONE_EXACTLY, expect_colour(assign_variable_callback(progress_colour)),
- "textureFile1", ZERO_OR_ONE, expect_string(assign_variable_callback_string(back_texture_file)),
- "textureFile2", ZERO_OR_ONE, expect_string(assign_variable_callback_string(progress_texture_file)),
+ "textureFile1", ZERO_OR_ONE, expect_string(assign_variable_callback_string(progress_texture_file)),
+ "textureFile2", ZERO_OR_ONE, expect_string(assign_variable_callback_string(back_texture_file)),
"size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)),
"effectFile", ONE_EXACTLY, success_callback,
@@ -84,12 +81,12 @@ bool LineChart::_fill_key_map(key_map_t& key_map) {
return ret;
}
-MaskedFlag::MaskedFlag() : texture_file {}, mask_file {} {}
+MaskedFlag::MaskedFlag() : overlay_file {}, mask_file {} {}
bool MaskedFlag::_fill_key_map(key_map_t& key_map) {
bool ret = Sprite::_fill_key_map(key_map);
ret &= add_key_map_entries(key_map,
- "textureFile1", ONE_EXACTLY, expect_string(assign_variable_callback_string(texture_file)),
+ "textureFile1", ONE_EXACTLY, expect_string(assign_variable_callback_string(overlay_file)),
"textureFile2", ONE_EXACTLY, expect_string(assign_variable_callback_string(mask_file)),
"effectFile", ONE_EXACTLY, success_callback,
"allwaystransparent", ZERO_OR_ONE, success_callback,
diff --git a/src/openvic-simulation/interface/GFX.hpp b/src/openvic-simulation/interface/GFX.hpp
index 2422e24..ff27613 100644
--- a/src/openvic-simulation/interface/GFX.hpp
+++ b/src/openvic-simulation/interface/GFX.hpp
@@ -117,11 +117,10 @@ namespace OpenVic::GFX {
OV_DETAIL_GET_TYPE
};
-
class MaskedFlag final : public Sprite {
friend std::unique_ptr<MaskedFlag> std::make_unique<MaskedFlag>();
- std::string PROPERTY(texture_file)
+ std::string PROPERTY(overlay_file)
std::string PROPERTY(mask_file);
protected:
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index 549e539..f854cab 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -141,14 +141,6 @@ bool Map::add_region(std::string_view identifier, std::vector<std::string_view>
return ret;
}
-Province* Map::get_province_by_index(Province::index_t index) {
- return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr;
-}
-
-Province const* Map::get_province_by_index(Province::index_t index) const {
- return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr;
-}
-
Province::index_t Map::get_index_from_colour(colour_t colour) const {
const colour_index_map_t::const_iterator it = colour_index_map.find(colour);
if (it != colour_index_map.end()) {
@@ -229,10 +221,6 @@ bool Map::add_mapmode(std::string_view identifier, Mapmode::colour_func_t colour
return mapmodes.add_item({ identifier, mapmodes.size(), colour_func });
}
-Mapmode const* Map::get_mapmode_by_index(size_t index) const {
- return mapmodes.get_item_by_index(index);
-}
-
bool Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) const {
if (target == nullptr) {
Logger::error("Mapmode colour target pointer is null!");
diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp
index 0999145..638d7a5 100644
--- a/src/openvic-simulation/map/Map.hpp
+++ b/src/openvic-simulation/map/Map.hpp
@@ -73,15 +73,13 @@ namespace OpenVic {
Map();
bool add_province(std::string_view identifier, colour_t colour);
- IDENTIFIER_REGISTRY_ACCESSORS(province)
- IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(province)
+ IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_INDEX_OFFSET(province, 1)
+ IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_INDEX_OFFSET(province, 1);
bool set_water_province(std::string_view identifier);
bool set_water_province_list(std::vector<std::string_view> const& list);
void lock_water_provinces();
- Province* get_province_by_index(Province::index_t index);
- Province const* get_province_by_index(Province::index_t index) const;
Province::index_t get_province_index_at(size_t x, size_t y) const;
bool set_max_provinces(Province::index_t new_max_provinces);
Province::index_t get_max_provinces() const;
@@ -99,7 +97,6 @@ namespace OpenVic {
bool add_mapmode(std::string_view identifier, Mapmode::colour_func_t colour_func);
IDENTIFIER_REGISTRY_ACCESSORS(mapmode)
- Mapmode const* get_mapmode_by_index(size_t index) const;
/* The mapmode colour image contains of a list of base colours and stripe colours. Each colour is four bytes
* in RGBA format, with the alpha value being used to interpolate with the terrain colour, so A = 0 is fully terrain
diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp
index c2d2da0..193b1f9 100644
--- a/src/openvic-simulation/map/Province.cpp
+++ b/src/openvic-simulation/map/Province.cpp
@@ -10,7 +10,8 @@ Province::Province(
) : HasIdentifierAndColour { new_identifier, new_colour, true, false }, index { new_index },
region { nullptr }, on_map { false }, has_region { false }, water { false }, default_terrain_type { nullptr },
terrain_type { nullptr }, life_rating { 0 }, colony_status { colony_status_t::STATE }, owner { nullptr },
- controller { nullptr }, slave { false }, buildings { "buildings", false }, rgo { nullptr }, total_population { 0 } {
+ controller { nullptr }, slave { false }, crime { nullptr }, rgo { nullptr }, buildings { "buildings", false },
+ total_population { 0 } {
assert(index != NULL_INDEX);
}
diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp
index af0bed4..a57f914 100644
--- a/src/openvic-simulation/map/Province.hpp
+++ b/src/openvic-simulation/map/Province.hpp
@@ -78,6 +78,7 @@ namespace OpenVic {
Country const* PROPERTY(controller);
std::vector<Country const*> PROPERTY(cores);
bool PROPERTY(slave);
+ Crime const* PROPERTY_RW(crime);
// TODO - change this into a factory-like structure
Good const* PROPERTY(rgo);
IdentifierRegistry<BuildingInstance> buildings;
diff --git a/src/openvic-simulation/map/TerrainType.cpp b/src/openvic-simulation/map/TerrainType.cpp
index 3048b66..ae10474 100644
--- a/src/openvic-simulation/map/TerrainType.cpp
+++ b/src/openvic-simulation/map/TerrainType.cpp
@@ -10,7 +10,6 @@ TerrainType::TerrainType(
) : HasIdentifierAndColour { new_identifier, new_colour, false, false }, modifier { std::move(new_modifier) },
is_water { new_is_water } {}
-
TerrainTypeMapping::TerrainTypeMapping(
std::string_view new_identifier, TerrainType const& new_type, std::vector<index_t>&& new_terrain_indicies,
index_t new_priority, bool new_has_texture
diff --git a/src/openvic-simulation/military/Deployment.hpp b/src/openvic-simulation/military/Deployment.hpp
index ead324e..597f727 100644
--- a/src/openvic-simulation/military/Deployment.hpp
+++ b/src/openvic-simulation/military/Deployment.hpp
@@ -99,7 +99,7 @@ namespace OpenVic {
bool add_deployment(
std::string_view path, std::vector<Army>&& armies, std::vector<Navy>&& navies, std::vector<Leader>&& leaders
);
- IDENTIFIER_REGISTRY_ACCESSORS(deployment)
+ IDENTIFIER_REGISTRY_ACCESSORS(deployment)
bool load_oob_file(
GameManager const& game_manager, Dataloader const& dataloader, std::string_view history_path,
diff --git a/src/openvic-simulation/military/Unit.cpp b/src/openvic-simulation/military/Unit.cpp
index 1c4efcf..7995aeb 100644
--- a/src/openvic-simulation/military/Unit.cpp
+++ b/src/openvic-simulation/military/Unit.cpp
@@ -132,7 +132,7 @@ bool UnitManager::load_unit_file(GoodManager const& good_manager, ast::NodeCPtr
bool primary_culture = false;
std::string_view sprite_override {}, sprite_mount {}, sprite_mount_attach_node {};
fixed_point_t reconnaissance = 0, attack = 0, defence = 0, discipline = 0, support = 0, maneuver = 0, siege = 0;
-
+
ret &= add_key_map_entries(key_map,
"primary_culture", ZERO_OR_ONE, expect_bool(assign_variable_callback(primary_culture)),
"sprite_override", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_override)),
@@ -146,9 +146,9 @@ bool UnitManager::load_unit_file(GoodManager const& good_manager, ast::NodeCPtr
"maneuver", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(maneuver)),
"siege", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(siege))
);
-
+
ret &= expect_dictionary_key_map(key_map)(value);
-
+
ret &= add_land_unit(key, UNIT_ARGS, LAND_ARGS);
return ret;
@@ -180,9 +180,9 @@ bool UnitManager::load_unit_file(GoodManager const& good_manager, ast::NodeCPtr
);
ret &= expect_dictionary_key_map(key_map)(value);
-
+
ret &= add_naval_unit(key, UNIT_ARGS, NAVY_ARGS);
-
+
return ret;
}
default: Logger::error("Unknown unit type for ", key, ": ", static_cast<int>(type)); return false;
@@ -215,7 +215,7 @@ bool UnitManager::generate_modifiers(ModifierManager& modifier_manager) {
STAT_MODIFIER("siege", true, RAW_DECIMAL);
break;
}
- case Unit::type_t::NAVAL: {
+ case Unit::type_t::NAVAL: {
STAT_MODIFIER("colonial_points", true, INT);
STAT_MODIFIER("supply_consumption_score", false, INT);
STAT_MODIFIER("hull", true, RAW_DECIMAL);
@@ -223,8 +223,8 @@ bool UnitManager::generate_modifiers(ModifierManager& modifier_manager) {
STAT_MODIFIER("fire_range", true, RAW_DECIMAL);
STAT_MODIFIER("evasion", true, PROPORTION_DECIMAL);
STAT_MODIFIER("torpedo_attack", true, RAW_DECIMAL);
- break;
- }
+ break;
+ }
}
return ret;
diff --git a/src/openvic-simulation/military/Wargoal.hpp b/src/openvic-simulation/military/Wargoal.hpp
index ef8170f..f696511 100644
--- a/src/openvic-simulation/military/Wargoal.hpp
+++ b/src/openvic-simulation/military/Wargoal.hpp
@@ -9,24 +9,24 @@ namespace OpenVic {
struct WargoalTypeManager;
enum class peace_options_t : uint32_t {
- PO_ANNEX = 0b100000000000000000,
- PO_DEMAND_STATE = 0b010000000000000000,
- PO_COLONY = 0b001000000000000000,
- PO_ADD_TO_SPHERE = 0b000100000000000000,
- PO_DISARMAMENT = 0b000010000000000000,
- PO_REMOVE_FORTS = 0b000001000000000000,
- PO_REMOVE_NAVAL_BASES = 0b000000100000000000,
- PO_REPARATIONS = 0b000000010000000000,
- PO_REPAY_DEBT = 0b000000001000000000,
- PO_REMOVE_PRESTIGE = 0b000000000100000000,
- PO_MAKE_PUPPET = 0b000000000010000000,
- PO_RELEASE_PUPPET = 0b000000000001000000,
- PO_STATUS_QUO = 0b000000000000100000,
- PO_INSTALL_COMMUNISM = 0b000000000000010000,
- PO_REMOVE_COMMUNISM = 0b000000000000001000,
- PO_REMOVE_CORES = 0b000000000000000100, // only usable with ANNEX, DEMAND_STATE, or TRANSFER_PROVINCES
- PO_TRANSFER_PROVINCES = 0b000000000000000010,
- PO_CLEAR_UNION_SPHERE = 0b000000000000000001
+ PO_ANNEX = 0b100000000000000000,
+ PO_DEMAND_STATE = 0b010000000000000000,
+ PO_COLONY = 0b001000000000000000,
+ PO_ADD_TO_SPHERE = 0b000100000000000000,
+ PO_DISARMAMENT = 0b000010000000000000,
+ PO_REMOVE_FORTS = 0b000001000000000000,
+ PO_REMOVE_NAVAL_BASES = 0b000000100000000000,
+ PO_REPARATIONS = 0b000000010000000000,
+ PO_REPAY_DEBT = 0b000000001000000000,
+ PO_REMOVE_PRESTIGE = 0b000000000100000000,
+ PO_MAKE_PUPPET = 0b000000000010000000,
+ PO_RELEASE_PUPPET = 0b000000000001000000,
+ PO_STATUS_QUO = 0b000000000000100000,
+ PO_INSTALL_COMMUNISM = 0b000000000000010000,
+ PO_REMOVE_COMMUNISM = 0b000000000000001000,
+ PO_REMOVE_CORES = 0b000000000000000100, // only usable with ANNEX, DEMAND_STATE, or TRANSFER_PROVINCES
+ PO_TRANSFER_PROVINCES = 0b000000000000000010,
+ PO_CLEAR_UNION_SPHERE = 0b000000000000000001
};
template<> struct enable_bitfield<peace_options_t> : std::true_type{};
diff --git a/src/openvic-simulation/GameAdvancementHook.cpp b/src/openvic-simulation/misc/GameAdvancementHook.cpp
index e56331c..f4c0adc 100644
--- a/src/openvic-simulation/GameAdvancementHook.cpp
+++ b/src/openvic-simulation/misc/GameAdvancementHook.cpp
@@ -3,8 +3,8 @@
using namespace OpenVic;
const std::vector<std::chrono::milliseconds> GameAdvancementHook::GAME_SPEEDS = {
- std::chrono::milliseconds { 4000 }, std::chrono::milliseconds { 3000 }, std::chrono::milliseconds { 2000 },
- std::chrono::milliseconds { 1000 }, std::chrono::milliseconds { 100 }, std::chrono::milliseconds { 1 }
+ std::chrono::milliseconds { 3000 }, std::chrono::milliseconds { 2000 }, std::chrono::milliseconds { 1000 },
+ std::chrono::milliseconds { 100 }, std::chrono::milliseconds { 1 }
};
GameAdvancementHook::GameAdvancementHook(
diff --git a/src/openvic-simulation/GameAdvancementHook.hpp b/src/openvic-simulation/misc/GameAdvancementHook.hpp
index 75af718..75af718 100644
--- a/src/openvic-simulation/GameAdvancementHook.hpp
+++ b/src/openvic-simulation/misc/GameAdvancementHook.hpp
diff --git a/src/openvic-simulation/misc/Modifier.cpp b/src/openvic-simulation/misc/Modifier.cpp
index 86c659b..6ad14aa 100644
--- a/src/openvic-simulation/misc/Modifier.cpp
+++ b/src/openvic-simulation/misc/Modifier.cpp
@@ -77,10 +77,19 @@ ModifierValue ModifierValue::operator-(ModifierValue const& right) const {
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 } {}
+TriggeredModifier::TriggeredModifier(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon)
+ : Modifier { new_identifier, std::move(new_values), new_icon } {}
+
ModifierInstance::ModifierInstance(Modifier const& modifier, Date expiry_date)
: modifier { modifier }, expiry_date { expiry_date } {}
-ModifierManager::ModifierManager() : modifier_effects { "modifier effects" }, event_modifiers { "event modifiers" } {}
+Crime::Crime(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon, bool new_default_active)
+ : TriggeredModifier { new_identifier, std::move(new_values), new_icon }, default_active { new_default_active },
+ active { new_default_active } {}
+
+ModifierManager::ModifierManager()
+ : modifier_effects { "modifier effects" }, crime_modifiers { "crime modifiers" }, event_modifiers { "event modifiers" },
+ static_modifiers { "static modifiers" }, triggered_modifiers { "triggered modifiers" } {}
bool ModifierManager::add_modifier_effect(std::string_view identifier, bool positive_good, ModifierEffect::format_t format) {
if (identifier.empty()) {
@@ -92,18 +101,6 @@ bool ModifierManager::add_modifier_effect(std::string_view identifier, bool posi
);
}
-bool ModifierManager::add_event_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon) {
- if (identifier.empty()) {
- Logger::error("Invalid modifier effect identifier - empty!");
- return false;
- }
- if (icon <= 0) {
- Logger::error("Invalid modifier icon for ", identifier, ": ", icon);
- return false;
- }
- return event_modifiers.add_item({ identifier, std::move(values), icon }, duplicate_warning_callback);
-}
-
bool ModifierManager::setup_modifier_effects() {
bool ret = true;
@@ -133,6 +130,7 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("issue_change_speed", true);
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("loan_interest", false);
ret &= add_modifier_effect("max_loan_modifier", true);
@@ -140,6 +138,7 @@ bool ModifierManager::setup_modifier_effects() {
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("middle_income_modifier", true);
ret &= add_modifier_effect("middle_life_needs", true);
ret &= add_modifier_effect("middle_everyday_needs", true);
@@ -192,7 +191,7 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("increase_research", true);
ret &= add_modifier_effect("influence", true);
ret &= add_modifier_effect("administrative_efficiency", true);
- ret &= add_modifier_effect("tax_eff", true);
+ ret &= add_modifier_effect("tax_eff", true);
ret &= add_modifier_effect("military_tactics", true);
ret &= add_modifier_effect("dig_in_cap", true, INT);
ret &= add_modifier_effect("max_national_focus", true, INT);
@@ -200,6 +199,7 @@ bool ModifierManager::setup_modifier_effects() {
/* Province Modifier Effects */
ret &= add_modifier_effect("assimilation_rate", true);
+ ret &= add_modifier_effect("boost_strongest_party", false);
ret &= add_modifier_effect("immigrant_attract", true);
ret &= add_modifier_effect("immigrant_push", false);
ret &= add_modifier_effect("life_rating", true);
@@ -220,11 +220,13 @@ bool ModifierManager::setup_modifier_effects() {
ret &= add_modifier_effect("farm_RGO_eff", true);
ret &= add_modifier_effect("farm_rgo_size", true);
ret &= add_modifier_effect("farm_RGO_size", true);
+ ret &= add_modifier_effect("max_attrition", false, RAW_DECIMAL);
ret &= add_modifier_effect("mine_rgo_eff", true);
ret &= add_modifier_effect("mine_RGO_eff", true);
ret &= add_modifier_effect("mine_rgo_size", true);
ret &= add_modifier_effect("mine_RGO_size", true);
ret &= add_modifier_effect("movement_cost", false);
+ ret &= add_modifier_effect("number_of_voters", false);
ret &= add_modifier_effect("railroads", true); // capitalist likelihood for railroads vs factories
ret &= add_modifier_effect("supply_limit", true, RAW_DECIMAL);
@@ -247,37 +249,111 @@ void ModifierManager::register_complex_modifier(std::string_view identifier) {
complex_modifiers.emplace(identifier);
}
+bool ModifierManager::add_crime_modifier(
+ std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon, bool active
+) {
+ if (identifier.empty()) {
+ Logger::error("Invalid crime modifier effect identifier - empty!");
+ return false;
+ }
+ return crime_modifiers.add_item({ identifier, std::move(values), icon, active }, duplicate_warning_callback);
+}
+
bool ModifierManager::load_crime_modifiers(ast::NodeCPtr root) {
- // TODO - DEV TASK: read crime modifiers
+ const bool ret = expect_dictionary_reserve_length(
+ crime_modifiers,
+ [this](std::string_view key, ast::NodeCPtr value) -> bool {
+ ModifierValue modifier_value;
+ Modifier::icon_t icon = 0;
+ bool active = false;
+ bool ret = expect_modifier_value_and_keys(
+ move_variable_callback(modifier_value),
+ "icon", ZERO_OR_ONE, expect_uint(assign_variable_callback(icon)),
+ "trigger", ONE_EXACTLY, success_callback, // TODO - load condition
+ "active", ZERO_OR_ONE, expect_bool(assign_variable_callback(active))
+ )(value);
+ ret &= add_crime_modifier(key, std::move(modifier_value), icon, active);
+ return ret;
+ }
+ )(root);
+ lock_crime_modifiers();
+ return ret;
return true;
}
+bool ModifierManager::add_event_modifier(std::string_view identifier, ModifierValue&& values, Modifier::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);
+}
+
bool ModifierManager::load_event_modifiers(ast::NodeCPtr root) {
- // TODO - DEV TASK: read event modifiers - example framework below
- return true;
- /*return expect_dictionary_reserve_length(
+ const bool ret = expect_dictionary_reserve_length(
event_modifiers,
[this](std::string_view key, ast::NodeCPtr value) -> bool {
ModifierValue modifier_value;
Modifier::icon_t icon = 0;
bool ret = expect_modifier_value_and_keys(
move_variable_callback(modifier_value),
- "icon", ONE_EXACTLY, expect_uint(assign_variable_callback(icon))
+ "icon", ZERO_OR_ONE, expect_uint(assign_variable_callback(icon))
)(value);
ret &= add_event_modifier(key, std::move(modifier_value), icon);
return ret;
}
- )(root);*/
+ )(root);
+ lock_event_modifiers();
+ return ret;
+}
+
+bool ModifierManager::add_static_modifier(std::string_view identifier, ModifierValue&& values) {
+ if (identifier.empty()) {
+ Logger::error("Invalid static modifier effect identifier - empty!");
+ return false;
+ }
+ return static_modifiers.add_item({ identifier, std::move(values), 0 }, duplicate_warning_callback);
}
bool ModifierManager::load_static_modifiers(ast::NodeCPtr root) {
- // TODO - DEV TASK: read static modifiers
- return true;
+ const bool ret = expect_dictionary_reserve_length(
+ static_modifiers,
+ [this](std::string_view key, ast::NodeCPtr value) -> bool {
+ ModifierValue modifier_value;
+ bool ret = expect_modifier_value(move_variable_callback(modifier_value))(value);
+ ret &= add_static_modifier(key, std::move(modifier_value));
+ return ret;
+ }
+ )(root);
+ lock_static_modifiers();
+ return ret;
+}
+
+bool ModifierManager::add_triggered_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon) {
+ if (identifier.empty()) {
+ Logger::error("Invalid triggered modifier effect identifier - empty!");
+ return false;
+ }
+ return triggered_modifiers.add_item({ identifier, std::move(values), icon }, duplicate_warning_callback);
}
bool ModifierManager::load_triggered_modifiers(ast::NodeCPtr root) {
- // TODO - DEV TASK: read triggered modifiers
- return true;
+ const bool ret = expect_dictionary_reserve_length(
+ triggered_modifiers,
+ [this](std::string_view key, ast::NodeCPtr value) -> bool {
+ ModifierValue modifier_value;
+ Modifier::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)),
+ "trigger", ONE_EXACTLY, success_callback // TODO - load condition
+ )(value);
+ ret &= add_triggered_modifier(key, std::move(modifier_value), icon);
+ return ret;
+ }
+ )(root);
+ lock_triggered_modifiers();
+ return ret;
}
key_value_callback_t ModifierManager::_modifier_effect_callback(
diff --git a/src/openvic-simulation/misc/Modifier.hpp b/src/openvic-simulation/misc/Modifier.hpp
index 9f14f41..9665e07 100644
--- a/src/openvic-simulation/misc/Modifier.hpp
+++ b/src/openvic-simulation/misc/Modifier.hpp
@@ -80,6 +80,32 @@ namespace OpenVic {
Modifier(Modifier&&) = default;
};
+ struct TriggeredModifier : Modifier {
+ friend struct ModifierManager;
+
+ private:
+ // TODO - trigger condition
+
+ protected:
+ TriggeredModifier(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon);
+
+ public:
+ TriggeredModifier(TriggeredModifier&&) = default;
+ };
+
+ struct Crime final : TriggeredModifier {
+ friend struct ModifierManager;
+
+ private:
+ const bool PROPERTY(default_active);
+ bool PROPERTY_RW(active);
+
+ Crime(std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon, bool new_default_active);
+
+ public:
+ Crime(Crime&&) = default;
+ };
+
struct ModifierInstance {
private:
@@ -99,9 +125,13 @@ namespace OpenVic {
*/
private:
IdentifierInstanceRegistry<ModifierEffect> modifier_effects;
- IdentifierRegistry<Modifier> event_modifiers;
string_set_t complex_modifiers;
+ IdentifierRegistry<Crime> crime_modifiers;
+ IdentifierRegistry<Modifier> event_modifiers;
+ IdentifierRegistry<Modifier> static_modifiers;
+ IdentifierRegistry<TriggeredModifier> triggered_modifiers;
+
/* effect_validator takes in ModifierEffect const& */
NodeTools::key_value_callback_t _modifier_effect_callback(
ModifierValue& modifier, NodeTools::key_value_callback_t default_callback,
@@ -117,15 +147,24 @@ namespace OpenVic {
);
IDENTIFIER_REGISTRY_ACCESSORS(modifier_effect)
- bool add_event_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon);
- IDENTIFIER_REGISTRY_ACCESSORS(event_modifier)
void register_complex_modifier(std::string_view identifier);
bool setup_modifier_effects();
+ bool add_crime_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon, bool active);
+ IDENTIFIER_REGISTRY_ACCESSORS(crime_modifier)
bool load_crime_modifiers(ast::NodeCPtr root);
+
+ bool add_event_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon);
+ IDENTIFIER_REGISTRY_ACCESSORS(event_modifier)
bool load_event_modifiers(ast::NodeCPtr root);
+
+ bool add_static_modifier(std::string_view identifier, ModifierValue&& values);
+ IDENTIFIER_REGISTRY_ACCESSORS(static_modifier)
bool load_static_modifiers(ast::NodeCPtr root);
+
+ bool add_triggered_modifier(std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon);
+ IDENTIFIER_REGISTRY_ACCESSORS(triggered_modifier)
bool load_triggered_modifiers(ast::NodeCPtr root);
NodeTools::node_callback_t expect_validated_modifier_value_and_default(
diff --git a/src/openvic-simulation/politics/Government.cpp b/src/openvic-simulation/politics/Government.cpp
index 0d1d063..609e75f 100644
--- a/src/openvic-simulation/politics/Government.cpp
+++ b/src/openvic-simulation/politics/Government.cpp
@@ -37,9 +37,16 @@ bool GovernmentTypeManager::add_government_type(
return false;
}
- return government_types.add_item({
+ const bool ret = government_types.add_item({
identifier, std::move(ideologies), elections, appoint_ruling_party, term_duration, flag_type
});
+
+ /* flag_type can be empty here for default/non-ideological flag */
+ if (ret && std::find(flag_types.begin(), flag_types.end(), flag_type) == flag_types.end()) {
+ flag_types.emplace_back(flag_type);
+ }
+
+ return ret;
}
/* REQUIREMENTS: FS-525, SIM-27 */
@@ -49,7 +56,7 @@ bool GovernmentTypeManager::load_government_types_file(IdeologyManager const& id
std::vector<Ideology const*> ideologies;
bool elections = false, appoint_ruling_party = false;
Timespan term_duration = 0;
- std::string_view flag_type_identifier = "republic";
+ std::string_view flag_type_identifier;
size_t total_expected_ideologies = 0;
bool ret = expect_dictionary_keys_and_default(
diff --git a/src/openvic-simulation/politics/Government.hpp b/src/openvic-simulation/politics/Government.hpp
index 0bc777a..025e238 100644
--- a/src/openvic-simulation/politics/Government.hpp
+++ b/src/openvic-simulation/politics/Government.hpp
@@ -29,6 +29,7 @@ namespace OpenVic {
struct GovernmentTypeManager {
private:
IdentifierRegistry<GovernmentType> government_types;
+ std::vector<std::string> PROPERTY(flag_types);
public:
GovernmentTypeManager();
diff --git a/src/openvic-simulation/politics/PoliticsManager.hpp b/src/openvic-simulation/politics/PoliticsManager.hpp
index 4f62124..0afe002 100644
--- a/src/openvic-simulation/politics/PoliticsManager.hpp
+++ b/src/openvic-simulation/politics/PoliticsManager.hpp
@@ -24,5 +24,8 @@ namespace OpenVic {
inline bool load_national_foci_file(PopManager const& pop_manager, GoodManager const& good_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root) {
return national_focus_manager.load_national_foci_file(pop_manager, ideology_manager, good_manager, modifier_manager, root);
}
+ inline bool load_rebels_file(ast::NodeCPtr root) {
+ return rebel_manager.load_rebels_file(ideology_manager, government_type_manager, root);
+ }
};
}
diff --git a/src/openvic-simulation/politics/Rebel.cpp b/src/openvic-simulation/politics/Rebel.cpp
index cc0514c..e58b3de 100644
--- a/src/openvic-simulation/politics/Rebel.cpp
+++ b/src/openvic-simulation/politics/Rebel.cpp
@@ -3,37 +3,43 @@
using namespace OpenVic;
using namespace OpenVic::NodeTools;
-RebelType::RebelType(std::string_view new_identifier, RebelType::icon_t icon, RebelType::area_t area, bool break_alliance_on_win,
- RebelType::government_map_t desired_governments, RebelType::defection_t defection, RebelType::independence_t independence, uint16_t defect_delay,
- Ideology const* ideology, bool allow_all_cultures, bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient,
- bool reinforcing, bool general, bool smart, bool unit_transfer, fixed_point_t occupation_mult)
-: HasIdentifier { new_identifier }, icon { icon }, area { area }, break_alliance_on_win { break_alliance_on_win },
- desired_governments { std::move(desired_governments) }, defection { defection }, independence { independence }, defect_delay { defect_delay },
- ideology { ideology }, allow_all_cultures { allow_all_cultures }, allow_all_culture_groups { allow_all_culture_groups },
- allow_all_religions { allow_all_religions }, allow_all_ideologies { allow_all_ideologies }, resilient { resilient }, reinforcing { reinforcing },
- general { general }, smart { smart }, unit_transfer { unit_transfer }, occupation_mult { occupation_mult } {}
+RebelType::RebelType(
+ std::string_view new_identifier, RebelType::icon_t icon, RebelType::area_t area, bool break_alliance_on_win,
+ RebelType::government_map_t&& desired_governments, RebelType::defection_t defection,
+ RebelType::independence_t independence, uint16_t defect_delay, Ideology const* ideology, bool allow_all_cultures,
+ bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient, bool reinforcing,
+ bool general, bool smart, bool unit_transfer, fixed_point_t occupation_mult
+) : HasIdentifier { new_identifier }, icon { icon }, area { area }, break_alliance_on_win { break_alliance_on_win },
+ desired_governments { std::move(desired_governments) }, defection { defection }, independence { independence },
+ defect_delay { defect_delay }, ideology { ideology }, allow_all_cultures { allow_all_cultures },
+ allow_all_culture_groups { allow_all_culture_groups }, allow_all_religions { allow_all_religions },
+ allow_all_ideologies { allow_all_ideologies }, resilient { resilient }, reinforcing { reinforcing }, general { general },
+ smart { smart }, unit_transfer { unit_transfer }, occupation_mult { occupation_mult } {}
RebelManager::RebelManager() : rebel_types { "rebel types" } {}
bool RebelManager::add_rebel_type(
- std::string_view new_identifier, RebelType::icon_t icon, RebelType::area_t area, bool break_alliance_on_win, RebelType::government_map_t desired_governments,
- RebelType::defection_t defection, RebelType::independence_t independence, uint16_t defect_delay, Ideology const* ideology, bool allow_all_cultures,
- bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient, bool reinforcing, bool general, bool smart, bool unit_transfer,
- fixed_point_t occupation_mult) {
-
+ std::string_view new_identifier, RebelType::icon_t icon, RebelType::area_t area, bool break_alliance_on_win,
+ RebelType::government_map_t&& desired_governments, RebelType::defection_t defection,
+ RebelType::independence_t independence, uint16_t defect_delay, Ideology const* ideology, bool allow_all_cultures,
+ bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient, bool reinforcing,
+ bool general, bool smart, bool unit_transfer, fixed_point_t occupation_mult
+) {
if (new_identifier.empty()) {
Logger::error("Invalid rebel type identifier - empty!");
return false;
}
return rebel_types.add_item({
- new_identifier, icon, area, break_alliance_on_win, desired_governments, defection, independence, defect_delay, ideology,
- allow_all_cultures, allow_all_culture_groups, allow_all_religions, allow_all_ideologies, resilient, reinforcing, general,
- smart, unit_transfer, occupation_mult
+ new_identifier, icon, area, break_alliance_on_win, std::move(desired_governments), defection, independence,
+ defect_delay, ideology, allow_all_cultures, allow_all_culture_groups, allow_all_religions, allow_all_ideologies,
+ resilient, reinforcing, general, smart, unit_transfer, occupation_mult
});
}
-bool RebelManager::load_rebels_file(IdeologyManager const& ideology_manager, GovernmentTypeManager const& government_type_manager, ast::NodeCPtr root) {
+bool RebelManager::load_rebels_file(
+ IdeologyManager const& ideology_manager, GovernmentTypeManager const& government_type_manager, ast::NodeCPtr root
+) {
static const string_map_t<RebelType::area_t> area_map = {
{ "nation", RebelType::area_t::NATION },
{ "nation_religion", RebelType::area_t::NATION_RELIGION },
@@ -66,41 +72,44 @@ bool RebelManager::load_rebels_file(IdeologyManager const& ideology_manager, Gov
bool ret = expect_dictionary(
[this, &ideology_manager, &government_type_manager](std::string_view identifier, ast::NodeCPtr node) -> bool {
- RebelType::icon_t icon;
- RebelType::area_t area;
+ RebelType::icon_t icon = 0;
+ RebelType::area_t area = RebelType::area_t::ALL;
RebelType::government_map_t desired_governments;
- RebelType::defection_t defection;
- RebelType::independence_t independence;
- uint16_t defect_delay;
- std::string_view ideology_identifier;
- bool break_alliance_on_win, allow_all_cultures, allow_all_culture_groups, allow_all_religions, allow_all_ideologies, resilient, reinforcing, general, smart, unit_transfer;
- fixed_point_t occupation_mult;
+ RebelType::defection_t defection = RebelType::defection_t::ANY;
+ RebelType::independence_t independence = RebelType::independence_t::ANY;
+ uint16_t defect_delay = 0;
+ Ideology const* ideology = nullptr;
+ bool break_alliance_on_win = false, allow_all_cultures = true, allow_all_culture_groups = true,
+ allow_all_religions = true, allow_all_ideologies = true, resilient = true, reinforcing = true, general = true,
+ smart = true, unit_transfer = false;
+ fixed_point_t occupation_mult = 0;
bool ret = expect_dictionary_keys(
"icon", ONE_EXACTLY, expect_uint(assign_variable_callback(icon)),
"area", ONE_EXACTLY, expect_identifier(expect_mapped_string(area_map, assign_variable_callback(area))),
"break_alliance_on_win", ZERO_OR_ONE, expect_bool(assign_variable_callback(break_alliance_on_win)),
- "government", ONE_EXACTLY, expect_dictionary([this, &government_type_manager, &desired_governments](std::string_view key, ast::NodeCPtr value) -> bool {
- bool ret = true;
-
- GovernmentType const* from = government_type_manager.get_government_type_by_identifier(key);
- ret &= from != nullptr; //invalid from
-
- std::string_view to_identifier;
- ret &= expect_identifier(assign_variable_callback(to_identifier))(value);
-
- GovernmentType const* to = government_type_manager.get_government_type_by_identifier(to_identifier);
- ret &= to != nullptr; //invalid to
-
- if (desired_governments.contains(from)) ret = false; //duplicate
- else if (ret) desired_governments.emplace(from, to); //only proceed if both values are valid
-
- return ret;
- }),
- "defection", ONE_EXACTLY, expect_identifier(expect_mapped_string(defection_map, assign_variable_callback(defection))),
- "independence", ONE_EXACTLY, expect_identifier(expect_mapped_string(independence_map, assign_variable_callback(independence))),
+ "government", ONE_EXACTLY, government_type_manager.expect_government_type_dictionary(
+ [this, &government_type_manager, &desired_governments](GovernmentType const& from,
+ ast::NodeCPtr value) -> bool {
+ if (desired_governments.contains(&from)) {
+ Logger::error("Duplicate \"from\" government type in rebel type: ", from.get_identifier());
+ return false;
+ }
+ return government_type_manager.expect_government_type_identifier(
+ [&desired_governments, &from](GovernmentType const& to) -> bool {
+ desired_governments.emplace(&from, &to);
+ return true;
+ }
+ )(value);
+ }
+ ),
+ "defection", ONE_EXACTLY,
+ expect_identifier(expect_mapped_string(defection_map, assign_variable_callback(defection))),
+ "independence", ONE_EXACTLY,
+ expect_identifier(expect_mapped_string(independence_map, assign_variable_callback(independence))),
"defect_delay", ONE_EXACTLY, expect_uint(assign_variable_callback(defect_delay)),
- "ideology", ZERO_OR_ONE, expect_identifier(assign_variable_callback(ideology_identifier)),
+ "ideology", ZERO_OR_ONE,
+ ideology_manager.expect_ideology_identifier(assign_variable_callback_pointer(ideology)),
"allow_all_cultures", ONE_EXACTLY, expect_bool(assign_variable_callback(allow_all_cultures)),
"allow_all_culture_groups", ZERO_OR_ONE, expect_bool(assign_variable_callback(allow_all_culture_groups)),
"allow_all_religions", ONE_EXACTLY, expect_bool(assign_variable_callback(allow_all_religions)),
@@ -120,12 +129,10 @@ bool RebelManager::load_rebels_file(IdeologyManager const& ideology_manager, Gov
"demands_enforced_effect", ZERO_OR_ONE, success_callback //TODO
)(node);
- Ideology const* ideology = ideology_manager.get_ideology_by_identifier(ideology_identifier);
-
ret &= add_rebel_type(
- identifier, icon, area, break_alliance_on_win, desired_governments, defection, independence,defect_delay,
- ideology, allow_all_cultures, allow_all_culture_groups, allow_all_religions, allow_all_ideologies, resilient, reinforcing,
- general, smart, unit_transfer, occupation_mult
+ identifier, icon, area, break_alliance_on_win, std::move(desired_governments), defection, independence,
+ defect_delay, ideology, allow_all_cultures, allow_all_culture_groups, allow_all_religions,
+ allow_all_ideologies, resilient, reinforcing, general, smart, unit_transfer, occupation_mult
);
return ret;
diff --git a/src/openvic-simulation/politics/Rebel.hpp b/src/openvic-simulation/politics/Rebel.hpp
index 791e95b..f012829 100644
--- a/src/openvic-simulation/politics/Rebel.hpp
+++ b/src/openvic-simulation/politics/Rebel.hpp
@@ -52,13 +52,14 @@ namespace OpenVic {
RebelType(
std::string_view new_identifier, RebelType::icon_t icon, RebelType::area_t area, bool break_alliance_on_win,
- RebelType::government_map_t desired_governments, RebelType::defection_t defection, RebelType::independence_t independence, uint16_t defect_delay,
- Ideology const* ideology, bool allow_all_cultures, bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient,
+ RebelType::government_map_t&& desired_governments, RebelType::defection_t defection,
+ RebelType::independence_t independence, uint16_t defect_delay, Ideology const* ideology, bool allow_all_cultures,
+ bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient,
bool reinforcing, bool general, bool smart, bool unit_transfer, fixed_point_t occupation_mult
);
public:
- RebelType(RebelType&&) = default;
+ RebelType(RebelType&&) = default;
};
struct RebelManager {
@@ -71,11 +72,14 @@ namespace OpenVic {
IDENTIFIER_REGISTRY_ACCESSORS(rebel_type)
bool add_rebel_type(
std::string_view new_identifier, RebelType::icon_t icon, RebelType::area_t area, bool break_alliance_on_win,
- RebelType::government_map_t desired_governments, RebelType::defection_t defection, RebelType::independence_t independence, uint16_t defect_delay,
- Ideology const* ideology, bool allow_all_cultures, bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient,
+ RebelType::government_map_t&& desired_governments, RebelType::defection_t defection,
+ RebelType::independence_t independence, uint16_t defect_delay, Ideology const* ideology, bool allow_all_cultures,
+ bool allow_all_culture_groups, bool allow_all_religions, bool allow_all_ideologies, bool resilient,
bool reinforcing, bool general, bool smart, bool unit_transfer, fixed_point_t occupation_mult
);
- bool load_rebels_file(IdeologyManager const& ideology_manager, GovernmentTypeManager const& government_type_manager, ast::NodeCPtr root);
+ bool load_rebels_file(
+ IdeologyManager const& ideology_manager, GovernmentTypeManager const& government_type_manager, ast::NodeCPtr root
+ );
};
} \ No newline at end of file
diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp
index 31ab6d5..4d87081 100644
--- a/src/openvic-simulation/pop/Pop.cpp
+++ b/src/openvic-simulation/pop/Pop.cpp
@@ -23,24 +23,32 @@ PopType::PopType(
std::string_view new_identifier, colour_t new_colour, strata_t new_strata, sprite_t new_sprite,
Good::good_map_t&& new_life_needs, Good::good_map_t&& new_everyday_needs, Good::good_map_t&& new_luxury_needs,
rebel_units_t&& new_rebel_units, Pop::pop_size_t new_max_size, Pop::pop_size_t new_merge_max_size,
- bool new_state_capital_only, bool new_demote_migrant, bool new_is_artisan, bool new_is_slave
+ bool new_state_capital_only, bool new_demote_migrant, bool new_is_artisan, bool new_allowed_to_vote, bool new_is_slave,
+ bool new_can_be_recruited, bool new_can_reduce_consciousness, bool new_administrative_efficiency, bool new_can_build,
+ bool new_factory, bool new_can_work_factory, bool new_unemployment
) : HasIdentifierAndColour { new_identifier, new_colour, false, false }, strata { new_strata }, sprite { new_sprite },
life_needs { std::move(new_life_needs) }, everyday_needs { std::move(new_everyday_needs) },
luxury_needs { std::move(new_luxury_needs) }, rebel_units { std::move(new_rebel_units) }, max_size { new_max_size },
merge_max_size { new_merge_max_size }, state_capital_only { new_state_capital_only },
- demote_migrant { new_demote_migrant }, is_artisan { new_is_artisan }, is_slave { new_is_slave } {
+ demote_migrant { new_demote_migrant }, is_artisan { new_is_artisan }, allowed_to_vote { new_allowed_to_vote },
+ is_slave { new_is_slave }, can_be_recruited { new_can_be_recruited },
+ can_reduce_consciousness { new_can_reduce_consciousness }, administrative_efficiency { new_administrative_efficiency },
+ can_build { new_can_build }, factory { new_factory }, can_work_factory { new_can_work_factory },
+ unemployment { new_unemployment } {
assert(sprite > 0);
assert(max_size >= 0);
assert(merge_max_size >= 0);
}
-PopManager::PopManager() : pop_types { "pop types" } {}
+PopManager::PopManager() : pop_types { "pop types" }, slave_sprite { 0 }, administrative_sprite { 0 } {}
bool PopManager::add_pop_type(
std::string_view identifier, colour_t colour, PopType::strata_t strata, PopType::sprite_t sprite,
Good::good_map_t&& life_needs, Good::good_map_t&& everyday_needs, Good::good_map_t&& luxury_needs,
PopType::rebel_units_t&& rebel_units, Pop::pop_size_t max_size, Pop::pop_size_t merge_max_size, bool state_capital_only,
- bool demote_migrant, bool is_artisan, bool is_slave
+ bool demote_migrant, bool is_artisan, bool allowed_to_vote, bool is_slave, bool can_be_recruited,
+ bool can_reduce_consciousness, bool administrative_efficiency, bool can_build, bool factory, bool can_work_factory,
+ bool unemployment
) {
if (identifier.empty()) {
Logger::error("Invalid pop type identifier - empty!");
@@ -62,11 +70,21 @@ bool PopManager::add_pop_type(
Logger::error("Invalid pop type merge max size for ", identifier, ": ", merge_max_size);
return false;
}
- return pop_types.add_item({
+ const bool ret = pop_types.add_item({
identifier, colour, strata, sprite, std::move(life_needs), std::move(everyday_needs),
std::move(luxury_needs), std::move(rebel_units), max_size, merge_max_size, state_capital_only,
- demote_migrant, is_artisan, is_slave
+ demote_migrant, is_artisan, allowed_to_vote, is_slave, can_be_recruited, can_reduce_consciousness,
+ administrative_efficiency, can_build, factory, can_work_factory, unemployment
});
+ if (slave_sprite <= 0 && ret && is_slave) {
+ /* Set slave sprite to that of the first is_slave pop type we find. */
+ slave_sprite = sprite;
+ }
+ if (administrative_sprite <= 0 && ret && administrative_efficiency) {
+ /* Set administrative sprite to that of the first administrative_efficiency pop type we find. */
+ administrative_sprite = sprite;
+ }
+ return ret;
}
/* REQUIREMENTS:
@@ -86,7 +104,9 @@ bool PopManager::load_pop_type_file(
PopType::sprite_t sprite = 0;
Good::good_map_t life_needs, everyday_needs, luxury_needs;
PopType::rebel_units_t rebel_units;
- bool state_capital_only = false, is_artisan = false, is_slave = false, demote_migrant = false;
+ bool state_capital_only = false, demote_migrant = false, is_artisan = false, allowed_to_vote = true, is_slave = false,
+ can_be_recruited = false, can_reduce_consciousness = false, administrative_efficiency = false, can_build = false,
+ factory = false, can_work_factory = false, unemployment = false;
Pop::pop_size_t max_size = 0, merge_max_size = 0;
bool ret = expect_dictionary_keys(
"sprite", ONE_EXACTLY, expect_uint(assign_variable_callback(sprite)),
@@ -96,41 +116,43 @@ bool PopManager::load_pop_type_file(
"merge_max_size", ZERO_OR_ONE, expect_uint(assign_variable_callback(merge_max_size)),
"strata", ONE_EXACTLY, expect_identifier(expect_mapped_string(strata_map, assign_variable_callback(strata))),
"state_capital_only", ZERO_OR_ONE, expect_bool(assign_variable_callback(state_capital_only)),
- "research_points", ZERO_OR_ONE, success_callback,
- "research_optimum", ZERO_OR_ONE, success_callback,
+ "research_points", ZERO_OR_ONE, success_callback, // TODO - research points generation
+ "research_optimum", ZERO_OR_ONE, success_callback, // TODO - bonus research points generation
"rebel", ZERO_OR_ONE, unit_manager.expect_unit_decimal_map(move_variable_callback(rebel_units)),
- "equivalent", ZERO_OR_ONE, success_callback,
- "leadership", ZERO_OR_ONE, success_callback,
- "allowed_to_vote", ZERO_OR_ONE, success_callback,
+ "equivalent", ZERO_OR_ONE, success_callback, // TODO - worker convertability
+ "leadership", ZERO_OR_ONE, success_callback, // TODO - leadership points generation
+ "allowed_to_vote", ZERO_OR_ONE, expect_bool(assign_variable_callback(allowed_to_vote)),
"is_slave", ZERO_OR_ONE, expect_bool(assign_variable_callback(is_slave)),
- "can_be_recruited", ZERO_OR_ONE, success_callback,
- "can_reduce_consciousness", ZERO_OR_ONE, success_callback,
- "life_needs_income", ZERO_OR_ONE, success_callback,
+ "can_be_recruited", ZERO_OR_ONE, expect_bool(assign_variable_callback(can_be_recruited)),
+ "can_reduce_consciousness", ZERO_OR_ONE, expect_bool(assign_variable_callback(can_reduce_consciousness)),
+ "life_needs_income", ZERO_OR_ONE, success_callback, // TODO - incomes from national budget
"everyday_needs_income", ZERO_OR_ONE, success_callback,
"luxury_needs_income", ZERO_OR_ONE, success_callback,
"luxury_needs", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(luxury_needs)),
"everyday_needs", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(everyday_needs)),
"life_needs", ZERO_OR_ONE, good_manager.expect_good_decimal_map(move_variable_callback(life_needs)),
- "country_migration_target", ZERO_OR_ONE, success_callback,
+ "country_migration_target", ZERO_OR_ONE, success_callback, // TODO - pop migration weight scripts
"migration_target", ZERO_OR_ONE, success_callback,
- "promote_to", ZERO_OR_ONE, success_callback,
- "ideologies", ZERO_OR_ONE, success_callback,
+ "promote_to", ZERO_OR_ONE, success_callback, // TODO - pop promotion weight scripts
+ "ideologies", ZERO_OR_ONE, success_callback, // TODO - pop politics weight scripts
"issues", ZERO_OR_ONE, success_callback,
"demote_migrant", ZERO_OR_ONE, expect_bool(assign_variable_callback(demote_migrant)),
- "administrative_efficiency", ZERO_OR_ONE, success_callback,
- "tax_eff", ZERO_OR_ONE, success_callback,
- "can_build", ZERO_OR_ONE, success_callback,
- "factory", ZERO_OR_ONE, success_callback,
- "workplace_input", ZERO_OR_ONE, success_callback,
+ "administrative_efficiency", ZERO_OR_ONE, expect_bool(assign_variable_callback(administrative_efficiency)),
+ "tax_eff", ZERO_OR_ONE, success_callback, // TODO - tax collection modifier
+ "can_build", ZERO_OR_ONE, expect_bool(assign_variable_callback(can_build)),
+ "factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(factory)),
+ "workplace_input", ZERO_OR_ONE, success_callback, // TODO - work out what these do
"workplace_output", ZERO_OR_ONE, success_callback,
"starter_share", ZERO_OR_ONE, success_callback,
- "can_work_factory", ZERO_OR_ONE, success_callback,
- "unemployment", ZERO_OR_ONE, success_callback
+ "can_work_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(can_work_factory)),
+ "unemployment", ZERO_OR_ONE, expect_bool(assign_variable_callback(unemployment))
)(root);
ret &= add_pop_type(
filestem, colour, strata, sprite, std::move(life_needs), std::move(everyday_needs), std::move(luxury_needs),
- std::move(rebel_units), max_size, merge_max_size, state_capital_only, demote_migrant, is_artisan, is_slave
+ std::move(rebel_units), max_size, merge_max_size, state_capital_only, demote_migrant, is_artisan, allowed_to_vote,
+ is_slave, can_be_recruited, can_reduce_consciousness, administrative_efficiency, can_build, factory, can_work_factory,
+ unemployment
);
return ret;
}
diff --git a/src/openvic-simulation/pop/Pop.hpp b/src/openvic-simulation/pop/Pop.hpp
index 798e78e..fb51c59 100644
--- a/src/openvic-simulation/pop/Pop.hpp
+++ b/src/openvic-simulation/pop/Pop.hpp
@@ -59,7 +59,15 @@ namespace OpenVic {
const bool PROPERTY(state_capital_only);
const bool PROPERTY(demote_migrant);
const bool PROPERTY(is_artisan);
+ const bool PROPERTY(allowed_to_vote);
const bool PROPERTY(is_slave);
+ const bool PROPERTY(can_be_recruited);
+ const bool PROPERTY(can_reduce_consciousness);
+ const bool PROPERTY(administrative_efficiency);
+ const bool PROPERTY(can_build);
+ const bool PROPERTY(factory);
+ const bool PROPERTY(can_work_factory);
+ const bool PROPERTY(unemployment);
// TODO - country and province migration targets, promote_to targets, ideologies and issues
@@ -67,7 +75,10 @@ namespace OpenVic {
std::string_view new_identifier, colour_t new_colour, strata_t new_strata, sprite_t new_sprite,
Good::good_map_t&& new_life_needs, Good::good_map_t&& new_everyday_needs, Good::good_map_t&& new_luxury_needs,
rebel_units_t&& new_rebel_units, Pop::pop_size_t new_max_size, Pop::pop_size_t new_merge_max_size,
- bool new_state_capital_only, bool new_demote_migrant, bool new_is_artisan, bool new_is_slave
+ bool new_state_capital_only, bool new_demote_migrant, bool new_is_artisan, bool new_allowed_to_vote,
+ bool new_is_slave, bool new_can_be_recruited, bool new_can_reduce_consciousness,
+ bool new_administrative_efficiency, bool new_can_build, bool new_factory, bool new_can_work_factory,
+ bool new_unemployment
);
public:
@@ -79,6 +90,8 @@ namespace OpenVic {
struct PopManager {
private:
IdentifierRegistry<PopType> pop_types;
+ PopType::sprite_t PROPERTY(slave_sprite);
+ PopType::sprite_t PROPERTY(administrative_sprite);
CultureManager PROPERTY_REF(culture_manager);
ReligionManager PROPERTY_REF(religion_manager);
@@ -90,7 +103,9 @@ namespace OpenVic {
std::string_view identifier, colour_t new_colour, PopType::strata_t strata, PopType::sprite_t sprite,
Good::good_map_t&& life_needs, Good::good_map_t&& everyday_needs, Good::good_map_t&& luxury_needs,
PopType::rebel_units_t&& rebel_units, Pop::pop_size_t max_size, Pop::pop_size_t merge_max_size,
- bool state_capital_only, bool demote_migrant, bool is_artisan, bool is_slave
+ bool state_capital_only, bool demote_migrant, bool is_artisan, bool allowed_to_vote, bool is_slave,
+ bool can_be_recruited, bool can_reduce_consciousness, bool administrative_efficiency, bool can_build, bool factory,
+ bool can_work_factory, bool unemployment
);
IDENTIFIER_REGISTRY_ACCESSORS(pop_type)
diff --git a/src/openvic-simulation/tech/Technology.cpp b/src/openvic-simulation/tech/Technology.cpp
index aa96fe2..1234ff3 100644
--- a/src/openvic-simulation/tech/Technology.cpp
+++ b/src/openvic-simulation/tech/Technology.cpp
@@ -3,18 +3,25 @@
using namespace OpenVic;
using namespace OpenVic::NodeTools;
-TechnologyFolder::TechnologyFolder(std::string_view identifier) : HasIdentifier { identifier } {}
+TechnologyFolder::TechnologyFolder(std::string_view new_identifier) : HasIdentifier { new_identifier } {}
-TechnologyArea::TechnologyArea(std::string_view identifier, TechnologyFolder const& folder) : HasIdentifier { identifier }, folder { folder } {}
+TechnologyArea::TechnologyArea(std::string_view new_identifier, TechnologyFolder const& new_folder)
+ : HasIdentifier { new_identifier }, folder { new_folder } {}
-Technology::Technology(std::string_view identifier, TechnologyArea const& area, year_t year, fixed_point_t cost, bool unciv_military, uint8_t unit, unit_set_t activated_units, building_set_t activated_buildings, ModifierValue&& values)
- : Modifier { identifier, std::move(values), 0 }, area { area }, year { year }, cost { cost }, unciv_military { unciv_military }, unit { unit }, activated_buildings { std::move(activated_units) }, activated_units { std::move(activated_buildings) } {}
+Technology::Technology(
+ std::string_view new_identifier, TechnologyArea const& new_area, year_t new_year, fixed_point_t new_cost,
+ bool new_unciv_military, uint8_t new_unit, unit_set_t&& new_activated_units, building_set_t&& new_activated_buildings,
+ ModifierValue&& new_values
+) : Modifier { new_identifier, std::move(new_values), 0 }, area { new_area }, year { new_year }, cost { new_cost },
+ unciv_military { new_unciv_military }, unit { new_unit }, activated_buildings { std::move(new_activated_units) },
+ activated_units { std::move(new_activated_buildings) } {}
-TechnologySchool::TechnologySchool(std::string_view new_identifier, ModifierValue&& new_values)
- : Modifier { new_identifier, std::move(new_values), 0 } {} //TODO: school icon
+TechnologySchool::TechnologySchool(std::string_view new_identifier, ModifierValue&& new_values)
+ : Modifier { new_identifier, std::move(new_values), 0 } {}
-TechnologyManager::TechnologyManager() : technology_folders { "technology folders" }, technology_areas { "technology areas" },
- technologies { "technologies" }, technology_schools { "technology schools" } {}
+TechnologyManager::TechnologyManager()
+ : technology_folders { "technology folders" }, technology_areas { "technology areas" }, technologies { "technologies" },
+ technology_schools { "technology schools" } {}
bool TechnologyManager::add_technology_folder(std::string_view identifier) {
if (identifier.empty()) {
@@ -39,7 +46,11 @@ bool TechnologyManager::add_technology_area(std::string_view identifier, Technol
return technology_areas.add_item({ identifier, *folder });
}
-bool TechnologyManager::add_technology(std::string_view identifier, TechnologyArea const* area, Technology::year_t year, fixed_point_t cost, bool unciv_military, uint8_t unit, Technology::unit_set_t activated_units, Technology::building_set_t activated_buildings, ModifierValue&& values) {
+bool TechnologyManager::add_technology(
+ std::string_view identifier, TechnologyArea const* area, Technology::year_t year, fixed_point_t cost, bool unciv_military,
+ uint8_t unit, Technology::unit_set_t&& activated_units, Technology::building_set_t&& activated_buildings,
+ ModifierValue&& values
+) {
if (identifier.empty()) {
Logger::error("Invalid technology identifier - empty!");
return false;
@@ -50,7 +61,10 @@ bool TechnologyManager::add_technology(std::string_view identifier, TechnologyAr
return false;
}
- return technologies.add_item({ identifier, *area, year, cost, unciv_military, unit, activated_units, activated_buildings, std::move(values) });
+ return technologies.add_item({
+ identifier, *area, year, cost, unciv_military, unit, std::move(activated_units), std::move(activated_buildings),
+ std::move(values)
+ });
}
bool TechnologyManager::add_technology_school(std::string_view identifier, ModifierValue&& values) {
@@ -100,34 +114,37 @@ bool TechnologyManager::load_technology_file_schools(ModifierManager const& modi
bool TechnologyManager::load_technologies_file(ModifierManager const& modifier_manager, UnitManager const& unit_manager, BuildingManager const& building_manager, ast::NodeCPtr root) {
return expect_dictionary_reserve_length(technologies, [this, &modifier_manager, &unit_manager, &building_manager](std::string_view tech_key, ast::NodeCPtr tech_value) -> bool {
ModifierValue modifiers;
- std::string_view area_identifier;
- Technology::year_t year;
- fixed_point_t cost;
+ TechnologyArea const* area = nullptr;
+ Technology::year_t year = 0;
+ fixed_point_t cost = 0;
bool unciv_military = false;
- uint8_t unit = 0;
+ uint8_t unit = 0;
Technology::unit_set_t activated_units;
Technology::building_set_t activated_buildings;
-
+
bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(modifiers),
- "area", ONE_EXACTLY, expect_identifier(assign_variable_callback(area_identifier)),
+ "area", ONE_EXACTLY, expect_technology_area_identifier(assign_variable_callback_pointer(area)),
"year", ONE_EXACTLY, expect_uint(assign_variable_callback(year)),
"cost", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(cost)),
"unciv_military", ZERO_OR_ONE, expect_bool(assign_variable_callback(unciv_military)),
"unit", ZERO_OR_ONE, expect_uint(assign_variable_callback(unit)),
- "activate_unit", ZERO_OR_MORE, expect_identifier([this, &unit_manager, &activated_units](std::string_view identifier) -> bool {
- activated_units.insert(unit_manager.get_unit_by_identifier(identifier));
- return true;
- }),
- "activate_building", ZERO_OR_MORE, expect_identifier([this, &building_manager, &activated_buildings](std::string_view identifier) -> bool {
- activated_buildings.insert(building_manager.get_building_type_by_identifier(identifier));
+ "activate_unit", ZERO_OR_MORE, unit_manager.expect_unit_identifier([&activated_units](Unit const& unit) -> bool {
+ activated_units.insert(&unit);
return true;
}),
- "ai_chance", ONE_EXACTLY, expect_dictionary([this](std::string_view identifier, ast::NodeCPtr value) -> bool { return true; }) //TODO
+ "activate_building", ZERO_OR_MORE, building_manager.expect_building_type_identifier(
+ [&activated_buildings](BuildingType const& building_type) -> bool {
+ activated_buildings.insert(&building_type);
+ return true;
+ }
+ ),
+ "ai_chance", ONE_EXACTLY, success_callback //TODO
)(tech_value);
- TechnologyArea const* area = get_technology_area_by_identifier(area_identifier);
-
- ret &= add_technology(tech_key, area, year, cost, unciv_military, unit, activated_units, activated_buildings, std::move(modifiers));
+ ret &= add_technology(
+ tech_key, area, year, cost, unciv_military, unit, std::move(activated_units), std::move(activated_buildings),
+ std::move(modifiers)
+ );
return ret;
})(root);
}
@@ -135,12 +152,14 @@ bool TechnologyManager::load_technologies_file(ModifierManager const& modifier_m
bool TechnologyManager::generate_modifiers(ModifierManager& modifier_manager) {
bool ret = true;
- ret &= modifier_manager.add_modifier_effect("unciv_military_modifier", true, ModifierEffect::format_t::PROPORTION_DECIMAL);
- ret &= modifier_manager.add_modifier_effect("unciv_economic_modifier", true, ModifierEffect::format_t::PROPORTION_DECIMAL);
+ ret &= modifier_manager.add_modifier_effect("unciv_military_modifier", true);
+ ret &= modifier_manager.add_modifier_effect("unciv_economic_modifier", true);
+ ret &= modifier_manager.add_modifier_effect("self_unciv_economic_modifier", true);
+ ret &= modifier_manager.add_modifier_effect("self_unciv_military_modifier", true);
for (TechnologyFolder const& folder : get_technology_folders()) {
std::string folder_name = std::string(folder.get_identifier()) + "_research_bonus";
- ret &= modifier_manager.add_modifier_effect(folder_name, true, ModifierEffect::format_t::PROPORTION_DECIMAL);
+ ret &= modifier_manager.add_modifier_effect(folder_name, true);
}
return ret;
} \ No newline at end of file
diff --git a/src/openvic-simulation/tech/Technology.hpp b/src/openvic-simulation/tech/Technology.hpp
index 0aca1f6..6f50f01 100644
--- a/src/openvic-simulation/tech/Technology.hpp
+++ b/src/openvic-simulation/tech/Technology.hpp
@@ -11,7 +11,7 @@ namespace OpenVic {
friend struct TechnologyManager;
private:
- TechnologyFolder(std::string_view identifier);
+ TechnologyFolder(std::string_view new_identifier);
public:
TechnologyFolder(TechnologyFolder&&) = default;
@@ -23,7 +23,7 @@ namespace OpenVic {
private:
TechnologyFolder const& PROPERTY(folder);
- TechnologyArea(std::string_view identifier, TechnologyFolder const& folder);
+ TechnologyArea(std::string_view new_identifier, TechnologyFolder const& new_folder);
public:
TechnologyArea(TechnologyArea&&) = default;
@@ -31,6 +31,7 @@ namespace OpenVic {
struct Technology : Modifier {
friend struct TechnologyManager;
+
using year_t = Date::year_t;
using unit_set_t = std::unordered_set<Unit const*>;
using building_set_t = std::unordered_set<BuildingType const*>;
@@ -46,8 +47,12 @@ namespace OpenVic {
//TODO: implement rules/modifiers and ai_chance
- Technology(std::string_view identifier, TechnologyArea const& area, year_t year, fixed_point_t cost, bool unciv_military, uint8_t unit, unit_set_t activated_units, building_set_t activated_buildings, ModifierValue&& values);
-
+ Technology(
+ std::string_view new_identifier, TechnologyArea const& new_area, year_t new_year, fixed_point_t new_cost,
+ bool new_unciv_military, uint8_t new_unit, unit_set_t&& new_activated_units,
+ building_set_t&& new_activated_buildings, ModifierValue&& new_values
+ );
+
public:
Technology(Technology&&) = default;
};
@@ -74,15 +79,21 @@ namespace OpenVic {
bool add_technology_area(std::string_view identifier, TechnologyFolder const* folder);
IDENTIFIER_REGISTRY_ACCESSORS(technology_area)
- bool add_technology(std::string_view identifier, TechnologyArea const* area, Technology::year_t year, fixed_point_t cost, bool unciv_military, uint8_t unit, Technology::unit_set_t activated_units, Technology::building_set_t activated_buildings, ModifierValue&& values);
+ bool add_technology(
+ std::string_view identifier, TechnologyArea const* area, Technology::year_t year, fixed_point_t cost,
+ bool unciv_military, uint8_t unit, Technology::unit_set_t&& activated_units,
+ Technology::building_set_t&& activated_buildings, ModifierValue&& values);
IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(technology, technologies)
- bool add_technology_school(std::string_view identifier, ModifierValue&& values); //, Modifier::icon_t icon);
+ bool add_technology_school(std::string_view identifier, ModifierValue&& values);
IDENTIFIER_REGISTRY_ACCESSORS(technology_school);
bool load_technology_file_areas(ast::NodeCPtr root); // common/technology.txt
bool load_technology_file_schools(ModifierManager const& modifier_manager, ast::NodeCPtr root); // also common/technology.txt
- bool load_technologies_file(ModifierManager const& modifier_manager, UnitManager const& unit_manager, BuildingManager const& building_manager, ast::NodeCPtr root); // technologies/*.txt
+ bool load_technologies_file(
+ ModifierManager const& modifier_manager, UnitManager const& unit_manager, BuildingManager const& building_manager,
+ ast::NodeCPtr root
+ ); // technologies/*.txt
bool generate_modifiers(ModifierManager& modifier_manager);
};
} \ No newline at end of file
diff --git a/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp
index ffe1ee9..4bff710 100644
--- a/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp
@@ -167,7 +167,7 @@ namespace OpenVic {
);
add_requirement(ECON_244);
Requirement* ECON_245 = new Requirement(
- "ECON_245", "The base price for Precious Metal shall be 8",
+ "ECON_245", "The base price for Precious Metal shall be 8",
"The base price of 8 for Precious Metal can be seen in program output data"
);
add_requirement(ECON_245);
@@ -449,7 +449,7 @@ namespace OpenVic {
check_base_price("paper", "3.4", "ECON_244");
// ECON_245
- // The base price for Precious Metal shall be 8
+ // The base price for Precious Metal shall be 8
// The base price of 8 for Precious Metal can be seen in program output data
check_base_price("precious_metal", "8.0", "ECON_245");
diff --git a/src/openvic-simulation/types/Date.cpp b/src/openvic-simulation/types/Date.cpp
index 1b15e45..7356768 100644
--- a/src/openvic-simulation/types/Date.cpp
+++ b/src/openvic-simulation/types/Date.cpp
@@ -100,6 +100,12 @@ std::ostream& OpenVic::operator<<(std::ostream& out, Timespan const& timespan) {
return out << timespan.to_string();
}
+const std::string Date::MONTH_NAMES[MONTHS_IN_YEAR] = {
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November",
+ "December"
+};
+
Timespan Date::_date_to_timespan(year_t year, month_t month, day_t day) {
month = std::clamp<month_t>(month, 1, MONTHS_IN_YEAR);
day = std::clamp<day_t>(day, 1, DAYS_IN_MONTH[month - 1]);
@@ -208,6 +214,15 @@ bool Date::in_range(Date start, Date end) const {
return start <= *this && *this <= end;
}
+std::string const& Date::get_month_name() const {
+ const month_t month = get_month();
+ if (1 <= month && month <= MONTHS_IN_YEAR) {
+ return MONTH_NAMES[month - 1];
+ }
+ static const std::string invalid_month_name = "Invalid Month";
+ return invalid_month_name;
+}
+
std::string Date::to_string() const {
std::stringstream ss;
ss << *this;
diff --git a/src/openvic-simulation/types/Date.hpp b/src/openvic-simulation/types/Date.hpp
index cce1308..a78b4e6 100644
--- a/src/openvic-simulation/types/Date.hpp
+++ b/src/openvic-simulation/types/Date.hpp
@@ -58,6 +58,7 @@ namespace OpenVic {
static month_t const* MONTH_FROM_DAY_IN_YEAR;
static constexpr char SEPARATOR_CHARACTER = '.';
+ static const std::string MONTH_NAMES[MONTHS_IN_YEAR];
private:
// Number of days since Jan 1st, Year 0
@@ -93,6 +94,10 @@ namespace OpenVic {
bool in_range(Date start, Date end) const;
+ /* This returns a std::string const&, rather than a std::string_view, as it needs to be converted to a
+ * godot::StringName in order to be localised, and std::string_view to a godot::StringName conversion requires an
+ * intermediary std::string. */
+ std::string const& get_month_name() const;
std::string to_string() const;
explicit operator std::string() const;
// Parsed from string of the form YYYY.MM.DD
diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp
index 072ab07..cfb4fed 100644
--- a/src/openvic-simulation/types/IdentifierRegistry.hpp
+++ b/src/openvic-simulation/types/IdentifierRegistry.hpp
@@ -197,7 +197,7 @@ namespace OpenVic {
return nullptr; \
} \
value_type CONST* get_item_by_index(size_t index) CONST { \
- return index < items.size() ? &items[index] : nullptr; \
+ return index < items.size() ? GetPointer(items[index]) : nullptr; \
} \
NodeTools::callback_t<std::string_view> expect_item_str( \
NodeTools::callback_t<value_type CONST&> callback, bool warn \
@@ -315,72 +315,98 @@ namespace OpenVic {
template<std::derived_from<HasIdentifier> _Type>
using IdentifierInstanceRegistry = InstanceRegistry<_Type, _get_identifier<_Type>>;
+/* Member functions for const access to a UniqueKeyRegistry member variable. */
+#define IDENTIFIER_REGISTRY_ACCESSORS(name) \
+ IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(name, name##s)
+
#define IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(singular, plural) \
+ IDENTIFIER_REGISTRY_ACCESSORS_FULL_CUSTOM(singular, plural, plural, 0)
+
+#define IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_INDEX_OFFSET(name, index_offset) \
+ IDENTIFIER_REGISTRY_ACCESSORS_FULL_CUSTOM(name, name##s, name##s, index_offset)
+
+#define IDENTIFIER_REGISTRY_ACCESSORS_FULL_CUSTOM(singular, plural, registry, index_offset) \
void lock_##plural() { \
- plural.lock(); \
+ registry.lock(); \
} \
bool plural##_are_locked() const { \
- return plural.is_locked(); \
+ return registry.is_locked(); \
} \
- decltype(plural)::value_type const* get_##singular##_by_identifier(std::string_view identifier) const { \
- return plural.get_item_by_identifier(identifier); \
+ decltype(registry)::value_type const* get_##singular##_by_identifier(std::string_view identifier) const { \
+ return registry.get_item_by_identifier(identifier); \
} \
bool has_##singular##_identifier(std::string_view identifier) const { \
- return plural.has_identifier(identifier); \
+ return registry.has_identifier(identifier); \
+ } \
+ decltype(registry)::value_type const* get_##singular##_by_index(size_t index) const { \
+ return index >= index_offset ? registry.get_item_by_index(index - index_offset) : nullptr; \
} \
size_t get_##singular##_count() const { \
- return plural.size(); \
+ return registry.size(); \
} \
bool plural##_empty() const { \
- return plural.empty(); \
+ return registry.empty(); \
} \
- std::vector<decltype(plural)::storage_type> const& get_##plural() const { \
- return plural.get_items(); \
+ std::vector<decltype(registry)::storage_type> const& get_##plural() const { \
+ return registry.get_items(); \
} \
std::vector<std::string_view> get_##singular##_identifiers() const { \
- return plural.get_item_identifiers(); \
+ return registry.get_item_identifiers(); \
} \
NodeTools::callback_t<std::string_view> expect_##singular##_str( \
- NodeTools::callback_t<decltype(plural)::value_type const&> callback, bool warn = false \
+ NodeTools::callback_t<decltype(registry)::value_type const&> callback, bool warn = false \
) const { \
- return plural.expect_item_str(callback, warn); \
+ return registry.expect_item_str(callback, warn); \
} \
NodeTools::node_callback_t expect_##singular##_identifier( \
- NodeTools::callback_t<decltype(plural)::value_type const&> callback, bool warn = false \
+ NodeTools::callback_t<decltype(registry)::value_type const&> callback, bool warn = false \
) const { \
- return plural.expect_item_identifier(callback, warn); \
+ return registry.expect_item_identifier(callback, warn); \
} \
NodeTools::node_callback_t expect_##singular##_dictionary( \
- NodeTools::callback_t<decltype(plural)::value_type const&, ast::NodeCPtr> callback \
+ NodeTools::callback_t<decltype(registry)::value_type const&, ast::NodeCPtr> callback \
) const { \
- return plural.expect_item_dictionary(callback); \
+ return registry.expect_item_dictionary(callback); \
} \
NodeTools::node_callback_t expect_##singular##_decimal_map( \
- NodeTools::callback_t<fixed_point_map_t<decltype(plural)::value_type const*>&&> callback \
+ NodeTools::callback_t<fixed_point_map_t<decltype(registry)::value_type const*>&&> callback \
) const { \
- return plural.expect_item_decimal_map(callback); \
+ return registry.expect_item_decimal_map(callback); \
}
+/* Member functions for non-const access to a UniqueKeyRegistry member variable. */
+#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(name) \
+ IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(name, name##s)
+
#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(singular, plural) \
- decltype(plural)::value_type* get_##singular##_by_identifier(std::string_view identifier) { \
- return plural.get_item_by_identifier(identifier); \
+ IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_FULL_CUSTOM(single, plural, plural, 0)
+
+#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_INDEX_OFFSET(name, index_offset) \
+ IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_FULL_CUSTOM(name, name##s, name##s, index_offset)
+
+#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_FULL_CUSTOM(singular, plural, registry, index_offset) \
+ decltype(registry)::value_type* get_##singular##_by_identifier(std::string_view identifier) { \
+ return registry.get_item_by_identifier(identifier); \
+ } \
+ decltype(registry)::value_type* get_##singular##_by_index(size_t index) { \
+ return index >= index_offset ? registry.get_item_by_index(index - index_offset) : nullptr; \
+ } \
+ std::vector<decltype(registry)::storage_type>& get_##plural() { \
+ return registry.get_items(); \
} \
NodeTools::callback_t<std::string_view> expect_##singular##_str( \
- NodeTools::callback_t<decltype(plural)::value_type&> callback, bool warn = false \
+ NodeTools::callback_t<decltype(registry)::value_type&> callback, bool warn = false \
) { \
- return plural.expect_item_str(callback, warn); \
+ return registry.expect_item_str(callback, warn); \
} \
NodeTools::node_callback_t expect_##singular##_identifier( \
- NodeTools::callback_t<decltype(plural)::value_type&> callback, bool warn = false \
+ NodeTools::callback_t<decltype(registry)::value_type&> callback, bool warn = false \
) { \
- return plural.expect_item_identifier(callback, warn); \
+ return registry.expect_item_identifier(callback, warn); \
} \
NodeTools::node_callback_t expect_##singular##_dictionary( \
- NodeTools::callback_t<decltype(plural)::value_type&, ast::NodeCPtr> callback \
+ NodeTools::callback_t<decltype(registry)::value_type&, ast::NodeCPtr> callback \
) { \
- return plural.expect_item_dictionary(callback); \
+ return registry.expect_item_dictionary(callback); \
}
-
-#define IDENTIFIER_REGISTRY_ACCESSORS(name) IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(name, name##s)
-#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(name) IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(name, name##s)
}
diff --git a/src/openvic-simulation/utility/Getters.hpp b/src/openvic-simulation/utility/Getters.hpp
index 1be9287..a722071 100644
--- a/src/openvic-simulation/utility/Getters.hpp
+++ b/src/openvic-simulation/utility/Getters.hpp
@@ -83,13 +83,13 @@ namespace OpenVic {
* manually specify the accessibility level, if your variable deviates from this norm; use PROPERTY_CUSTOM_NAME when
* you wish to manually specify the getter name; use PROPERTY_FULL if you want to specify everything.
* Examples:
- * int PROPERTY(x); // int x; int get_x() const;
- * const std::string PROPERTY(name); // const std::string name; std::string_view get_name() const;
- * std::vector<int> PROPERTY(sizes); // std::vector<int> sizes; std::vector<int> const& get_sizes() const;
- * uint8_t const* PROPERTY(data); // uint8_t const* data; uint8_t const* get_data() const;
- * colour_t* PROPERTY(pixels); // colour_t* pixels; colour_t const* get_pixels() const;
- * CultureGroup const& PROPERTY(group);// CultureGroup const& group; CultureGroup const& get_group() const;
- * Province& PROPERTY(province); // Province& province; Province const& get_province() const;
+ * int PROPERTY(x); // int x; int get_x() const;
+ * const std::string PROPERTY(name); // const std::string name; std::string_view get_name() const;
+ * std::vector<int> PROPERTY(sizes); // std::vector<int> sizes; std::vector<int> const& get_sizes() const;
+ * uint8_t const* PROPERTY(data); // uint8_t const* data; uint8_t const* get_data() const;
+ * colour_t* PROPERTY(pixels); // colour_t* pixels; colour_t const* get_pixels() const;
+ * CultureGroup const& PROPERTY(group);// CultureGroup const& group; CultureGroup const& get_group() const;
+ * Province& PROPERTY(province); // Province& province; Province const& get_province() const;
*/
#define PROPERTY(NAME) PROPERTY_ACCESS(NAME, private)
#define PROPERTY_CUSTOM_PREFIX(NAME, PREFIX) PROPERTY_CUSTOM_NAME(NAME, PREFIX##_##NAME)