From 5f3e1f3b1b021cbee243236ad8947f203d0416be Mon Sep 17 00:00:00 2001 From: Hop311 Date: Thu, 14 Sep 2023 09:34:54 +0100 Subject: Region + localisation loading --- src/openvic-simulation/map/Map.cpp | 24 ++++++++++++++++++++++++ src/openvic-simulation/map/Map.hpp | 1 + 2 files changed, 25 insertions(+) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 728fc42..74764d2 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -7,6 +7,7 @@ #include "openvic-simulation/utility/Logger.hpp" using namespace OpenVic; +using namespace OpenVic::NodeTools; Mapmode::Mapmode(const std::string_view new_identifier, index_t new_index, colour_func_t new_colour_func) : HasIdentifier { new_identifier }, @@ -503,3 +504,26 @@ bool Map::load_province_definitions(std::vector const& lines) { lock_provinces(); return ret; } + +/* TODO - add support for non-state province groupings used by some mods + * (currently they trigger "province already in other region" errors). + */ +bool Map::load_region_file(ast::NodeCPtr root) { + const bool ret = expect_dictionary_reserve_length( + regions, + [this](std::string_view region_identifier, ast::NodeCPtr region_node) -> bool { + std::vector province_identifiers; + bool ret = expect_list_reserve_length( + province_identifiers, + expect_identifier([&province_identifiers](std::string_view identifier) -> bool { + province_identifiers.push_back(identifier); + return true; + }) + )(region_node); + ret &= add_region(region_identifier, province_identifiers); + return ret; + } + )(root); + lock_regions(); + return ret; +} diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index 71719e2..d5157ef 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -113,5 +113,6 @@ namespace OpenVic { void tick(Date const& today); bool load_province_definitions(std::vector const& lines); + bool load_region_file(ast::NodeCPtr root); }; } -- cgit v1.2.3-56-ga3b1 From 46bbbb038e5fa21e25fa33c4fee84e4b14690885 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Thu, 14 Sep 2023 20:09:10 +0100 Subject: Meta region loading --- src/openvic-simulation/GameManager.cpp | 2 +- src/openvic-simulation/map/Building.cpp | 2 +- src/openvic-simulation/map/Map.cpp | 65 ++++++++++++++++++--------------- src/openvic-simulation/map/Province.cpp | 8 +++- src/openvic-simulation/map/Province.hpp | 5 ++- src/openvic-simulation/map/Region.cpp | 17 +++++++-- src/openvic-simulation/map/Region.hpp | 19 ++++++++-- 7 files changed, 75 insertions(+), 43 deletions(-) (limited to 'src/openvic-simulation/map') diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp index 0b42230..4c8b55f 100644 --- a/src/openvic-simulation/GameManager.cpp +++ b/src/openvic-simulation/GameManager.cpp @@ -63,7 +63,7 @@ bool GameManager::load_hardcoded_defines() { const std::vector mapmodes { { "mapmode_terrain", [](Map const&, Province const& province) -> colour_t { - return LOW_ALPHA_VALUE | (province.is_water() ? 0x4287F5 : 0x0D7017); + return LOW_ALPHA_VALUE | (province.get_water() ? 0x4287F5 : 0x0D7017); } }, { "mapmode_province", [](Map const&, Province const& province) -> colour_t { diff --git a/src/openvic-simulation/map/Building.cpp b/src/openvic-simulation/map/Building.cpp index 6e5cf18..eba2049 100644 --- a/src/openvic-simulation/map/Building.cpp +++ b/src/openvic-simulation/map/Building.cpp @@ -117,7 +117,7 @@ bool BuildingManager::generate_province_buildings(Province& province) const { return false; } bool ret = true; - if (!province.is_water()) { + if (!province.get_water()) { for (BuildingType const& type : building_types.get_items()) { ret &= province.add_building({ type }); } diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 74764d2..fa11f86 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -68,7 +68,7 @@ bool Map::set_water_province(const std::string_view identifier) { Logger::error("Unrecognised water province identifier: ", identifier); return false; } - if (province->is_water()) { + if (province->get_water()) { Logger::warning("Province ", identifier, " is already a water province!"); return true; } @@ -99,53 +99,60 @@ bool Map::add_region(const std::string_view identifier, std::vector(province->get_region()); - if (other_region_index != 0) { - other_region_index--; - if (other_region_index < regions.size()) - Logger::error("Cannot add province ", province_identifier, " to region ", identifier, " - it is already part of ", regions.get_item_by_index(other_region_index)->get_identifier()); - else - Logger::error("Cannot add province ", province_identifier, " to region ", identifier, " - it is already part of an unknown region with index ", other_region_index); - ret = false; - } else if (!new_region.add_province(province)) { - Logger::error("Failed to add province ", province_identifier, " to region ", identifier); - ret = false; + if (province->get_has_region()) { + meta = true; } + provinces.push_back(province); } } else { Logger::error("Invalid province identifier ", province_identifier, " for region ", identifier); ret = false; } } - new_region.lock(); - if (new_region.empty()) { - Logger::error("No valid provinces in list for ", identifier); - return false; + if (provinces.empty()) { + Logger::warning("No valid provinces in list for ", identifier); + return ret; } - // Used to detect provinces listed in multiple regions, will - // be corrected once regions is stable (i.e. lock_regions). - Region* tmp_region_index = reinterpret_cast(regions.size()); - for (Province* province : new_region.get_provinces()) - province->region = tmp_region_index; - ret &= regions.add_item(std::move(new_region)); + if (!meta) { + for (Province* province : provinces) { + province->has_region = true; + } + } + ret &= regions.add_item({ identifier, std::move(provinces), meta }); return ret; } void Map::lock_regions() { regions.lock(); - for (Region& region : regions.get_items()) - for (Province* province : region.get_provinces()) - province->region = ®ion; + for (Region& region : regions.get_items()) { + if (!region.meta) { + for (Province* province : region.get_provinces()) { + if (!province->get_has_region()) { + Logger::error("Province in non-meta region without has_region set: ", province->get_identifier()); + province->has_region = true; + } + province->region = ®ion; + } + } + } + for (Province& province : provinces.get_items()) { + const bool region_null = province.get_region() == nullptr; + if (province.get_has_region() == region_null) { + Logger::error("Province has_region / region mismatch: has_region = ", province.get_has_region(), ", region = ", province.get_region()); + province.has_region = !region_null; + } + } } size_t Map::get_province_count() const { @@ -421,7 +428,7 @@ bool Map::setup(GoodManager const& good_manager, BuildingManager const& building for (Province& province : provinces.get_items()) { province.clear_pops(); // Set all land provinces to have an RGO based on their index to test them - if (!province.is_water() && good_manager.get_good_count() > 0) + if (!province.get_water() && !good_manager.get_good_count() > 0) province.rgo = good_manager.get_good_by_index(province.get_index() % good_manager.get_good_count()); ret &= building_manager.generate_province_buildings(province); } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index f53de3a..b4a80b5 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -22,7 +22,11 @@ Region* Province::get_region() const { return region; } -bool Province::is_water() const { +bool Province::get_has_region() const { + return has_region; +} + +bool Province::get_water() const { return water; } @@ -64,7 +68,7 @@ bool Province::load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root) } bool Province::add_pop(Pop&& pop) { - if (!is_water()) { + if (!get_water()) { pops.push_back(std::move(pop)); return true; } else { diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index 67816ff..ca8138f 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -23,7 +23,7 @@ namespace OpenVic { private: const index_t index; Region* region = nullptr; - bool water = false; + bool has_region = false, water = false; life_rating_t life_rating = 0; IdentifierRegistry buildings; // TODO - change this into a factory-like structure @@ -40,7 +40,8 @@ namespace OpenVic { index_t get_index() const; Region* get_region() const; - bool is_water() const; + bool get_has_region() const; + bool get_water() const; life_rating_t get_life_rating() const; bool add_building(Building&& building); IDENTIFIER_REGISTRY_ACCESSORS(Building, building) diff --git a/src/openvic-simulation/map/Region.cpp b/src/openvic-simulation/map/Region.cpp index 33092c5..c0422de 100644 --- a/src/openvic-simulation/map/Region.cpp +++ b/src/openvic-simulation/map/Region.cpp @@ -2,6 +2,8 @@ using namespace OpenVic; +ProvinceSet::ProvinceSet(provinces_t&& new_provinces) : provinces { std::move(new_provinces) } {} + bool ProvinceSet::add_province(Province* province) { if (locked) { Logger::error("Cannot add province to province set - locked!"); @@ -57,13 +59,20 @@ bool ProvinceSet::contains_province(Province const* province) const { return province && std::find(provinces.begin(), provinces.end(), province) != provinces.end(); } -std::vector const& ProvinceSet::get_provinces() const { +ProvinceSet::provinces_t const& ProvinceSet::get_provinces() const { return provinces; } -Region::Region(const std::string_view new_identifier) : HasIdentifier { new_identifier } {} +Region::Region(const std::string_view new_identifier, provinces_t&& new_provinces, bool new_meta) + : HasIdentifier { new_identifier }, ProvinceSet { std::move(new_provinces) }, meta { new_meta } { + lock(); +} + +bool Region::get_meta() const { + return meta; +} colour_t Region::get_colour() const { - if (provinces.empty()) return FULL_COLOUR << 16; - return provinces.front()->get_colour(); + if (empty()) return FULL_COLOUR << 16; + return get_provinces().front()->get_colour(); } diff --git a/src/openvic-simulation/map/Region.hpp b/src/openvic-simulation/map/Region.hpp index 2fccf06..d68033b 100644 --- a/src/openvic-simulation/map/Region.hpp +++ b/src/openvic-simulation/map/Region.hpp @@ -5,11 +5,15 @@ namespace OpenVic { struct ProvinceSet { - protected: - std::vector provinces; + using provinces_t = std::vector; + + private: + provinces_t provinces; bool locked = false; public: + ProvinceSet(provinces_t&& new_provinces = {}); + bool add_province(Province* province); void lock(bool log = false); bool is_locked() const; @@ -18,7 +22,7 @@ namespace OpenVic { size_t size() const; void reserve(size_t size); bool contains_province(Province const* province) const; - std::vector const& get_provinces() const; + provinces_t const& get_provinces() const; }; /* REQUIREMENTS: @@ -28,11 +32,18 @@ namespace OpenVic { friend struct Map; private: - Region(const std::string_view new_identifier); + /* A meta region cannot be the template for a state. + * Any region containing a province already listed in a + * previously defined region is considered a meta region. + */ + const bool meta; + + Region(const std::string_view new_identifier, provinces_t&& new_provinces, bool new_meta); public: Region(Region&&) = default; + bool get_meta() const; colour_t get_colour() const; }; } -- cgit v1.2.3-56-ga3b1 From 8add7c666455a8a4edd9e02ca5a33f78a25e8f2c Mon Sep 17 00:00:00 2001 From: Hop311 Date: Fri, 15 Sep 2023 21:55:00 +0100 Subject: First go at Modifiers --- deps/openvic-dataloader | 2 +- src/openvic-simulation/Modifier.cpp | 115 +++++++++++++++++++++ src/openvic-simulation/Modifier.hpp | 95 +++++++++++++++++ src/openvic-simulation/dataloader/Dataloader.cpp | 28 +++-- src/openvic-simulation/dataloader/Dataloader.hpp | 7 +- src/openvic-simulation/economy/Good.cpp | 2 +- src/openvic-simulation/map/Map.cpp | 3 - src/openvic-simulation/map/Province.cpp | 2 +- src/openvic-simulation/pop/Culture.cpp | 2 +- src/openvic-simulation/pop/Pop.cpp | 2 +- src/openvic-simulation/pop/Religion.cpp | 2 +- src/openvic-simulation/types/Colour.hpp | 14 ++- .../types/IdentifierRegistry.cpp | 8 +- .../types/IdentifierRegistry.hpp | 4 +- 14 files changed, 248 insertions(+), 38 deletions(-) create mode 100644 src/openvic-simulation/Modifier.cpp create mode 100644 src/openvic-simulation/Modifier.hpp (limited to 'src/openvic-simulation/map') diff --git a/deps/openvic-dataloader b/deps/openvic-dataloader index 2564d91..8f71abc 160000 --- a/deps/openvic-dataloader +++ b/deps/openvic-dataloader @@ -1 +1 @@ -Subproject commit 2564d91f23a0b2a332d0d72023caa4091a56d1f1 +Subproject commit 8f71abc25ec993ce7e85f5342a52fb456bdba26f diff --git a/src/openvic-simulation/Modifier.cpp b/src/openvic-simulation/Modifier.cpp new file mode 100644 index 0000000..ed32ee2 --- /dev/null +++ b/src/openvic-simulation/Modifier.cpp @@ -0,0 +1,115 @@ +#include "Modifier.hpp" + +using namespace OpenVic; + +ModifierEffect::ModifierEffect(const std::string_view new_identifier, bool new_positive_good) + : HasIdentifier { new_identifier }, positive_good { new_positive_good } {} + +bool ModifierEffect::get_positive_good() const { + return positive_good; +} + +ModifierValue::ModifierValue() = default; +ModifierValue::ModifierValue(ModifierValue const&) = default; +ModifierValue::ModifierValue(ModifierValue&&) = default; + +void ModifierValue::trim() { + std::erase_if(values, [](effect_map_t::value_type const& value) -> bool { + return value.second == fixed_point_t::_0(); + }); +} + +size_t ModifierValue::get_effect_count() const { + return values.size(); +} + +fixed_point_t ModifierValue::get_effect(ModifierEffect const* effect, bool* successful) { + const effect_map_t::const_iterator it = values.find(effect); + if (it != values.end()) { + if (successful != nullptr) *successful = true; + return it->second; + } + if (successful != nullptr) *successful = false; + return fixed_point_t::_0(); +} + +bool ModifierValue::has_effect(ModifierEffect const* effect) const { + return values.find(effect) != values.end(); +} + +ModifierValue& ModifierValue::operator+=(ModifierValue const& right) { + for (effect_map_t::value_type const& value : right.values) { + values[value.first] += value.second; + } + return *this; +} + +ModifierValue ModifierValue::operator+(ModifierValue const& right) const { + ModifierValue ret = *this; + return ret += right; +} + +ModifierValue ModifierValue::operator-() const { + ModifierValue ret = *this; + for (effect_map_t::value_type& value : ret.values) { + value.second = -value.second; + } + return ret; +} + +ModifierValue& ModifierValue::operator-=(ModifierValue const& right) { + for (effect_map_t::value_type const& value : right.values) { + values[value.first] -= value.second; + } + return *this; +} + +ModifierValue ModifierValue::operator-(ModifierValue const& right) const { + ModifierValue ret = *this; + return ret -= right; +} + +std::ostream& OpenVic::operator<<(std::ostream& stream, ModifierValue const& value) { + for (ModifierValue::effect_map_t::value_type const& effect : value.values) { + stream << effect.first << ": " << effect.second << "\n"; + } + return stream; +} + +Modifier::Modifier(const std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon) + : HasIdentifier { new_identifier }, ModifierValue { std::move(new_values) }, icon { new_icon } {} + +Modifier::icon_t Modifier::get_icon() const { + return icon; +} + +Modifier const& ModifierInstance::get_modifier() const { + return modifier; +} + +Date const& ModifierInstance::get_expiry_date() const { + return expiry_date; +} + +ModifierManager::ModifierManager() + : modifier_effects { "modifier effects"}, modifiers { "modifiers" } {} + +bool ModifierManager::add_modifier_effect(const std::string_view identifier, bool positive_good) { + if (identifier.empty()) { + Logger::error("Invalid modifier effect identifier - empty!"); + return false; + } + return modifier_effects.add_item({ identifier, positive_good }); +} + +bool ModifierManager::add_modifier(const 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 modifiers.add_item({ identifier, std::move(values), icon }); +} diff --git a/src/openvic-simulation/Modifier.hpp b/src/openvic-simulation/Modifier.hpp new file mode 100644 index 0000000..e8c4c8b --- /dev/null +++ b/src/openvic-simulation/Modifier.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include "openvic-simulation/types/IdentifierRegistry.hpp" + +namespace OpenVic { + struct ModifierManager; + + struct ModifierEffect : HasIdentifier { + friend struct ModifierManager; + + private: + /* If true, positive values will be green and negative values will be red. + * If false, the colours will be switced. + */ + const bool positive_good; + + // TODO - format/precision, e.g. 80% vs 0.8 vs 0.800, 2 vs 2.0 vs 200% + + ModifierEffect(const std::string_view new_identifier, bool new_positive_good); + + public: + ModifierEffect(ModifierEffect&&) = default; + + bool get_positive_good() const; + }; + + struct ModifierValue { + using effect_map_t = std::map; + private: + effect_map_t values; + + public: + ModifierValue(); + ModifierValue(ModifierValue const&); + ModifierValue(ModifierValue&&); + + /* Removes effect entries with a value of zero. */ + void trim(); + size_t get_effect_count() const; + + fixed_point_t get_effect(ModifierEffect const* effect, bool* successful = nullptr); + bool has_effect(ModifierEffect const* effect) const; + + ModifierValue& operator+=(ModifierValue const& right); + ModifierValue operator+(ModifierValue const& right) const; + ModifierValue operator-() const; + ModifierValue& operator-=(ModifierValue const& right); + ModifierValue operator-(ModifierValue const& right) const; + + friend std::ostream& operator<<(std::ostream& stream, ModifierValue const& value); + }; + + struct Modifier : HasIdentifier, ModifierValue { + friend struct ModifierManager; + + using icon_t = uint8_t; + + private: + const icon_t icon; + + Modifier(const std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon); + + public: + Modifier(Modifier&&) = default; + + icon_t get_icon() const; + }; + + struct ModifierInstance { + + private: + Modifier const& modifier; + Date expiry_date; + + public: + Modifier const& get_modifier() const; + Date const& get_expiry_date() const; + }; + + struct ModifierManager { + + private: + IdentifierRegistry modifier_effects; + IdentifierRegistry modifiers; + + public: + ModifierManager(); + + bool add_modifier_effect(const std::string_view identifier, bool province_good); + IDENTIFIER_REGISTRY_ACCESSORS(ModifierEffect, modifier_effect) + + bool add_modifier(const std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon); + IDENTIFIER_REGISTRY_ACCESSORS(Modifier, modifier) + }; +} diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index c409e1d..e85f499 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -49,9 +49,6 @@ fs::path Dataloader::lookup_file(fs::path const& path) const { return {}; } -const fs::path Dataloader::TXT = ".txt"; -const fs::path Dataloader::CSV = ".csv"; - static bool contains_file_with_name(Dataloader::path_vector_t const& paths, fs::path const& name) { for (fs::path const& path : paths) { @@ -60,8 +57,7 @@ static bool contains_file_with_name(Dataloader::path_vector_t const& paths, fs:: return false; } -Dataloader::path_vector_t Dataloader::lookup_files_in_dir(fs::path const& path, fs::path const* extension) const { - +Dataloader::path_vector_t Dataloader::lookup_files_in_dir(fs::path const& path, fs::path const& extension) const { path_vector_t ret; for (fs::path const& root : roots) { const fs::path composed = root / path; @@ -69,7 +65,7 @@ Dataloader::path_vector_t Dataloader::lookup_files_in_dir(fs::path const& path, for (fs::directory_entry const& entry : fs::directory_iterator { composed, ec }) { if (entry.is_regular_file()) { const fs::path file = entry; - if (extension == nullptr || file.extension() == *extension) { + if (extension.empty() || file.extension() == extension) { if (!contains_file_with_name(ret, file.filename())) { ret.push_back(file); } @@ -80,7 +76,7 @@ Dataloader::path_vector_t Dataloader::lookup_files_in_dir(fs::path const& path, return ret; } -bool Dataloader::apply_to_files_in_dir(fs::path const& path, std::function callback, fs::path const* extension) const { +bool Dataloader::apply_to_files_in_dir(fs::path const& path, fs::path const& extension, std::function callback) const { bool ret = true; for (fs::path const& file : lookup_files_in_dir(path, extension)) { @@ -108,7 +104,7 @@ static Parser _run_ovdl_parser(fs::path const& path) { parser.set_error_log_to(error_log_stream); parser.load_from_file(path); if (!buffer.empty()) { - Logger::error("Parser load errors:\n\n", buffer, "\n"); + Logger::error("Parser load errors for ", path, ":\n\n", buffer, "\n"); buffer.clear(); } if (parser.has_fatal_error() || parser.has_error()) { @@ -116,10 +112,10 @@ static Parser _run_ovdl_parser(fs::path const& path) { return parser; } if (!parse_func(parser)) { - Logger::error("Parse function returned false!"); + Logger::error("Parse function returned false for ", path, "!"); } if (!buffer.empty()) { - Logger::error("Parser parse errors:\n\n", buffer, "\n"); + Logger::error("Parser parse errors for ", path, ":\n\n", buffer, "\n"); buffer.clear(); } if (parser.has_fatal_error() || parser.has_error()) { @@ -145,7 +141,7 @@ static csv::Windows1252Parser _parse_csv(fs::path const& path) { } bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const { - const bool ret = apply_to_files_in_dir(pop_type_directory, + const bool ret = apply_to_files_in_dir(pop_type_directory, ".txt", [&pop_manager](fs::path const& file) -> bool { return pop_manager.load_pop_type_file(file.stem().string(), _parse_defines(file).get_file_node()); } @@ -283,7 +279,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { } bool Dataloader::load_pop_history(GameManager& game_manager, fs::path const& path) const { - return apply_to_files_in_dir(path, + return apply_to_files_in_dir(path, ".txt", [&game_manager](fs::path const& file) -> bool { return expect_dictionary( [&game_manager](std::string_view province_key, ast::NodeCPtr province_node) -> bool { @@ -317,7 +313,9 @@ static bool _load_localisation_file(Dataloader::localisation_callback_t callback } bool Dataloader::load_localisation_files(localisation_callback_t callback, fs::path const& localisation_dir) { - return apply_to_files_in_dir(localisation_dir, [callback](fs::path path) -> bool { - return _load_localisation_file(callback, _parse_csv(path).get_lines()); - }, &CSV); + return apply_to_files_in_dir(localisation_dir, ".csv", + [callback](fs::path path) -> bool { + return _load_localisation_file(callback, _parse_csv(path).get_lines()); + } + ); } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index d93ca39..2b358b6 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -31,10 +31,9 @@ namespace OpenVic { * DAT-24 */ fs::path lookup_file(fs::path const& path) const; - static const fs::path TXT, CSV; - path_vector_t lookup_files_in_dir(fs::path const& path, fs::path const* extension = &TXT) const; - bool apply_to_files_in_dir(fs::path const& path, std::function callback, - fs::path const* extension = &TXT) const; + path_vector_t lookup_files_in_dir(fs::path const& path, fs::path const& extension) const; + bool apply_to_files_in_dir(fs::path const& path, fs::path const& extension, + std::function callback) const; bool load_defines(GameManager& game_manager) const; bool load_pop_history(GameManager& game_manager, fs::path const& path) const; diff --git a/src/openvic-simulation/economy/Good.cpp b/src/openvic-simulation/economy/Good.cpp index e3dbd3e..6edf631 100644 --- a/src/openvic-simulation/economy/Good.cpp +++ b/src/openvic-simulation/economy/Good.cpp @@ -9,7 +9,7 @@ GoodCategory::GoodCategory(const std::string_view new_identifier) : HasIdentifie Good::Good(const 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, true }, + : HasIdentifierAndColour { new_identifier, new_colour, true, false }, category { new_category }, base_price { new_base_price }, available_from_start { new_available_from_start }, diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index fa11f86..e8178e9 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -512,9 +512,6 @@ bool Map::load_province_definitions(std::vector const& lines) { return ret; } -/* TODO - add support for non-state province groupings used by some mods - * (currently they trigger "province already in other region" errors). - */ bool Map::load_region_file(ast::NodeCPtr root) { const bool ret = expect_dictionary_reserve_length( regions, diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index b4a80b5..49a9bfc 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -8,7 +8,7 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; Province::Province(const std::string_view new_identifier, colour_t new_colour, index_t new_index) - : HasIdentifierAndColour { new_identifier, new_colour, false }, + : HasIdentifierAndColour { new_identifier, new_colour, false, false }, index { new_index }, buildings { "buildings", false } { assert(index != NULL_INDEX); diff --git a/src/openvic-simulation/pop/Culture.cpp b/src/openvic-simulation/pop/Culture.cpp index 709f305..bf14df9 100644 --- a/src/openvic-simulation/pop/Culture.cpp +++ b/src/openvic-simulation/pop/Culture.cpp @@ -27,7 +27,7 @@ bool CultureGroup::get_is_overseas() const { Culture::Culture(const std::string_view new_identifier, colour_t new_colour, CultureGroup const& new_group, std::vector const& new_first_names, std::vector const& new_last_names) - : HasIdentifierAndColour { new_identifier, new_colour, true }, + : HasIdentifierAndColour { new_identifier, new_colour, true, false }, group { new_group }, first_names { new_first_names }, last_names { new_last_names } {} diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp index f8e7254..1c11b80 100644 --- a/src/openvic-simulation/pop/Pop.cpp +++ b/src/openvic-simulation/pop/Pop.cpp @@ -53,7 +53,7 @@ PopType::PopType(const std::string_view new_identifier, colour_t new_colour, strata_t new_strata, sprite_t new_sprite, 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) - : HasIdentifierAndColour { new_identifier, new_colour, true }, + : HasIdentifierAndColour { new_identifier, new_colour, true, false }, strata { new_strata }, sprite { new_sprite }, max_size { new_max_size }, diff --git a/src/openvic-simulation/pop/Religion.cpp b/src/openvic-simulation/pop/Religion.cpp index 0652eb2..ec919fe 100644 --- a/src/openvic-simulation/pop/Religion.cpp +++ b/src/openvic-simulation/pop/Religion.cpp @@ -9,7 +9,7 @@ ReligionGroup::ReligionGroup(const std::string_view new_identifier) : HasIdentif Religion::Religion(const std::string_view new_identifier, colour_t new_colour, ReligionGroup const& new_group, icon_t new_icon, bool new_pagan) - : HasIdentifierAndColour { new_identifier, new_colour, true }, + : HasIdentifierAndColour { new_identifier, new_colour, true, false }, group { new_group }, icon { new_icon }, pagan { new_pagan } { diff --git a/src/openvic-simulation/types/Colour.hpp b/src/openvic-simulation/types/Colour.hpp index 01f3852..15c574f 100644 --- a/src/openvic-simulation/types/Colour.hpp +++ b/src/openvic-simulation/types/Colour.hpp @@ -7,30 +7,36 @@ #include namespace OpenVic { - // Represents a 24-bit RGB integer OR a 32-bit ARGB integer + /* Colour represented by an unsigned integer, either 24-bit RGB or 32-bit ARGB. */ using colour_t = uint32_t; + /* When colour_t is used as an identifier, NULL_COLOUR is disallowed * and should be reserved as an error value. * When colour_t is used in a purely graphical context, NULL_COLOUR * should be allowed. */ - static constexpr colour_t NULL_COLOUR = 0, FULL_COLOUR = 0xFF, MAX_COLOUR_RGB = 0xFFFFFF; + static constexpr colour_t NULL_COLOUR = 0, FULL_COLOUR = 0xFF, + MAX_COLOUR_RGB = 0xFFFFFF, MAX_COLOUR_ARGB = 0xFFFFFFFF; + constexpr colour_t float_to_colour_byte(float f, float min = 0.0f, float max = 1.0f) { return static_cast(std::clamp(min + f * (max - min), min, max) * 255.0f); } + constexpr colour_t fraction_to_colour_byte(int n, int d, float min = 0.0f, float max = 1.0f) { return float_to_colour_byte(static_cast(n) / static_cast(d), min, max); } + constexpr colour_t float_to_alpha_value(float a) { return float_to_colour_byte(a) << 24; } + constexpr float colour_byte_to_float(colour_t colour) { return std::clamp(static_cast(colour) / 255.0f, 0.0f, 1.0f); } - inline std::string colour_to_hex_string(colour_t colour) { + inline std::string colour_to_hex_string(colour_t colour, bool alpha = false) { std::ostringstream stream; - stream << std::hex << std::setfill('0') << std::setw(6) << colour; + stream << std::uppercase << std::hex << std::setfill('0') << std::setw(!alpha ? 6 : 8) << colour; return stream.str(); } } diff --git a/src/openvic-simulation/types/IdentifierRegistry.cpp b/src/openvic-simulation/types/IdentifierRegistry.cpp index e33bc29..f284164 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.cpp +++ b/src/openvic-simulation/types/IdentifierRegistry.cpp @@ -21,8 +21,8 @@ std::ostream& OpenVic::operator<<(std::ostream& stream, HasIdentifier const* obj return obj != nullptr ? stream << *obj : stream << ""; } -HasColour::HasColour(colour_t const new_colour, bool can_be_null) : colour(new_colour) { - assert((can_be_null || colour != NULL_COLOUR) && colour <= MAX_COLOUR_RGB); +HasColour::HasColour(colour_t const new_colour, bool can_be_null, bool can_have_alpha) : colour(new_colour) { + assert((can_be_null || colour != NULL_COLOUR) && colour <= (!can_have_alpha ? MAX_COLOUR_RGB : MAX_COLOUR_ARGB)); } colour_t HasColour::get_colour() const { return colour; } @@ -32,9 +32,9 @@ std::string HasColour::colour_to_hex_string() const { } HasIdentifierAndColour::HasIdentifierAndColour(const std::string_view new_identifier, - const colour_t new_colour, bool can_be_null) + const colour_t new_colour, bool can_be_null, bool can_have_alpha) : HasIdentifier { new_identifier }, - HasColour { new_colour, can_be_null } {} + HasColour { new_colour, can_be_null, can_have_alpha } {} distribution_t::value_type OpenVic::get_largest_item(distribution_t const& dist) { const distribution_t::const_iterator result = std::max_element(dist.begin(), dist.end(), diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp index 20eebb9..3f73a2c 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -37,7 +37,7 @@ namespace OpenVic { const colour_t colour; protected: - HasColour(const colour_t new_colour, bool can_be_null); + HasColour(const colour_t new_colour, bool can_be_null, bool can_have_alpha); public: HasColour(HasColour const&) = delete; @@ -55,7 +55,7 @@ namespace OpenVic { */ class HasIdentifierAndColour : public HasIdentifier, public HasColour { protected: - HasIdentifierAndColour(const std::string_view new_identifier, const colour_t new_colour, bool can_be_null); + HasIdentifierAndColour(const std::string_view new_identifier, const colour_t new_colour, bool can_be_null, bool can_have_alpha); public: HasIdentifierAndColour(HasIdentifierAndColour const&) = delete; -- cgit v1.2.3-56-ga3b1