aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/map')
-rw-r--r--src/openvic-simulation/map/Map.cpp86
-rw-r--r--src/openvic-simulation/map/Province.cpp35
-rw-r--r--src/openvic-simulation/map/Province.hpp13
3 files changed, 97 insertions, 37 deletions
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index 18f72cf..1e68cc6 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -294,8 +294,15 @@ bool Map::apply_history_to_provinces(ProvinceHistoryManager const& history_manag
if (!province.get_water()) {
ProvinceHistoryMap const* history_map = history_manager.get_province_history(&province);
if (history_map != nullptr) {
+ ProvinceHistoryEntry const* pop_history_entry = nullptr;
for (ProvinceHistoryEntry const* entry : history_map->get_entries_up_to(date)) {
province.apply_history_to_province(entry);
+ if (!entry->get_pops().empty()) {
+ pop_history_entry = entry;
+ }
+ }
+ if (pop_history_entry != nullptr) {
+ province.add_pop_vec(pop_history_entry->get_pops());
}
}
}
@@ -493,34 +500,41 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain
std::vector<fixed_point_map_t<TerrainType const*>> terrain_type_pixels_list(provinces.size());
bool ret = true;
std::unordered_set<colour_t> unrecognised_province_colours;
+
+ std::vector<fixed_point_t> pixels_per_province(provinces.size());
+ std::vector<fixed_point_t> x_sum_per_province(provinces.size());
+ std::vector<fixed_point_t> y_sum_per_province(provinces.size());
for (size_t y = 0; y < height; ++y) {
for (size_t x = 0; x < width; ++x) {
- const size_t idx = x + y * width;
+ const size_t pixel_index = x + y * width;
+ const colour_t province_colour = colour_at(province_data, pixel_index);
- const colour_t province_colour = colour_at(province_data, idx);
if (x > 0) {
- const size_t jdx = idx - 1;
+ const size_t jdx = pixel_index - 1;
if (colour_at(province_data, jdx) == province_colour) {
- province_shape_image[idx].index = province_shape_image[jdx].index;
+ province_shape_image[pixel_index].index = province_shape_image[jdx].index;
goto set_terrain;
}
}
+
if (y > 0) {
- const size_t jdx = idx - width;
+ const size_t jdx = pixel_index - width;
if (colour_at(province_data, jdx) == province_colour) {
- province_shape_image[idx].index = province_shape_image[jdx].index;
+ province_shape_image[pixel_index].index = province_shape_image[jdx].index;
goto set_terrain;
}
}
+
{
- const Province::index_t index = get_index_from_colour(province_colour);
- if (index != Province::NULL_INDEX) {
- province_checklist[index - 1] = true;
- province_shape_image[idx].index = index;
+ const Province::index_t province_index = get_index_from_colour(province_colour);
+ if (province_index != Province::NULL_INDEX) {
+ province_checklist[province_index - 1] = true;
+ province_shape_image[pixel_index].index = province_index;
goto set_terrain;
}
}
+
if (!unrecognised_province_colours.contains(province_colour)) {
unrecognised_province_colours.insert(province_colour);
if (detailed_errors) {
@@ -529,20 +543,30 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain
);
}
}
- province_shape_image[idx].index = Province::NULL_INDEX;
+
+ province_shape_image[pixel_index].index = Province::NULL_INDEX;
set_terrain:
- const TerrainTypeMapping::index_t terrain = terrain_data[idx];
+ const Province::index_t province_index = province_shape_image[pixel_index].index;
+ if (province_index != Province::NULL_INDEX) {
+ const uint16_t array_index = province_index - 1;
+ pixels_per_province[array_index]++;
+ x_sum_per_province[array_index] += x;
+ y_sum_per_province[array_index] += y;
+ }
+
+ const TerrainTypeMapping::index_t terrain = terrain_data[pixel_index];
TerrainTypeMapping const* mapping = terrain_type_manager.get_terrain_type_mapping_for(terrain);
if (mapping != nullptr) {
- if (province_shape_image[idx].index != Province::NULL_INDEX) {
- terrain_type_pixels_list[province_shape_image[idx].index - 1][&mapping->get_type()]++;
+
+ if (province_index != Province::NULL_INDEX) {
+ terrain_type_pixels_list[province_index - 1][&mapping->get_type()]++;
}
- province_shape_image[idx].terrain =
+ province_shape_image[pixel_index].terrain =
mapping->get_has_texture() && terrain < terrain_type_manager.get_terrain_texture_limit() ? terrain + 1 : 0;
} else {
- province_shape_image[idx].terrain = 0;
+ province_shape_image[pixel_index].terrain = 0;
}
}
}
@@ -552,11 +576,22 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain
}
size_t missing = 0;
- 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->default_terrain_type = largest != terrain_type_pixels_list[idx].end() ? largest->first : nullptr;
- province->on_map = province_checklist[idx];
+ for (size_t array_index = 0; array_index < province_checklist.size(); ++array_index) {
+ Province* province = provinces.get_item_by_index(array_index);
+ const fixed_point_t pixel_count = pixels_per_province[array_index];
+ if(pixel_count > 0) {
+ const fixed_point_t x = x_sum_per_province[array_index] / pixel_count;
+ const fixed_point_t y = y_sum_per_province[array_index] / pixel_count;
+ const fvec2_t center { x, y };
+ province->positions.center = center;
+ }
+ else {
+ Logger::warning("Province ",province->index," has no pixels");
+ }
+
+ const fixed_point_map_const_iterator_t<TerrainType const*> largest = get_largest_item(terrain_type_pixels_list[array_index]);
+ province->default_terrain_type = largest != terrain_type_pixels_list[array_index].end() ? largest->first : nullptr;
+ province->on_map = province_checklist[array_index];
if (!province->on_map) {
if (detailed_errors) {
Logger::warning("Province missing from shape image: ", province->to_string());
@@ -577,10 +612,12 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain
bool Map::_generate_province_adjacencies() {
bool changed = false;
- auto generate_adjacency = [&](Province* cur, size_t x, size_t y) -> bool {
+ auto generate_adjacency = [&](Province* current, size_t x, size_t y) -> bool {
Province* neighbour = get_province_by_index(province_shape_image[x + y * width].index);
- if (neighbour != nullptr && cur != neighbour) {
- return cur->add_adjacency(neighbour, 0, 0) | neighbour->add_adjacency(cur, 0, 0);
+ if (neighbour != nullptr && current != neighbour) {
+ const Province::distance_t distance = current->calculate_distance_to(neighbour);
+ const Province::flags_t flags = 0;
+ return current->add_adjacency(neighbour, distance, flags) | neighbour->add_adjacency(current, distance, flags);
}
return false;
};
@@ -588,6 +625,7 @@ bool Map::_generate_province_adjacencies() {
for (size_t y = 0; y < height; ++y) {
for (size_t x = 0; x < width; ++x) {
Province* cur = get_province_by_index(province_shape_image[x + y * width].index);
+
if (cur != nullptr) {
changed |= generate_adjacency(cur, (x + 1) % width, y);
if (y + 1 < height) {
diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp
index 363be6c..717ef35 100644
--- a/src/openvic-simulation/map/Province.cpp
+++ b/src/openvic-simulation/map/Province.cpp
@@ -58,14 +58,6 @@ bool Province::expand_building(std::string_view building_type_identifier) {
return building->expand();
}
-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 {
- return pop_manager.load_pop_into_province(*this, pop_type_identifier, pop_node);
- }
- )(root);
-}
-
bool Province::add_pop(Pop&& pop) {
if (!get_water()) {
pops.push_back(std::move(pop));
@@ -76,6 +68,19 @@ bool Province::add_pop(Pop&& pop) {
}
}
+bool Province::add_pop_vec(std::vector<Pop> const& pop_vec) {
+ if (!get_water()) {
+ pops.reserve(pops.size() + pop_vec.size());
+ for (Pop const& pop : pop_vec) {
+ pops.push_back(pop);
+ }
+ return true;
+ } else {
+ Logger::error("Trying to add pop vector to water province ", get_identifier());
+ return false;
+ }
+}
+
size_t Province::get_pop_count() const {
return pops.size();
}
@@ -116,7 +121,7 @@ Province::adjacency_t::adjacency_t(Province const* province, distance_t distance
assert(province != nullptr);
}
-bool Province::is_adjacent_to(Province const* province) {
+bool Province::is_adjacent_to(Province const* province) const {
for (adjacency_t adj : adjacencies) {
if (adj.province == province) {
return true;
@@ -137,6 +142,18 @@ bool Province::add_adjacency(Province const* province, distance_t distance, flag
return true;
}
+fvec2_t Province::get_unit_position() const {
+ return positions.unit.value_or(positions.center);
+}
+
+Province::distance_t Province::calculate_distance_to(Province const* province) const {
+ const fvec2_t my_unit_position = get_unit_position();
+ const fvec2_t other_unit_position = province->get_unit_position();
+ const fvec2_t distance_vector = other_unit_position - my_unit_position;
+ const fixed_point_t distance = distance_vector.length_squared();
+ return static_cast<Province::distance_t>(distance);
+}
+
bool Province::reset(BuildingTypeManager const& building_type_manager) {
terrain_type = default_terrain_type;
life_rating = 0;
diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp
index 0b98588..2f8068e 100644
--- a/src/openvic-simulation/map/Province.hpp
+++ b/src/openvic-simulation/map/Province.hpp
@@ -26,7 +26,7 @@ namespace OpenVic {
using index_t = uint16_t;
using life_rating_t = int8_t;
- using distance_t = uint16_t;
+ using distance_t = fixed_point_t;
using flags_t = uint16_t;
enum struct colony_status_t : uint8_t { STATE, PROTECTORATE, COLONY };
@@ -43,10 +43,11 @@ namespace OpenVic {
};
struct province_positions_t {
+ fvec2_t center;
fvec2_t text;
fixed_point_t text_rotation;
fixed_point_t text_scale;
- fvec2_t unit;
+ std::optional<fvec2_t> unit;
fvec2_t city;
fvec2_t factory;
fvec2_t building_construction;
@@ -89,6 +90,8 @@ namespace OpenVic {
fixed_point_map_t<Culture const*> PROPERTY(culture_distribution);
fixed_point_map_t<Religion const*> PROPERTY(religion_distribution);
+ fvec2_t get_unit_position() const;
+
Province(std::string_view new_identifier, colour_t new_colour, index_t new_index);
public:
@@ -100,17 +103,19 @@ namespace OpenVic {
bool expand_building(std::string_view building_type_identifier);
- bool load_pop_list(PopManager const& pop_manager, ast::NodeCPtr root);
bool add_pop(Pop&& pop);
+ bool add_pop_vec(std::vector<Pop> const& pop_vec);
size_t get_pop_count() const;
void update_pops();
void update_state(Date today);
void tick(Date today);
- bool is_adjacent_to(Province const* province);
+ bool is_adjacent_to(Province const* province) const;
bool add_adjacency(Province const* province, distance_t distance, flags_t flags);
+ distance_t calculate_distance_to(Province const* province) const;
+
bool reset(BuildingTypeManager const& building_type_manager);
bool apply_history_to_province(ProvinceHistoryEntry const* entry);
};