diff options
Diffstat (limited to 'src/openvic-simulation/map')
-rw-r--r-- | src/openvic-simulation/map/Map.cpp | 86 | ||||
-rw-r--r-- | src/openvic-simulation/map/Province.cpp | 35 | ||||
-rw-r--r-- | src/openvic-simulation/map/Province.hpp | 13 |
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); }; |