diff options
author | hop311 <hop3114@gmail.com> | 2023-12-02 16:48:08 +0100 |
---|---|---|
committer | hop311 <hop3114@gmail.com> | 2023-12-02 20:14:29 +0100 |
commit | 4a899c1a9e83ab9476b85522751081be434caa35 (patch) | |
tree | f1f6276c91beceecdfd9b09083d1c91ea8b41b60 | |
parent | cd6875d5e0ca5e2545fd0e1647678cd18a6c81c2 (diff) |
Crime+event modifier loading + misc UI backend
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) |