aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation')
-rw-r--r--src/openvic-simulation/Modifier.cpp21
-rw-r--r--src/openvic-simulation/Modifier.hpp5
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp38
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.hpp8
-rw-r--r--src/openvic-simulation/dataloader/NodeTools.cpp31
-rw-r--r--src/openvic-simulation/dataloader/NodeTools.hpp42
-rw-r--r--src/openvic-simulation/economy/Good.cpp2
-rw-r--r--src/openvic-simulation/economy/Good.hpp2
-rw-r--r--src/openvic-simulation/map/Map.cpp100
-rw-r--r--src/openvic-simulation/map/Map.hpp17
-rw-r--r--src/openvic-simulation/map/Province.cpp6
-rw-r--r--src/openvic-simulation/map/Province.hpp2
-rw-r--r--src/openvic-simulation/pop/Culture.cpp9
-rw-r--r--src/openvic-simulation/pop/Pop.cpp4
-rw-r--r--src/openvic-simulation/types/IdentifierRegistry.hpp58
-rw-r--r--src/openvic-simulation/types/Vector.hpp1
16 files changed, 220 insertions, 126 deletions
diff --git a/src/openvic-simulation/Modifier.cpp b/src/openvic-simulation/Modifier.cpp
index d2e21c6..46bba48 100644
--- a/src/openvic-simulation/Modifier.cpp
+++ b/src/openvic-simulation/Modifier.cpp
@@ -1,6 +1,7 @@
#include "Modifier.hpp"
using namespace OpenVic;
+using namespace OpenVic::NodeTools;
ModifierEffect::ModifierEffect(const std::string_view new_identifier, bool new_positive_good)
: HasIdentifier { new_identifier }, positive_good { new_positive_good } {}
@@ -114,3 +115,23 @@ bool ModifierManager::add_modifier(const std::string_view identifier, ModifierVa
}
return modifiers.add_item({ identifier, std::move(values), icon });
}
+
+node_callback_t ModifierManager::expect_modifier_value(callback_t<ModifierValue&&> callback) const {
+ return [this, callback](ast::NodeCPtr root) -> bool {
+ ModifierValue modifier;
+ bool ret = expect_dictionary(
+ [this, &modifier](std::string_view key, ast::NodeCPtr value) -> bool {
+ ModifierEffect const* effect = get_modifier_effect_by_identifier(key);
+ if (effect != nullptr) {
+ return expect_fixed_point(
+ assign_variable_callback(modifier.values[effect])
+ )(value);
+ }
+ Logger::error("Invalid modifier effect: ", key);
+ return false;
+ }
+ )(root);
+ ret &= callback(std::move(modifier));
+ return ret;
+ };
+}
diff --git a/src/openvic-simulation/Modifier.hpp b/src/openvic-simulation/Modifier.hpp
index eb63788..acdadfe 100644
--- a/src/openvic-simulation/Modifier.hpp
+++ b/src/openvic-simulation/Modifier.hpp
@@ -25,6 +25,8 @@ namespace OpenVic {
};
struct ModifierValue {
+ friend struct ModifierManager;
+
using effect_map_t = std::map<ModifierEffect const*, fixed_point_t>;
private:
effect_map_t values;
@@ -57,6 +59,7 @@ namespace OpenVic {
using icon_t = uint8_t;
private:
+ /* A modifier can have no icon (zero). */
const icon_t icon;
Modifier(const std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon);
@@ -92,5 +95,7 @@ namespace OpenVic {
bool add_modifier(const std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon);
IDENTIFIER_REGISTRY_ACCESSORS(Modifier, modifier)
+
+ NodeTools::node_callback_t expect_modifier_value(NodeTools::callback_t<ModifierValue&&> callback) const;
};
}
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp
index e85f499..a30983b 100644
--- a/src/openvic-simulation/dataloader/Dataloader.cpp
+++ b/src/openvic-simulation/dataloader/Dataloader.cpp
@@ -50,7 +50,6 @@ fs::path Dataloader::lookup_file(fs::path const& path) const {
}
static bool contains_file_with_name(Dataloader::path_vector_t const& paths, fs::path const& name) {
-
for (fs::path const& path : paths) {
if (path.filename() == name) return true;
}
@@ -76,8 +75,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, fs::path const& extension, std::function<bool(fs::path const&)> callback) const {
-
+bool Dataloader::apply_to_files_in_dir(fs::path const& path, fs::path const& extension, callback_t<fs::path const&> callback) const {
bool ret = true;
for (fs::path const& file : lookup_files_in_dir(path, extension)) {
ret &= callback(file);
@@ -140,6 +138,12 @@ static csv::Windows1252Parser _parse_csv(fs::path const& path) {
return _run_ovdl_parser<csv::Windows1252Parser, &_csv_parse>(path);
}
+static callback_t<fs::path const&> _parse_defines_callback(node_callback_t callback) {
+ return [callback](fs::path const& path) -> bool {
+ return callback(_parse_defines(path).get_file_node());
+ };
+}
+
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, ".txt",
[&pop_manager](fs::path const& file) -> bool {
@@ -153,7 +157,9 @@ bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_ty
return ret;
}
-bool Dataloader::_load_map_dir(Map& map, fs::path const& map_directory) const {
+bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_directory) const {
+ Map& map = game_manager.map;
+
static const fs::path defaults_filename = "default.map";
static const std::string default_definitions = "definition.csv";
static const std::string default_provinces = "provinces.bmp";
@@ -226,6 +232,11 @@ bool Dataloader::_load_map_dir(Map& map, fs::path const& map_directory) const {
ret = false;
}
+ if (!map.load_province_positions(game_manager.building_manager, _parse_defines(lookup_file(map_directory / positions)).get_file_node())) {
+ Logger::error("Failed to load province positions file!");
+ ret = false;
+ }
+
if (!map.load_region_file(_parse_defines(lookup_file(map_directory / region)).get_file_node())) {
Logger::error("Failed to load region file!");
ret = false;
@@ -241,7 +252,7 @@ bool Dataloader::_load_map_dir(Map& map, fs::path const& map_directory) const {
}
bool Dataloader::load_defines(GameManager& game_manager) const {
- static const fs::path good_file = "common/goods.txt";
+ static const fs::path goods_file = "common/goods.txt";
static const fs::path pop_type_directory = "poptypes";
static const fs::path graphical_culture_type_file = "common/graphicalculturetype.txt";
static const fs::path culture_file = "common/cultures.txt";
@@ -250,7 +261,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const {
bool ret = true;
- if (!game_manager.good_manager.load_good_file(_parse_defines(lookup_file(good_file)).get_file_node())) {
+ if (!game_manager.good_manager.load_goods_file(_parse_defines(lookup_file(goods_file)).get_file_node())) {
Logger::error("Failed to load goods!");
ret = false;
}
@@ -270,7 +281,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const {
Logger::error("Failed to load religions!");
ret = false;
}
- if (!_load_map_dir(game_manager.map, map_directory)) {
+ if (!_load_map_dir(game_manager, map_directory)) {
Logger::error("Failed to load map!");
ret = false;
}
@@ -281,16 +292,11 @@ 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, ".txt",
[&game_manager](fs::path const& file) -> bool {
- return expect_dictionary(
- [&game_manager](std::string_view province_key, ast::NodeCPtr province_node) -> bool {
- Province* province = game_manager.map.get_province_by_identifier(province_key);
- if (province == nullptr) {
- Logger::error("Invalid province id: ", province_key);
- return false;
- }
- return province->load_pop_list(game_manager.pop_manager, province_node);
+ return _parse_defines_callback(game_manager.map.expect_province_dictionary(
+ [&game_manager](Province& province, ast::NodeCPtr value) -> bool {
+ return province.load_pop_list(game_manager.pop_manager, value);
}
- )(_parse_defines(file).get_file_node());
+ ))(file);
}
);
}
diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp
index 2b358b6..6741361 100644
--- a/src/openvic-simulation/dataloader/Dataloader.hpp
+++ b/src/openvic-simulation/dataloader/Dataloader.hpp
@@ -4,6 +4,8 @@
#include <functional>
#include <vector>
+#include "openvic-simulation/dataloader/NodeTools.hpp"
+
namespace OpenVic {
namespace fs = std::filesystem;
@@ -19,7 +21,7 @@ namespace OpenVic {
path_vector_t roots;
bool _load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const;
- bool _load_map_dir(Map& map, fs::path const& map_directory) const;
+ bool _load_map_dir(GameManager& game_manager, fs::path const& map_directory) const;
public:
Dataloader() = default;
@@ -33,7 +35,7 @@ namespace OpenVic {
fs::path lookup_file(fs::path const& path) 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<bool(fs::path const&)> callback) const;
+ NodeTools::callback_t<fs::path const&> callback) const;
bool load_defines(GameManager& game_manager) const;
bool load_pop_history(GameManager& game_manager, fs::path const& path) const;
@@ -46,7 +48,7 @@ namespace OpenVic {
};
/* Args: key, locale, localisation */
- using localisation_callback_t = std::function<bool(std::string_view, locale_t, std::string_view)>;
+ using localisation_callback_t = NodeTools::callback_t<std::string_view, locale_t, std::string_view>;
bool load_localisation_files(localisation_callback_t callback, fs::path const& localisation_dir = "localisation");
};
}
diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp
index 63a97ad..7dd6e16 100644
--- a/src/openvic-simulation/dataloader/NodeTools.cpp
+++ b/src/openvic-simulation/dataloader/NodeTools.cpp
@@ -19,20 +19,20 @@ static node_callback_t _expect_type(callback_t<T const&> callback) {
};
}
-template<typename T = ast::AbstractStringNode>
+template<typename T>
requires(std::derived_from<T, ast::AbstractStringNode>)
-static callback_t<T const&> abstract_string_node_callback(callback_t<std::string_view> callback) {
+static callback_t<T const&> _abstract_string_node_callback(callback_t<std::string_view> callback) {
return [callback](T const& node) -> bool {
return callback(node._name);
};
}
node_callback_t NodeTools::expect_identifier(callback_t<std::string_view> callback) {
- return _expect_type<ast::IdentifierNode>(abstract_string_node_callback<ast::IdentifierNode>(callback));
+ return _expect_type<ast::IdentifierNode>(_abstract_string_node_callback<ast::IdentifierNode>(callback));
}
node_callback_t NodeTools::expect_string(callback_t<std::string_view> callback) {
- return _expect_type<ast::StringNode>(abstract_string_node_callback<ast::StringNode>(callback));
+ return _expect_type<ast::StringNode>(_abstract_string_node_callback<ast::StringNode>(callback));
}
node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_view> callback) {
@@ -43,7 +43,7 @@ node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_vi
cast_node = node->cast_to<ast::StringNode>();
}
if (cast_node != nullptr) {
- return abstract_string_node_callback(callback)(*cast_node);
+ return _abstract_string_node_callback<ast::AbstractStringNode>(callback)(*cast_node);
}
Logger::error("Invalid node type ", node->get_type(), " when expecting ", ast::IdentifierNode::get_type_static(), " or ", ast::StringNode::get_type_static());
} else {
@@ -148,6 +148,27 @@ node_callback_t NodeTools::expect_date(callback_t<Date> callback) {
);
}
+template<typename T, node_callback_t (*expect_func)(callback_t<T>)>
+node_callback_t _expect_vec2(callback_t<vec2_t<T>> callback) {
+ return [callback](ast::NodeCPtr node) -> bool {
+ vec2_t<T> vec;
+ bool ret = expect_dictionary_keys(
+ "x", ONE_EXACTLY, expect_func(assign_variable_callback(vec.x)),
+ "y", ONE_EXACTLY, expect_func(assign_variable_callback(vec.y))
+ )(node);
+ ret &= callback(vec);
+ return ret;
+ };
+}
+
+node_callback_t NodeTools::expect_ivec2(callback_t<ivec2_t> callback) {
+ return _expect_vec2<int64_t, expect_int>(callback);
+}
+
+node_callback_t NodeTools::expect_fvec2(callback_t<fvec2_t> callback) {
+ return _expect_vec2<fixed_point_t, expect_fixed_point>(callback);
+}
+
node_callback_t NodeTools::expect_assign(key_value_callback_t callback) {
return _expect_type<ast::AssignNode>(
[callback](ast::AssignNode const& assign_node) -> bool {
diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp
index a68e922..51bbfa9 100644
--- a/src/openvic-simulation/dataloader/NodeTools.hpp
+++ b/src/openvic-simulation/dataloader/NodeTools.hpp
@@ -6,7 +6,7 @@
#include "openvic-simulation/types/Colour.hpp"
#include "openvic-simulation/types/Date.hpp"
-#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
+#include "openvic-simulation/types/Vector.hpp"
namespace OpenVic {
namespace ast = ovdl::v2script::ast;
@@ -20,6 +20,7 @@ namespace OpenVic {
constexpr bool success_callback(ast::NodeCPtr) { return true; }
using key_value_callback_t = callback_t<std::string_view, ast::NodeCPtr>;
+ constexpr bool key_value_success_callback(std::string_view, ast::NodeCPtr) { return true; }
node_callback_t expect_identifier(callback_t<std::string_view> callback);
node_callback_t expect_string(callback_t<std::string_view> callback);
@@ -30,6 +31,8 @@ namespace OpenVic {
node_callback_t expect_fixed_point(callback_t<fixed_point_t> callback);
node_callback_t expect_colour(callback_t<colour_t> callback);
node_callback_t expect_date(callback_t<Date> callback);
+ node_callback_t expect_ivec2(callback_t<ivec2_t> callback);
+ node_callback_t expect_fvec2(callback_t<fvec2_t> callback);
node_callback_t expect_assign(key_value_callback_t callback);
using length_callback_t = std::function<size_t(size_t)>;
@@ -133,31 +136,38 @@ namespace OpenVic {
};
}
- template<typename T>
- requires(std::integral<T>)
- callback_t<uint64_t> assign_variable_callback_uint(const std::string_view name, T& var) {
- return [&var, name](uint64_t val) -> bool {
- if (val <= std::numeric_limits<T>::max()) {
+ template<typename I, typename T>
+ requires(std::integral<I>, std::integral<T>)
+ callback_t<I> _assign_variable_callback_int(const std::string_view name, T& var) {
+ return [&var, name](I val) -> bool {
+ if (std::numeric_limits<T>::lowest() <= val && val <= std::numeric_limits<T>::max()) {
var = val;
return true;
}
- Logger::error("Invalid ", name, ": ", val, " (valid range: [0, ", static_cast<uint64_t>(std::numeric_limits<T>::max()), "])");
+ Logger::error("Invalid ", name, ": ", val, " (valid range: [",
+ static_cast<int64_t>(std::numeric_limits<T>::lowest()), ", ",
+ static_cast<uint64_t>(std::numeric_limits<T>::max()), "])");
return false;
};
}
template<typename T>
requires(std::integral<T>)
+ callback_t<uint64_t> assign_variable_callback_uint(const std::string_view name, T& var) {
+ return _assign_variable_callback_int<uint64_t>(name, var);
+ }
+
+ template<typename T>
+ requires(std::integral<T>)
callback_t<int64_t> assign_variable_callback_int(const std::string_view name, T& var) {
- return [&var, name](int64_t val) -> bool {
- if (std::numeric_limits<T>::lowest() <= val && val <= std::numeric_limits<T>::max()) {
- var = val;
- return true;
- }
- Logger::error("Invalid ", name, ": ", val, " (valid range: [",
- static_cast<int64_t>(std::numeric_limits<T>::lowest()), ", ",
- static_cast<uint64_t>(std::numeric_limits<T>::max()), "])");
- return false;
+ return _assign_variable_callback_int<int64_t>(name, var);
+ }
+
+ template<typename T>
+ callback_t<T const&> assign_variable_callback_pointer(T const*& var) {
+ return [&var](T const& val) -> bool {
+ var = &val;
+ return true;
};
}
}
diff --git a/src/openvic-simulation/economy/Good.cpp b/src/openvic-simulation/economy/Good.cpp
index 6edf631..8675369 100644
--- a/src/openvic-simulation/economy/Good.cpp
+++ b/src/openvic-simulation/economy/Good.cpp
@@ -92,7 +92,7 @@ void GoodManager::reset_to_defaults() {
good.reset_to_defaults();
}
-bool GoodManager::load_good_file(ast::NodeCPtr root) {
+bool GoodManager::load_goods_file(ast::NodeCPtr root) {
size_t total_expected_goods = 0;
bool ret = expect_dictionary_reserve_length(
good_categories,
diff --git a/src/openvic-simulation/economy/Good.hpp b/src/openvic-simulation/economy/Good.hpp
index ce97cad..6c237b1 100644
--- a/src/openvic-simulation/economy/Good.hpp
+++ b/src/openvic-simulation/economy/Good.hpp
@@ -74,6 +74,6 @@ namespace OpenVic {
IDENTIFIER_REGISTRY_ACCESSORS(Good, good)
void reset_to_defaults();
- bool load_good_file(ast::NodeCPtr root);
+ bool load_goods_file(ast::NodeCPtr root);
};
}
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index e8178e9..0173ab6 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -54,10 +54,6 @@ bool Map::add_province(const std::string_view identifier, colour_t colour) {
return provinces.add_item(std::move(new_province));
}
-void Map::lock_provinces() {
- provinces.lock();
-}
-
bool Map::set_water_province(const std::string_view identifier) {
if (water_provinces.is_locked()) {
Logger::error("The map's water provinces have already been locked!");
@@ -133,36 +129,6 @@ bool Map::add_region(const std::string_view identifier, std::vector<std::string_
return ret;
}
-void Map::lock_regions() {
- regions.lock();
- 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 = &region;
- }
- }
- }
- 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 {
- return provinces.size();
-}
-
-std::vector<Province> const& Map::get_provinces() const {
- return provinces.get_items();
-}
-
Province* Map::get_province_by_index(Province::index_t index) {
return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr;
}
@@ -171,14 +137,6 @@ Province const* Map::get_province_by_index(Province::index_t index) const {
return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr;
}
-Province* Map::get_province_by_identifier(const std::string_view identifier) {
- return provinces.get_item_by_identifier(identifier);
-}
-
-Province const* Map::get_province_by_identifier(const std::string_view identifier) const {
- return provinces.get_item_by_identifier(identifier);
-}
-
Province::index_t Map::get_index_from_colour(colour_t colour) const {
const colour_index_map_t::const_iterator it = colour_index_map.find(colour);
if (it != colour_index_map.end()) return it->second;
@@ -224,22 +182,6 @@ Province const* Map::get_selected_province() const {
return get_province_by_index(get_selected_province_index());
}
-Region* Map::get_region_by_identifier(const std::string_view identifier) {
- return regions.get_item_by_identifier(identifier);
-}
-
-Region const* Map::get_region_by_identifier(const std::string_view identifier) const {
- return regions.get_item_by_identifier(identifier);
-}
-
-size_t Map::get_region_count() const {
- return regions.size();
-}
-
-std::vector<Region> const& Map::get_regions() const {
- return regions.get_items();
-}
-
static colour_t colour_at(uint8_t const* colour_data, int32_t idx) {
idx *= 3;
return (colour_data[idx] << 16) | (colour_data[idx + 1] << 8) | colour_data[idx + 2];
@@ -344,6 +286,9 @@ bool Map::generate_province_shape_image(size_t new_width, size_t new_height, uin
Logger::error("Province image is missing ", missing, " province colours");
ret = false;
}
+
+ ret &= _generate_province_adjacencies();
+
return ret;
}
@@ -427,9 +372,6 @@ bool Map::setup(GoodManager const& good_manager, BuildingManager const& building
bool ret = true;
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.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);
}
return ret;
@@ -512,6 +454,14 @@ bool Map::load_province_definitions(std::vector<LineObject> const& lines) {
return ret;
}
+bool Map::load_province_positions(BuildingManager const& building_manager, ast::NodeCPtr root) {
+ return expect_province_dictionary(
+ [&building_manager](Province& province, ast::NodeCPtr node) -> bool {
+ return province.load_positions(building_manager, node);
+ }
+ )(root);
+}
+
bool Map::load_region_file(ast::NodeCPtr root) {
const bool ret = expect_dictionary_reserve_length(
regions,
@@ -529,5 +479,33 @@ bool Map::load_region_file(ast::NodeCPtr root) {
}
)(root);
lock_regions();
+ 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 = &region;
+ }
+ }
+ }
+ 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;
+ }
+ }
return ret;
}
+
+bool Map::_generate_province_adjacencies() {
+ /* TODO - generate default province adjacencies
+ * variables available for use:
+ * - width, height
+ * - province_shape_image, so the index at (x,y) is:
+ * province_shape_image[x + y * width].index
+ */
+ return true;
+}
diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp
index d5157ef..163a21f 100644
--- a/src/openvic-simulation/map/Map.hpp
+++ b/src/openvic-simulation/map/Map.hpp
@@ -61,24 +61,23 @@ namespace OpenVic {
Pop::pop_size_t highest_province_population, total_map_population;
Province::index_t get_index_from_colour(colour_t colour) const;
+ bool _generate_province_adjacencies();
public:
Map();
bool add_province(const std::string_view identifier, colour_t colour);
- void lock_provinces();
+ IDENTIFIER_REGISTRY_ACCESSORS(Province, province)
+ IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(Province, province)
bool set_water_province(const std::string_view identifier);
bool set_water_province_list(std::vector<std::string_view> const& list);
void lock_water_provinces();
bool add_region(const std::string_view identifier, std::vector<std::string_view> const& province_identifiers);
- void lock_regions();
+ IDENTIFIER_REGISTRY_ACCESSORS(Region, region)
+ IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(Region, region)
- size_t get_province_count() const;
- std::vector<Province> const& get_provinces() const;
Province* get_province_by_index(Province::index_t index);
Province const* get_province_by_index(Province::index_t index) const;
- Province* get_province_by_identifier(const std::string_view identifier);
- Province const* get_province_by_identifier(const std::string_view identifier) const;
Province::index_t get_province_index_at(size_t x, size_t y) const;
bool set_max_provinces(Province::index_t new_max_provinces);
Province::index_t get_max_provinces() const;
@@ -86,11 +85,6 @@ namespace OpenVic {
Province::index_t get_selected_province_index() const;
Province const* get_selected_province() const;
- Region* get_region_by_identifier(const std::string_view identifier);
- Region const* get_region_by_identifier(const std::string_view identifier) const;
- size_t get_region_count() const;
- std::vector<Region> const& get_regions() const;
-
bool generate_province_shape_image(size_t new_width, size_t new_height, uint8_t const* colour_data,
uint8_t const* terrain_data, terrain_variant_map_t const& terrain_variant_map, bool detailed_errors);
size_t get_width() const;
@@ -113,6 +107,7 @@ namespace OpenVic {
void tick(Date const& today);
bool load_province_definitions(std::vector<ovdl::csv::LineObject> const& lines);
+ bool load_province_positions(BuildingManager const& building_manager, ast::NodeCPtr root);
bool load_region_file(ast::NodeCPtr root);
};
}
diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp
index 49a9bfc..775c0a4 100644
--- a/src/openvic-simulation/map/Province.cpp
+++ b/src/openvic-simulation/map/Province.cpp
@@ -34,6 +34,12 @@ Province::life_rating_t Province::get_life_rating() const {
return life_rating;
}
+bool Province::load_positions(BuildingManager const& building_manager, ast::NodeCPtr root) {
+ // TODO - implement province position loading
+ // (root is the dictionary after the province identifier)
+ return true;
+}
+
bool Province::add_building(Building&& building) {
return buildings.add_item(std::move(building));
}
diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp
index ca8138f..bf407ae 100644
--- a/src/openvic-simulation/map/Province.hpp
+++ b/src/openvic-simulation/map/Province.hpp
@@ -43,6 +43,8 @@ namespace OpenVic {
bool get_has_region() const;
bool get_water() const;
life_rating_t get_life_rating() const;
+ bool load_positions(BuildingManager const& building_manager, ast::NodeCPtr root);
+
bool add_building(Building&& building);
IDENTIFIER_REGISTRY_ACCESSORS(Building, building)
void reset_buildings();
diff --git a/src/openvic-simulation/pop/Culture.cpp b/src/openvic-simulation/pop/Culture.cpp
index bf14df9..dadc0a6 100644
--- a/src/openvic-simulation/pop/Culture.cpp
+++ b/src/openvic-simulation/pop/Culture.cpp
@@ -1,5 +1,7 @@
#include "Culture.hpp"
+#include <set>
+
#include "openvic-simulation/dataloader/NodeTools.hpp"
using namespace OpenVic;
@@ -128,7 +130,7 @@ bool CultureManager::_load_culture_group(size_t& total_expected_cultures,
},
"unit", ZERO_OR_ONE, [this, &total_expected_cultures, &unit_graphical_culture_type](ast::NodeCPtr node) -> bool {
total_expected_cultures--;
- return expect_graphical_culture_type(unit_graphical_culture_type)(node);
+ return expect_graphical_culture_type_identifier(assign_variable_callback_pointer(unit_graphical_culture_type))(node);
},
"union", ZERO_OR_ONE, [&total_expected_cultures](ast::NodeCPtr) -> bool {
total_expected_cultures--;
@@ -207,7 +209,10 @@ bool CultureManager::load_culture_file(ast::NodeCPtr root) {
CultureGroup const* culture_group = get_culture_group_by_identifier(culture_group_key);
return expect_dictionary(
[this, culture_group](std::string_view key, ast::NodeCPtr value) -> bool {
- if (key == "leader" || key == "unit" || key == "union" || key == "is_overseas") return true;
+ static const std::set<std::string, std::less<void>> reserved_keys = {
+ "leader", "unit", "union", "is_overseas"
+ };
+ if (reserved_keys.find(key) != reserved_keys.end()) return true;
return _load_culture(culture_group, key, value);
}
)(culture_group_value);
diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp
index 1c11b80..8feead9 100644
--- a/src/openvic-simulation/pop/Pop.cpp
+++ b/src/openvic-simulation/pop/Pop.cpp
@@ -142,8 +142,8 @@ bool PopManager::load_pop_into_province(Province& province, const std::string_vi
Pop::pop_size_t size = 0;
bool ret = expect_dictionary_keys(
- "culture", ONE_EXACTLY, culture_manager.expect_culture(culture),
- "religion", ONE_EXACTLY, religion_manager.expect_religion(religion),
+ "culture", ONE_EXACTLY, culture_manager.expect_culture_identifier(assign_variable_callback_pointer(culture)),
+ "religion", ONE_EXACTLY, religion_manager.expect_religion_identifier(assign_variable_callback_pointer(religion)),
"size", ONE_EXACTLY, expect_uint(assign_variable_callback_uint("pop size", size)),
"militancy", ZERO_OR_ONE, success_callback,
"rebel_type", ZERO_OR_ONE, success_callback
diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp
index 3f73a2c..c79e51b 100644
--- a/src/openvic-simulation/types/IdentifierRegistry.hpp
+++ b/src/openvic-simulation/types/IdentifierRegistry.hpp
@@ -171,30 +171,72 @@ namespace OpenVic {
return items;
}
- NodeTools::node_callback_t expect_item(T const*& ret) const {
+ NodeTools::node_callback_t expect_item_identifier(NodeTools::callback_t<T&> callback) {
return NodeTools::expect_identifier(
- [this, &ret](std::string_view identifier) -> bool {
- ret = get_item_by_identifier(identifier);
- if (ret != nullptr) return true;
+ [this, callback](std::string_view identifier) -> bool {
+ T* item = get_item_by_identifier(identifier);
+ if (item != nullptr) return callback(*item);
Logger::error("Invalid ", name, ": ", identifier);
return false;
}
);
}
+
+ NodeTools::node_callback_t expect_item_identifier(NodeTools::callback_t<T const&> callback) const {
+ return NodeTools::expect_identifier(
+ [this, callback](std::string_view identifier) -> bool {
+ T const* item = get_item_by_identifier(identifier);
+ if (item != nullptr) return callback(*item);
+ Logger::error("Invalid ", name, ": ", identifier);
+ return false;
+ }
+ );
+ }
+
+ NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t<T&, ast::NodeCPtr> callback) {
+ return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool {
+ T* item = get_item_by_identifier(key);
+ if (item != nullptr) {
+ return callback(*item, value);
+ }
+ Logger::error("Invalid ", name, " identifier: ", key);
+ return false;
+ });
+ }
+
+ NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t<T const&, ast::NodeCPtr> callback) const {
+ return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool {
+ T const* item = get_item_by_identifier(key);
+ if (item != nullptr) {
+ return callback(*item, value);
+ }
+ Logger::error("Invalid ", name, " identifier: ", key);
+ return false;
+ });
+ }
};
#define IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(type, singular, plural) \
void lock_##plural() { plural.lock(); } \
- type const* get_##singular##_by_index(size_t index) const { \
- return plural.get_item_by_index(index); } \
type const* get_##singular##_by_identifier(const std::string_view identifier) const { \
return plural.get_item_by_identifier(identifier); } \
size_t get_##singular##_count() const { \
return plural.size(); } \
std::vector<type> const& get_##plural() const { \
return plural.get_items(); } \
- NodeTools::node_callback_t expect_##singular(type const*& ret) const { \
- return plural.expect_item(ret); }
+ NodeTools::node_callback_t expect_##singular##_identifier(NodeTools::callback_t<type const&> callback) const { \
+ return plural.expect_item_identifier(callback); } \
+ NodeTools::node_callback_t expect_##singular##_dictionary(NodeTools::callback_t<type const&, ast::NodeCPtr> callback) const { \
+ return plural.expect_item_dictionary(callback); }
+
+#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(type, singular, plural) \
+ type* get_##singular##_by_identifier(const std::string_view identifier) { \
+ return plural.get_item_by_identifier(identifier); } \
+ NodeTools::node_callback_t expect_##singular##_identifier(NodeTools::callback_t<type&> callback) { \
+ return plural.expect_item_identifier(callback); } \
+ NodeTools::node_callback_t expect_##singular##_dictionary(NodeTools::callback_t<type&, ast::NodeCPtr> callback) { \
+ return plural.expect_item_dictionary(callback); }
#define IDENTIFIER_REGISTRY_ACCESSORS(type, name) IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(type, name, name##s)
+#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(type, name) IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(type, name, name##s)
}
diff --git a/src/openvic-simulation/types/Vector.hpp b/src/openvic-simulation/types/Vector.hpp
index fdf7d70..66f8d2b 100644
--- a/src/openvic-simulation/types/Vector.hpp
+++ b/src/openvic-simulation/types/Vector.hpp
@@ -27,6 +27,7 @@ namespace OpenVic {
constexpr friend vec2_t operator-(vec2_t const& arg);
constexpr friend vec2_t operator-(vec2_t const& left, vec2_t const& right);
constexpr vec2_t& operator-=(vec2_t const& right);
+
constexpr friend std::ostream& operator<<(std::ostream& stream, vec2_t const& value);
};