From e031758cf68535e97045c07f36e2524676447778 Mon Sep 17 00:00:00 2001 From: hop311 Date: Tue, 14 Nov 2023 21:27:39 +0000 Subject: Striped mapmode and improved distributions --- src/openvic-simulation/map/Map.hpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/openvic-simulation/map/Map.hpp') diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index d11ad8e..db67390 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -14,7 +14,10 @@ namespace OpenVic { struct Mapmode : HasIdentifier { friend struct Map; - using colour_func_t = std::function; + /* Bottom 32 bits are the base colour, top 32 are the stripe colour, both in ARGB format with the alpha channels + * controlling interpolation with the terrain colour (0 = all terrain, 255 = all corresponding RGB) */ + using base_stripe_t = uint64_t; + using colour_func_t = std::function; using index_t = size_t; private: @@ -29,7 +32,7 @@ namespace OpenVic { Mapmode(Mapmode&&) = default; index_t get_index() const; - colour_t get_colour(Map const& map, Province const& province) const; + base_stripe_t get_base_stripe_colours(Map const& map, Province const& province) const; }; struct GoodManager; @@ -98,7 +101,12 @@ 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; - static constexpr size_t MAPMODE_COLOUR_SIZE = 4; + + /* 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 + * and A = 255 is fully the RGB colour packaged with A. The base and stripe colours for each province are packed + * together adjacently, so each province's entry is 8 bytes long. The list contains Province::MAX_INDEX + 1 entries, + * that is the maximum allowed number of provinces plus one for the index-zero "null province". */ bool generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) const; bool setup(BuildingManager const& building_manager, PopManager const& pop_manager); -- cgit v1.2.3-56-ga3b1 From 8271b1519e095ee3e7245cde2f0b54561c3ec619 Mon Sep 17 00:00:00 2001 From: hop311 Date: Tue, 14 Nov 2023 21:42:00 +0000 Subject: Bookmark loading + province and building cleanup --- src/openvic-simulation/GameManager.cpp | 25 ++- src/openvic-simulation/GameManager.hpp | 7 +- src/openvic-simulation/country/CountryInstance.cpp | 2 +- src/openvic-simulation/dataloader/Dataloader.cpp | 4 +- src/openvic-simulation/economy/Building.cpp | 155 ++-------------- src/openvic-simulation/economy/Building.hpp | 138 +++++--------- src/openvic-simulation/history/HistoryManager.hpp | 4 - src/openvic-simulation/history/HistoryMap.hpp | 15 +- src/openvic-simulation/history/ProvinceHistory.cpp | 4 +- src/openvic-simulation/history/ProvinceHistory.hpp | 5 +- src/openvic-simulation/map/Map.cpp | 23 ++- src/openvic-simulation/map/Map.hpp | 4 +- src/openvic-simulation/map/Province.cpp | 201 ++++++++------------- src/openvic-simulation/map/Province.hpp | 79 +++----- src/openvic-simulation/misc/Define.cpp | 25 +-- src/openvic-simulation/misc/Define.hpp | 7 +- src/openvic-simulation/types/Date.cpp | 4 + src/openvic-simulation/types/Date.hpp | 2 + .../types/IdentifierRegistry.hpp | 3 + 19 files changed, 259 insertions(+), 448 deletions(-) (limited to 'src/openvic-simulation/map/Map.hpp') diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp index 755ab37..ed450de 100644 --- a/src/openvic-simulation/GameManager.cpp +++ b/src/openvic-simulation/GameManager.cpp @@ -37,18 +37,31 @@ void GameManager::tick() { set_needs_update(); } -bool GameManager::setup() { +bool GameManager::reset() { session_start = time(nullptr); clock.reset(); - today = { 1836 }; + today = {}; economy_manager.get_good_manager().reset_to_defaults(); - bool ret = map.setup(economy_manager.get_building_manager(), pop_manager); + bool ret = map.reset(economy_manager.get_building_manager()); set_needs_update(); return ret; } -Date GameManager::get_today() const { - return today; +bool GameManager::load_bookmark(Bookmark const* new_bookmark) { + bool ret = reset(); + bookmark = new_bookmark; + if (bookmark == nullptr) { + return ret; + } + Logger::info("Loading bookmark ", bookmark->get_name(), " with start date ", bookmark->get_date()); + if (!define_manager.in_game_period(bookmark->get_date())) { + Logger::warning("Bookmark date ", bookmark->get_date(), " is not in the game's time period!"); + } + today = bookmark->get_date(); + ret &= map.apply_history_to_provinces(history_manager.get_province_manager(), today); + // TODO - apply country history + // TODO - apply pop history + return ret; } bool GameManager::expand_building(Province::index_t province_index, std::string_view building_type_identifier) { @@ -156,7 +169,7 @@ bool GameManager::load_hardcoded_defines() { make_solid_base_stripe_func([](Map const& map, Province const& province) -> colour_t { BuildingInstance const* railroad = province.get_building_by_identifier("railroad"); if (railroad != nullptr) { - colour_t val = fraction_to_colour_byte(railroad->get_current_level(), + colour_t val = fraction_to_colour_byte(railroad->get_level(), railroad->get_building().get_max_level() + 1, 0.5f, 1.0f); switch (railroad->get_expansion_state()) { case ExpansionState::CannotExpand: diff --git a/src/openvic-simulation/GameManager.hpp b/src/openvic-simulation/GameManager.hpp index 6be2938..3ac9de3 100644 --- a/src/openvic-simulation/GameManager.hpp +++ b/src/openvic-simulation/GameManager.hpp @@ -29,7 +29,8 @@ namespace OpenVic { GameAdvancementHook clock; time_t session_start; /* SS-54, as well as allowing time-tracking */ - Date today; + Bookmark const* PROPERTY(bookmark); + Date PROPERTY(today); state_updated_func_t state_updated; bool needs_update; @@ -52,9 +53,9 @@ namespace OpenVic { REF_GETTERS(ui_manager) REF_GETTERS(clock) - bool setup(); + bool reset(); + bool load_bookmark(Bookmark const* new_bookmark); - Date get_today() const; bool expand_building(Province::index_t province_index, std::string_view building_type_identifier); /* Hardcoded data for defining things for which parsing from files has diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index a14f0f0..1675543 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -49,7 +49,7 @@ bool CountryInstance::remove_reform(Reform const* reform_to_remove) { } void CountryInstance::apply_history_to_country(CountryHistoryMap const& history, Date date) { - auto entries = history.get_entries(date); + auto entries = history.get_entries_up_to(date); accepted_cultures.clear(); upper_house.clear(); diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index d36799f..f55ffaf 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -959,7 +959,9 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load wargoals!"); ret = false; } - if (!game_manager.get_history_manager().load_bookmark_file(parse_defines(lookup_file(bookmark_file)).get_file_node())) { + if (!game_manager.get_history_manager().get_bookmark_manager().load_bookmark_file( + parse_defines(lookup_file(bookmark_file)).get_file_node() + )) { Logger::error("Failed to load bookmarks!"); ret = false; } diff --git a/src/openvic-simulation/economy/Building.cpp b/src/openvic-simulation/economy/Building.cpp index bade4a5..c5707ea 100644 --- a/src/openvic-simulation/economy/Building.cpp +++ b/src/openvic-simulation/economy/Building.cpp @@ -1,10 +1,10 @@ #include "Building.hpp" -#include "openvic-simulation/map/Province.hpp" //imported here so the hpp doesn't get circular imports - using namespace OpenVic; using namespace OpenVic::NodeTools; +BuildingType::BuildingType(std::string_view new_identifier) : HasIdentifier { new_identifier } {} + Building::Building( std::string_view identifier, BuildingType const& type, ARGS ) : HasIdentifier { identifier }, type { type }, modifier { std::move(modifier) }, on_completion { on_completion }, @@ -16,135 +16,18 @@ Building::Building( colonial_range { colonial_range }, infrastructure { infrastructure }, spawn_railway_track { spawn_railway_track }, sail { sail }, steam { steam }, capital { capital }, port { port } {} -BuildingType const& Building::get_type() const { - return type; -} - -ModifierValue const& Building::get_modifier() const { - return modifier; -} - -std::string_view Building::get_on_completion() const { - return on_completion; -} - -fixed_point_t Building::get_completion_size() const { - return completion_size; -} - -Building::level_t Building::get_max_level() const { - return max_level; -} - -Good::good_map_t const& Building::get_goods_cost() const { - return goods_cost; -} - -fixed_point_t Building::get_cost() const { - return cost; -} - -Timespan Building::get_build_time() const { - return build_time; -} - -bool Building::has_visibility() const { - return visibility; -} - -bool Building::is_on_map() const { - return on_map; -} - -bool Building::is_default_enabled() const { - return default_enabled; -} - -ProductionType const* Building::get_production_type() const { - return production_type; -} - -bool Building::is_pop_built_factory() const { - return pop_build_factory; -} - -bool Building::is_strategic_factory() const { - return strategic_factory; -} - -bool Building::is_advanced_factory() const { - return advanced_factory; -} - -Building::level_t Building::get_fort_level() const { - return fort_level; -} - -uint64_t Building::get_naval_capacity() const { - return naval_capacity; -} - -std::vector const& Building::get_colonial_points() const { - return colonial_points; -} - -bool Building::is_in_province() const { - return in_province; -} - -bool Building::is_one_per_state() const { - return one_per_state; -} - -fixed_point_t Building::get_colonial_range() const { - return colonial_range; -} - -fixed_point_t Building::get_infrastructure() const { - return infrastructure; -} - -bool Building::spawned_railway_track() const { - return spawn_railway_track; -} - -BuildingType::BuildingType(std::string_view new_identifier) : HasIdentifier { new_identifier } {} - -BuildingInstance::BuildingInstance(Building const& building) - : HasIdentifier { building.get_identifier() }, building { building } {} - -Building const& BuildingInstance::get_building() const { - return building; -} +BuildingInstance::BuildingInstance(Building const& new_building, level_t new_level) + : HasIdentifier { building.get_identifier() }, building { new_building }, level { new_level }, + expansion_state { ExpansionState::CannotExpand } {} bool BuildingInstance::_can_expand() const { return level < building.get_max_level(); } -BuildingInstance::level_t BuildingInstance::get_current_level() const { - return level; -} - void BuildingInstance::set_level(BuildingInstance::level_t new_level) { level = new_level; } -ExpansionState BuildingInstance::get_expansion_state() const { - return expansion_state; -} - -Date BuildingInstance::get_start_date() const { - return start; -} - -Date BuildingInstance::get_end_date() const { - return end; -} - -float BuildingInstance::get_expansion_progress() const { - return expansion_progress; -} - bool BuildingInstance::expand() { if (expansion_state == ExpansionState::CanExpand) { expansion_state = ExpansionState::Preparing; @@ -160,11 +43,11 @@ bool BuildingInstance::expand() { void BuildingInstance::update_state(Date today) { switch (expansion_state) { case ExpansionState::Preparing: - start = today; - end = start + building.get_build_time(); + start_date = today; + end_date = start_date + building.get_build_time(); break; case ExpansionState::Expanding: - expansion_progress = static_cast(today - start) / static_cast(end - start); + expansion_progress = static_cast(today - start_date) / static_cast(end_date - start_date); break; default: expansion_state = _can_expand() ? ExpansionState::CanExpand : ExpansionState::CannotExpand; } @@ -175,7 +58,7 @@ void BuildingInstance::tick(Date today) { expansion_state = ExpansionState::Expanding; } if (expansion_state == ExpansionState::Expanding) { - if (end <= today) { + if (end_date <= today) { level++; expansion_state = ExpansionState::CannotExpand; } @@ -193,6 +76,10 @@ bool BuildingManager::add_building_type(std::string_view identifier) { } bool BuildingManager::add_building(std::string_view identifier, BuildingType const* type, ARGS) { + if (!building_types.is_locked()) { + Logger::error("Cannot add buildings until building types are locked!"); + return false; + } if (identifier.empty()) { Logger::error("Invalid building identifier - empty!"); return false; @@ -298,19 +185,3 @@ bool BuildingManager::load_buildings_file( return ret; } - -bool BuildingManager::generate_province_buildings(Province& province) const { - province.reset_buildings(); - if (!building_types.is_locked()) { - Logger::error("Cannot generate buildings until building types are locked!"); - return false; - } - bool ret = true; - if (!province.get_water()) { - for (Building const& building : buildings.get_items()) { - ret &= province.add_building({ building }); - } - } - province.lock_buildings(); - return ret; -} diff --git a/src/openvic-simulation/economy/Building.hpp b/src/openvic-simulation/economy/Building.hpp index c2eb1ef..ed1190b 100644 --- a/src/openvic-simulation/economy/Building.hpp +++ b/src/openvic-simulation/economy/Building.hpp @@ -18,7 +18,16 @@ namespace OpenVic { struct BuildingManager; - struct BuildingType; + + struct BuildingType : HasIdentifier { + friend struct BuildingManager; + + private: + BuildingType(std::string_view new_identifier); + + public: + BuildingType(BuildingType&&) = default; + }; /* REQUIREMENTS: * MAP-11, MAP-72, MAP-73 @@ -31,81 +40,43 @@ namespace OpenVic { using level_t = int16_t; private: - BuildingType const& type; - const ModifierValue modifier; - const std::string on_completion; // probably sound played on completion - const fixed_point_t completion_size; - const level_t max_level; - const Good::good_map_t goods_cost; - const fixed_point_t cost; - const Timespan build_time; // time - const bool visibility; - const bool on_map; // onmap - - const bool default_enabled; - ProductionType const* production_type; - const bool pop_build_factory; - const bool strategic_factory; - const bool advanced_factory; - - const level_t fort_level; // probably the step-per-level - - const uint64_t naval_capacity; - const std::vector colonial_points; - const bool in_province; // province - const bool one_per_state; - const fixed_point_t colonial_range; - - const fixed_point_t infrastructure; - const bool spawn_railway_track; - - const bool sail; // only in clipper shipyard - const bool steam; // only in steamer shipyard - const bool capital; // only in naval base - const bool port; // only in naval base + BuildingType const& PROPERTY(type); + ModifierValue PROPERTY(modifier); + std::string PROPERTY(on_completion); // probably sound played on completion + fixed_point_t PROPERTY(completion_size); + level_t PROPERTY(max_level); + Good::good_map_t PROPERTY(goods_cost); + fixed_point_t PROPERTY(cost); + Timespan PROPERTY(build_time); // time + bool PROPERTY(visibility); + bool PROPERTY(on_map); // onmap + + bool PROPERTY(default_enabled); + ProductionType const* PROPERTY(production_type); + bool PROPERTY(pop_build_factory); + bool PROPERTY(strategic_factory); + bool PROPERTY(advanced_factory); + + level_t PROPERTY(fort_level); // probably the step-per-level + + uint64_t PROPERTY(naval_capacity); + std::vector PROPERTY(colonial_points); + bool PROPERTY(in_province); // province + bool PROPERTY(one_per_state); + fixed_point_t PROPERTY(colonial_range); + + fixed_point_t PROPERTY(infrastructure); + bool PROPERTY(spawn_railway_track); + + bool PROPERTY(sail); // only in clipper shipyard + bool PROPERTY(steam); // only in steamer shipyard + bool PROPERTY(capital); // only in naval base + bool PROPERTY(port); // only in naval base Building(std::string_view identifier, BuildingType const& type, ARGS); public: Building(Building&&) = default; - - BuildingType const& get_type() const; - ModifierValue const& get_modifier() const; - std::string_view get_on_completion() const; - fixed_point_t get_completion_size() const; - level_t get_max_level() const; - Good::good_map_t const& get_goods_cost() const; - fixed_point_t get_cost() const; - Timespan get_build_time() const; - bool has_visibility() const; - bool is_on_map() const; - - bool is_default_enabled() const; - ProductionType const* get_production_type() const; - bool is_pop_built_factory() const; - bool is_strategic_factory() const; - bool is_advanced_factory() const; - - level_t get_fort_level() const; - - uint64_t get_naval_capacity() const; - std::vector const& get_colonial_points() const; - bool is_in_province() const; - bool is_one_per_state() const; - fixed_point_t get_colonial_range() const; - - fixed_point_t get_infrastructure() const; - bool spawned_railway_track() const; - }; - - struct BuildingType : HasIdentifier { - friend struct BuildingManager; - - private: - BuildingType(std::string_view new_identifier); - - public: - BuildingType(BuildingType&&) = default; }; enum class ExpansionState { CannotExpand, CanExpand, Preparing, Expanding }; @@ -115,36 +86,27 @@ namespace OpenVic { using level_t = Building::level_t; private: - Building const& building; + Building const& PROPERTY(building); - level_t level = 0; - ExpansionState expansion_state = ExpansionState::CannotExpand; - Date start, end; - float expansion_progress; + level_t PROPERTY(level); + ExpansionState PROPERTY(expansion_state); + Date PROPERTY(start_date) + Date PROPERTY(end_date); + float PROPERTY(expansion_progress); bool _can_expand() const; public: - BuildingInstance(Building const& building); + BuildingInstance(Building const& new_building, level_t new_level = 0); BuildingInstance(BuildingInstance&&) = default; - Building const& get_building() const; - - level_t get_current_level() const; void set_level(level_t new_level); - ExpansionState get_expansion_state() const; - Date get_start_date() const; - Date get_end_date() const; - float get_expansion_progress() const; - bool expand(); void update_state(Date today); void tick(Date today); }; - struct Province; - struct BuildingManager { using level_t = Building::level_t; // this is getting ridiculous @@ -165,7 +127,5 @@ namespace OpenVic { GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager& modifier_manager, ast::NodeCPtr root ); - - bool generate_province_buildings(Province& province) const; }; } diff --git a/src/openvic-simulation/history/HistoryManager.hpp b/src/openvic-simulation/history/HistoryManager.hpp index ec6d1c5..a7fc668 100644 --- a/src/openvic-simulation/history/HistoryManager.hpp +++ b/src/openvic-simulation/history/HistoryManager.hpp @@ -19,9 +19,5 @@ namespace OpenVic { REF_GETTERS(country_manager) REF_GETTERS(province_manager) REF_GETTERS(diplomacy_manager) - - inline bool load_bookmark_file(ast::NodeCPtr root) { - return bookmark_manager.load_bookmark_file(root); - } }; } diff --git a/src/openvic-simulation/history/HistoryMap.hpp b/src/openvic-simulation/history/HistoryMap.hpp index 64d886d..07f54f0 100644 --- a/src/openvic-simulation/history/HistoryMap.hpp +++ b/src/openvic-simulation/history/HistoryMap.hpp @@ -30,6 +30,11 @@ namespace OpenVic { std::map> PROPERTY(entries); bool _try_load_history_entry(GameManager const& game_manager, Args... args, Date date, ast::NodeCPtr root) { + const Date end_date = _get_end_date(game_manager); + if (date > end_date) { + Logger::error("History entry ", date, " defined after end date ", end_date); + return false; + } typename decltype(entries)::iterator it = entries.find(date); if (it == entries.end()) { const std::pair result = entries.emplace(date, _make_entry(date)); @@ -64,14 +69,12 @@ namespace OpenVic { bool is_date = false; const Date sub_date { Date::from_string(key, &is_date, true) }; if (is_date) { - if (sub_date <= date) { + if (sub_date < date) { Logger::error("History entry ", sub_date, " defined before parent entry date ", date); return false; } - const Date end_date = _get_end_date(game_manager); - if (sub_date > end_date) { - Logger::error("History entry ", sub_date, " defined after end date ", end_date); - return false; + if (sub_date == date) { + Logger::warning("History entry ", sub_date, " defined with same date as parent entry"); } if (_try_load_history_entry(game_manager, args..., sub_date, value)) { return true; @@ -94,7 +97,7 @@ namespace OpenVic { return nullptr; } /* Returns history entries up to date as an ordered list of entries. */ - std::vector get_entries(Date end) const { + std::vector get_entries_up_to(Date end) const { std::vector ret; for (typename decltype(entries)::value_type const& entry : entries) { if (entry.first <= end) { diff --git a/src/openvic-simulation/history/ProvinceHistory.cpp b/src/openvic-simulation/history/ProvinceHistory.cpp index 141d256..379c7d1 100644 --- a/src/openvic-simulation/history/ProvinceHistory.cpp +++ b/src/openvic-simulation/history/ProvinceHistory.cpp @@ -36,7 +36,7 @@ bool ProvinceHistoryMap::_load_history_entry( Building const* building = building_manager.get_building_by_identifier(key); if (building != nullptr) { return expect_uint([&entry, building](Building::level_t level) -> bool { - entry.buildings[building] = level; + entry.province_buildings[building] = level; return true; })(value); } @@ -93,7 +93,7 @@ bool ProvinceHistoryMap::_load_history_entry( ), "upgrade", ZERO_OR_ONE, success_callback // doesn't appear to have an effect )(node); - entry.buildings[building] = level; + entry.state_buildings[building] = level; return ret; } )(root); diff --git a/src/openvic-simulation/history/ProvinceHistory.hpp b/src/openvic-simulation/history/ProvinceHistory.hpp index 313f3a4..d0136bb 100644 --- a/src/openvic-simulation/history/ProvinceHistory.hpp +++ b/src/openvic-simulation/history/ProvinceHistory.hpp @@ -18,8 +18,6 @@ namespace OpenVic { struct ProvinceHistoryEntry : HistoryEntry { friend struct ProvinceHistoryMap; - using building_level_map_t = std::map; - private: Province const& PROPERTY(province); @@ -32,7 +30,8 @@ namespace OpenVic { std::optional PROPERTY(rgo); std::optional PROPERTY(life_rating); std::optional PROPERTY(terrain_type); - building_level_map_t PROPERTY(buildings); + std::map PROPERTY(province_buildings); + std::map PROPERTY(state_buildings); fixed_point_map_t PROPERTY(party_loyalties); ProvinceHistoryEntry(Province const& new_province, Date new_date); diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 261a13e..dad07a6 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -4,6 +4,7 @@ #include #include "openvic-simulation/economy/Good.hpp" +#include "openvic-simulation/history/ProvinceHistory.hpp" #include "openvic-simulation/utility/BMP.hpp" #include "openvic-simulation/utility/Logger.hpp" @@ -297,11 +298,25 @@ Pop::pop_size_t Map::get_total_map_population() const { return total_map_population; } -bool Map::setup(BuildingManager const& building_manager, PopManager const& pop_manager) { +bool Map::reset(BuildingManager const& building_manager) { bool ret = true; for (Province& province : provinces.get_items()) { - province.clear_pops(); - ret &= building_manager.generate_province_buildings(province); + ret &= province.reset(building_manager); + } + return ret; +} + +bool Map::apply_history_to_provinces(ProvinceHistoryManager const& history_manager, Date date) { + bool ret = true; + for (Province& province : provinces.get_items()) { + if (!province.get_water()) { + ProvinceHistoryMap const* history_map = history_manager.get_province_history(&province); + if (history_map != nullptr) { + for (ProvinceHistoryEntry const* entry : history_map->get_entries_up_to(date)) { + province.apply_history_to_province(entry); + } + } + } } return ret; } @@ -562,7 +577,7 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain for (size_t idx = 0; idx < province_checklist.size(); ++idx) { Province* province = provinces.get_item_by_index(idx); const fixed_point_map_const_iterator_t largest = get_largest_item(terrain_type_pixels_list[idx]); - province->_set_terrain_type(largest != terrain_type_pixels_list[idx].end() ? largest->first : nullptr); + province->default_terrain_type = largest != terrain_type_pixels_list[idx].end() ? largest->first : nullptr; province->on_map = province_checklist[idx]; if (!province->on_map) { if (detailed_errors) { diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index db67390..189713c 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -36,6 +36,7 @@ namespace OpenVic { }; struct GoodManager; + struct ProvinceHistoryManager; /* REQUIREMENTS: * MAP-4 @@ -109,7 +110,8 @@ namespace OpenVic { * that is the maximum allowed number of provinces plus one for the index-zero "null province". */ bool generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) const; - bool setup(BuildingManager const& building_manager, PopManager const& pop_manager); + bool reset(BuildingManager const& building_manager); + bool apply_history_to_provinces(ProvinceHistoryManager const& history_manager, Date date); void update_highest_province_population(); Pop::pop_size_t get_highest_province_population() const; diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index 1b47dea..97e5192 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -8,56 +8,16 @@ using namespace OpenVic::NodeTools; Province::Province( std::string_view new_identifier, colour_t new_colour, index_t new_index ) : HasIdentifierAndColour { new_identifier, new_colour, true, false }, index { new_index }, - buildings { "buildings", false } { + 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 } { assert(index != NULL_INDEX); } -Province::index_t Province::get_index() const { - return index; -} - -Region const* Province::get_region() const { - return region; -} - -bool Province::get_on_map() const { - return on_map; -} - -bool Province::get_has_region() const { - return has_region; -} - -bool Province::get_water() const { - return water; -} - -TerrainType const* Province::get_terrain_type() const { - return terrain_type; -} - -Province::life_rating_t Province::get_life_rating() const { - return life_rating; -} - -Province::colony_status_t Province::get_colony_status() const { - return colony_status; -} - -Country const* Province::get_owner() const { - return owner; -} - -Country const* Province::get_controller() const { - return controller; -} - -std::vector const& Province::get_cores() const { - return cores; -} - -bool Province::is_slave() const { - return slave; +std::string Province::to_string() const { + std::stringstream stream; + stream << "(#" << std::to_string(index) << ", " << get_identifier() << ", 0x" << colour_to_hex_string() << ")"; + return stream.str(); } bool Province::load_positions(BuildingManager const& building_manager, ast::NodeCPtr root) { @@ -89,14 +49,6 @@ bool Province::load_positions(BuildingManager const& building_manager, ast::Node )(root); } -bool Province::add_building(BuildingInstance&& building_instance) { - return buildings.add_item(std::move(building_instance)); -} - -void Province::reset_buildings() { - buildings.reset(); -} - bool Province::expand_building(std::string_view building_type_identifier) { BuildingInstance* building = buildings.get_item_by_identifier(building_type_identifier); if (building == nullptr) { @@ -105,16 +57,6 @@ bool Province::expand_building(std::string_view building_type_identifier) { return building->expand(); } -Good const* Province::get_rgo() const { - return rgo; -} - -std::string Province::to_string() const { - std::stringstream stream; - stream << "(#" << std::to_string(index) << ", " << get_identifier() << ", 0x" << colour_to_hex_string() << ")"; - return stream.str(); -} - bool Province::load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root) { return expect_dictionary_reserve_length(pops, [this, &pop_manager](std::string_view pop_type_identifier, ast::NodeCPtr pop_node) -> bool { @@ -133,22 +75,10 @@ bool Province::add_pop(Pop&& pop) { } } -void Province::clear_pops() { - pops.clear(); -} - size_t Province::get_pop_count() const { return pops.size(); } -std::vector const& Province::get_pops() const { - return pops; -} - -Pop::pop_size_t Province::get_total_population() const { - return total_population; -} - /* REQUIREMENTS: * MAP-65, MAP-68, MAP-70, MAP-234 */ @@ -185,14 +115,6 @@ Province::adjacency_t::adjacency_t(Province const* province, distance_t distance assert(province != nullptr); } -Province::distance_t Province::adjacency_t::get_distance() const { - return distance; -} - -Province::flags_t Province::adjacency_t::get_flags() const { - return flags; -} - bool Province::is_adjacent_to(Province const* province) { for (adjacency_t adj : adjacencies) { if (adj.province == province) { @@ -207,7 +129,6 @@ bool Province::add_adjacency(Province const* province, distance_t distance, flag Logger::error("Tried to create null adjacency province for province ", get_identifier(), "!"); return false; } - if (is_adjacent_to(province)) { return false; } @@ -215,46 +136,84 @@ bool Province::add_adjacency(Province const* province, distance_t distance, flag return true; } -std::vector const& Province::get_adjacencies() const { - return adjacencies; -} +bool Province::reset(BuildingManager const& building_manager) { + terrain_type = default_terrain_type; + life_rating = 0; + colony_status = colony_status_t::STATE; + owner = nullptr; + controller = nullptr; + cores.clear(); + slave = false; + rgo = nullptr; -void Province::_set_terrain_type(TerrainType const* type) { - terrain_type = type; -} + buildings.reset(); + bool ret = true; + if (!get_water()) { + if (building_manager.building_types_are_locked() && building_manager.buildings_are_locked()) { + for (Building const& building : building_manager.get_buildings()) { + if (building.get_in_province()) { + ret &= buildings.add_item({ building }); + } + } + } else { + Logger::error("Cannot generate buildings until building types are locked!"); + ret = false; + } + } + lock_buildings(); + + pops.clear(); + update_pops(); -void Province::apply_history_to_province(ProvinceHistoryMap const& history, Date date) { - auto entries = history.get_entries(date); - - reset_buildings(); + return ret; +} - for (ProvinceHistoryEntry const* entry : entries) { - if (entry->get_life_rating()) life_rating = *entry->get_life_rating(); - if (entry->get_colonial()) colony_status = *entry->get_colonial(); - if (entry->get_rgo()) rgo = *entry->get_rgo(); - if (entry->get_terrain_type()) terrain_type = *entry->get_terrain_type(); - if (entry->get_owner()) owner = *entry->get_owner(); - if (entry->get_controller()) controller = *entry->get_controller(); - if (entry->get_slave()) slave = *entry->get_slave(); - for (const auto& core : entry->get_remove_cores()) { - const auto existing_core = std::find(cores.begin(), cores.end(), core); - if (existing_core != cores.end()) cores.erase(existing_core); +bool Province::apply_history_to_province(ProvinceHistoryEntry const* entry) { + if (entry == nullptr) { + Logger::error("Trying to apply null province history to ", get_identifier()); + return false; + } + if (entry->get_life_rating()) life_rating = *entry->get_life_rating(); + if (entry->get_colonial()) colony_status = *entry->get_colonial(); + if (entry->get_rgo()) rgo = *entry->get_rgo(); + if (entry->get_terrain_type()) terrain_type = *entry->get_terrain_type(); + if (entry->get_owner()) owner = *entry->get_owner(); + if (entry->get_controller()) controller = *entry->get_controller(); + if (entry->get_slave()) slave = *entry->get_slave(); + for (Country const* core : entry->get_remove_cores()) { + const typename decltype(cores)::iterator existing_core = std::find(cores.begin(), cores.end(), core); + if (existing_core != cores.end()) { + cores.erase(existing_core); + } else { + Logger::warning( + "Trying to remove non-existent core ", core->get_identifier(), " from province ", get_identifier() + ); } - for (const auto& core : entry->get_add_cores()) { - const auto existing_core = std::find(cores.begin(), cores.end(), core); - if (existing_core == cores.end()) cores.push_back(core); + } + for (Country const* core : entry->get_add_cores()) { + const typename decltype(cores)::iterator existing_core = std::find(cores.begin(), cores.end(), core); + if (existing_core == cores.end()) { + cores.push_back(core); + } else { + Logger::warning( + "Trying to add already-existing core ", core->get_identifier(), " to province ", get_identifier() + ); } - // TODO: rework province buildings - for (const auto& building : entry->get_buildings()) { - BuildingInstance* existing_entry = buildings.get_item_by_identifier(building.first->get_identifier()); - if (existing_entry != nullptr) { - existing_entry->set_level(building.second); - } else { - BuildingInstance instance = { *building.first }; - instance.set_level(building.second); - add_building(std::move(instance)); - } + } + bool ret = true; + for (auto const& [building, level] : entry->get_province_buildings()) { + BuildingInstance* existing_entry = buildings.get_item_by_identifier(building->get_identifier()); + if (existing_entry != nullptr) { + existing_entry->set_level(level); + } else { + Logger::error( + "Trying to set level of non-existent province building ", building->get_identifier(), " to ", level, + " in province ", get_identifier() + ); + ret = false; } - // TODO: party loyalties for each POP when implemented on POP side } + // TODO: load state buildings + // TODO: party loyalties for each POP when implemented on POP side# + return ret; } diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index 21a974f..0b7a5d9 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -13,7 +13,7 @@ namespace OpenVic { struct Good; struct TerrainType; struct TerrainTypeMapping; - struct ProvinceHistoryMap; + struct ProvinceHistoryEntry; /* REQUIREMENTS: * MAP-5, MAP-7, MAP-8, MAP-43, MAP-47 @@ -34,14 +34,10 @@ namespace OpenVic { private: Province const* const province; - const distance_t distance; - flags_t flags; + const distance_t PROPERTY(distance); + flags_t PROPERTY(flags); adjacency_t(Province const* province, distance_t distance, flags_t flags); - - public: - distance_t get_distance() const; - flags_t get_flags() const; }; struct province_positions_t { @@ -64,62 +60,50 @@ namespace OpenVic { static constexpr index_t NULL_INDEX = 0, MAX_INDEX = std::numeric_limits::max(); private: - const index_t index; - Region const* region = nullptr; - bool on_map = false, has_region = false, water = false; - life_rating_t life_rating = 0; - colony_status_t colony_status = colony_status_t::STATE; - IdentifierRegistry buildings; + const index_t PROPERTY(index); + Region* PROPERTY(region); + bool PROPERTY(on_map); + bool PROPERTY(has_region); + bool PROPERTY(water); + /* Terrain type calculated from terrain image */ + TerrainType const* PROPERTY(default_terrain_type); + + std::vector PROPERTY(adjacencies); + province_positions_t positions; + + TerrainType const* PROPERTY(terrain_type); + life_rating_t PROPERTY(life_rating); + colony_status_t PROPERTY(colony_status); + Country const* PROPERTY(owner); + Country const* PROPERTY(controller); + std::vector PROPERTY(cores); + bool PROPERTY(slave); // TODO - change this into a factory-like structure - Good const* rgo = nullptr; + Good const* PROPERTY(rgo); + IdentifierRegistry buildings; - std::vector pops; - Pop::pop_size_t total_population; + std::vector PROPERTY(pops); + Pop::pop_size_t PROPERTY(total_population); fixed_point_map_t PROPERTY(pop_type_distribution); fixed_point_map_t PROPERTY(ideology_distribution); fixed_point_map_t PROPERTY(culture_distribution); fixed_point_map_t PROPERTY(religion_distribution); - std::vector adjacencies; - province_positions_t positions; - - TerrainType const* terrain_type = nullptr; - - void _set_terrain_type(TerrainType const* type); - - Country const* owner = nullptr; - Country const* controller = nullptr; - std::vector cores; - bool slave = false; - Province(std::string_view new_identifier, colour_t new_colour, index_t new_index); public: Province(Province&&) = default; - index_t get_index() const; - Region const* get_region() const; - bool get_on_map() const; - bool get_has_region() const; - bool get_water() const; - TerrainType const* get_terrain_type() const; - life_rating_t get_life_rating() const; - colony_status_t get_colony_status() const; + std::string to_string() const; + bool load_positions(BuildingManager const& building_manager, ast::NodeCPtr root); - bool add_building(BuildingInstance&& building_instance); IDENTIFIER_REGISTRY_ACCESSORS(building) - void reset_buildings(); bool expand_building(std::string_view building_type_identifier); - Good const* get_rgo() const; - std::string to_string() const; bool load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root); bool add_pop(Pop&& pop); - void clear_pops(); size_t get_pop_count() const; - std::vector const& get_pops() const; - Pop::pop_size_t get_total_population() const; void update_pops(); void update_state(Date today); @@ -127,13 +111,8 @@ namespace OpenVic { bool is_adjacent_to(Province const* province); bool add_adjacency(Province const* province, distance_t distance, flags_t flags); - std::vector const& get_adjacencies() const; - - Country const* get_owner() const; - Country const* get_controller() const; - std::vector const& get_cores() const; - bool is_slave() const; - void apply_history_to_province(ProvinceHistoryMap const& history, Date date); + bool reset(BuildingManager const& building_manager); + bool apply_history_to_province(ProvinceHistoryEntry const* entry); }; } diff --git a/src/openvic-simulation/misc/Define.cpp b/src/openvic-simulation/misc/Define.cpp index c866b5d..cfd96a6 100644 --- a/src/openvic-simulation/misc/Define.cpp +++ b/src/openvic-simulation/misc/Define.cpp @@ -37,27 +37,30 @@ bool DefineManager::add_define(std::string_view name, std::string&& value, Defin } Date DefineManager::get_start_date() const { - return *start_date; + return start_date ? *start_date : Date {}; } Date DefineManager::get_end_date() const { - return *end_date; + return end_date ? *end_date : Date {}; } -bool DefineManager::add_date_define(std::string_view name, Date date) { - if (name != "start_date" && name != "end_date") { +bool DefineManager::in_game_period(Date date) const { + if (start_date && end_date) { + return date.in_range(*start_date, *end_date); + } else { return false; } +} - bool ret = defines.add_item({ name, date.to_string(), Define::Type::None }); - +bool DefineManager::add_date_define(std::string_view name, Date date) { if (name == "start_date") { - start_date.reset(new Date(date)); + start_date = date; } else if (name == "end_date") { - end_date.reset(new Date(date)); + end_date = date; + } else { + return false; } - - return ret; + return defines.add_item({ name, date.to_string(), Define::Type::None }); } bool DefineManager::load_defines_file(ast::NodeCPtr root) { @@ -103,8 +106,6 @@ bool DefineManager::load_defines_file(ast::NodeCPtr root) { return ret; })(value); } else if (key == "start_date" || key == "end_date") { - using namespace std::placeholders; - return expect_identifier_or_string(expect_date_str([this, &key](Date date) -> bool { return add_date_define(key, date); }))(value); diff --git a/src/openvic-simulation/misc/Define.hpp b/src/openvic-simulation/misc/Define.hpp index be71f9d..46e4836 100644 --- a/src/openvic-simulation/misc/Define.hpp +++ b/src/openvic-simulation/misc/Define.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include "openvic-simulation/types/IdentifierRegistry.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" @@ -32,8 +32,8 @@ namespace OpenVic { private: IdentifierRegistry defines; - std::unique_ptr start_date = nullptr; - std::unique_ptr end_date = nullptr; + std::optional start_date; + std::optional end_date; public: DefineManager(); @@ -44,6 +44,7 @@ namespace OpenVic { Date get_start_date() const; Date get_end_date() const; + bool in_game_period(Date date) const; bool load_defines_file(ast::NodeCPtr root); }; diff --git a/src/openvic-simulation/types/Date.cpp b/src/openvic-simulation/types/Date.cpp index c5eac41..e695e45 100644 --- a/src/openvic-simulation/types/Date.cpp +++ b/src/openvic-simulation/types/Date.cpp @@ -204,6 +204,10 @@ Date Date::operator++(int) { return old; } +bool Date::in_range(Date start, Date end) const { + return start <= *this && *this <= end; +} + 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 b6e693c..5aed49b 100644 --- a/src/openvic-simulation/types/Date.hpp +++ b/src/openvic-simulation/types/Date.hpp @@ -91,6 +91,8 @@ namespace OpenVic { Date& operator++(); Date operator++(int); + bool in_range(Date start, Date end) 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 3794dd6..6c0dd3b 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -333,6 +333,9 @@ namespace OpenVic { size_t get_##singular##_count() const { \ return plural.size(); \ } \ + bool plural##_empty() const { \ + return plural.empty(); \ + } \ std::vector const& get_##plural() const { \ return plural.get_items(); \ } \ -- cgit v1.2.3-56-ga3b1