aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/openvic-simulation/GameManager.cpp25
-rw-r--r--src/openvic-simulation/GameManager.hpp7
-rw-r--r--src/openvic-simulation/country/CountryInstance.cpp2
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp4
-rw-r--r--src/openvic-simulation/economy/Building.cpp155
-rw-r--r--src/openvic-simulation/economy/Building.hpp138
-rw-r--r--src/openvic-simulation/history/HistoryManager.hpp4
-rw-r--r--src/openvic-simulation/history/HistoryMap.hpp15
-rw-r--r--src/openvic-simulation/history/ProvinceHistory.cpp4
-rw-r--r--src/openvic-simulation/history/ProvinceHistory.hpp5
-rw-r--r--src/openvic-simulation/map/Map.cpp23
-rw-r--r--src/openvic-simulation/map/Map.hpp4
-rw-r--r--src/openvic-simulation/map/Province.cpp201
-rw-r--r--src/openvic-simulation/map/Province.hpp79
-rw-r--r--src/openvic-simulation/misc/Define.cpp25
-rw-r--r--src/openvic-simulation/misc/Define.hpp7
-rw-r--r--src/openvic-simulation/types/Date.cpp4
-rw-r--r--src/openvic-simulation/types/Date.hpp2
-rw-r--r--src/openvic-simulation/types/IdentifierRegistry.hpp3
19 files changed, 259 insertions, 448 deletions
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<fixed_point_t> 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<double>(today - start) / static_cast<double>(end - start);
+ expansion_progress = static_cast<double>(today - start_date) / static_cast<double>(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<fixed_point_t> 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<fixed_point_t> 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<fixed_point_t> 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<Date, std::unique_ptr<entry_type>> 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<typename decltype(entries)::iterator, bool> 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<entry_type const*> get_entries(Date end) const {
+ std::vector<entry_type const*> get_entries_up_to(Date end) const {
std::vector<entry_type const*> 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<Building::level_t>([&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<Building const*, Building::level_t>;
-
private:
Province const& PROPERTY(province);
@@ -32,7 +30,8 @@ namespace OpenVic {
std::optional<Good const*> PROPERTY(rgo);
std::optional<Province::life_rating_t> PROPERTY(life_rating);
std::optional<TerrainType const*> PROPERTY(terrain_type);
- building_level_map_t PROPERTY(buildings);
+ std::map<Building const*, Building::level_t> PROPERTY(province_buildings);
+ std::map<Building const*, Building::level_t> PROPERTY(state_buildings);
fixed_point_map_t<Ideology const*> 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 <unordered_set>
#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<TerrainType const*> 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<Country const*> 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<Pop> 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<Province::adjacency_t> 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<index_t>::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<BuildingInstance> 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<adjacency_t> 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<Country const*> PROPERTY(cores);
+ bool PROPERTY(slave);
// TODO - change this into a factory-like structure
- Good const* rgo = nullptr;
+ Good const* PROPERTY(rgo);
+ IdentifierRegistry<BuildingInstance> buildings;
- std::vector<Pop> pops;
- Pop::pop_size_t total_population;
+ std::vector<Pop> PROPERTY(pops);
+ Pop::pop_size_t PROPERTY(total_population);
fixed_point_map_t<PopType const*> PROPERTY(pop_type_distribution);
fixed_point_map_t<Ideology const*> PROPERTY(ideology_distribution);
fixed_point_map_t<Culture const*> PROPERTY(culture_distribution);
fixed_point_map_t<Religion const*> PROPERTY(religion_distribution);
- std::vector<adjacency_t> 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<Country const*> 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<Pop> 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<adjacency_t> const& get_adjacencies() const;
-
- Country const* get_owner() const;
- Country const* get_controller() const;
- std::vector<Country const*> 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 <concepts>
-#include <memory>
+#include <optional>
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
@@ -32,8 +32,8 @@ namespace OpenVic {
private:
IdentifierRegistry<Define> defines;
- std::unique_ptr<Date> start_date = nullptr;
- std::unique_ptr<Date> end_date = nullptr;
+ std::optional<Date> start_date;
+ std::optional<Date> 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<decltype(plural)::storage_type> const& get_##plural() const { \
return plural.get_items(); \
} \