aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map/Province.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/map/Province.cpp')
-rw-r--r--src/openvic-simulation/map/Province.cpp93
1 files changed, 76 insertions, 17 deletions
diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp
index eb23759..89ddd39 100644
--- a/src/openvic-simulation/map/Province.cpp
+++ b/src/openvic-simulation/map/Province.cpp
@@ -1,6 +1,7 @@
#include "Province.hpp"
#include "openvic-simulation/history/ProvinceHistory.hpp"
+#include "openvic-simulation/map/Map.hpp"
#include "openvic-simulation/military/UnitInstance.hpp"
using namespace OpenVic;
@@ -10,9 +11,10 @@ Province::Province(
std::string_view new_identifier, colour_t new_colour, index_t new_index
) : HasIdentifierAndColour { new_identifier, new_colour, true }, index { new_index }, region { nullptr },
climate { nullptr }, continent { nullptr }, on_map { false }, has_region { false }, water { false }, coastal { false },
- port { false }, default_terrain_type { nullptr }, positions {}, terrain_type { nullptr }, life_rating { 0 },
- colony_status { colony_status_t::STATE }, state { nullptr }, owner { nullptr }, controller { nullptr }, slave { false },
- crime { nullptr }, rgo { nullptr }, buildings { "buildings", false }, total_population { 0 } {
+ port { false }, port_adjacent_province { nullptr }, default_terrain_type { nullptr }, positions {},
+ terrain_type { nullptr }, life_rating { 0 }, colony_status { colony_status_t::STATE }, state { nullptr },
+ owner { nullptr }, controller { nullptr }, slave { false }, crime { nullptr }, rgo { nullptr },
+ buildings { "buildings", false }, total_population { 0 } {
assert(index != NULL_INDEX);
}
@@ -26,33 +28,68 @@ std::string Province::to_string() const {
return stream.str();
}
-bool Province::load_positions(BuildingTypeManager const& building_type_manager, ast::NodeCPtr root) {
+bool Province::load_positions(Map const& map, BuildingTypeManager const& building_type_manager, ast::NodeCPtr root) {
+ const fixed_point_t map_height = map.get_height();
+
const bool ret = expect_dictionary_keys(
- "text_position", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.text)),
- "text_rotation", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(positions.text_rotation)),
+ "text_position", ZERO_OR_ONE, expect_fvec2(flip_y_callback(assign_variable_callback(positions.text), map_height)),
+ "text_rotation", ZERO_OR_ONE,
+ expect_fixed_point(negate_callback<fixed_point_t>(assign_variable_callback(positions.text_rotation))),
"text_scale", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(positions.text_scale)),
- "unit", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.unit)),
- "town", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.city)),
- "city", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.city)),
- "factory", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.factory)),
- "building_construction", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.building_construction)),
- "military_construction", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.military_construction)),
+
+ "unit", ZERO_OR_ONE, expect_fvec2(flip_y_callback(assign_variable_callback(positions.unit), map_height)),
+ "town", ZERO_OR_ONE, expect_fvec2(flip_y_callback(assign_variable_callback(positions.city), map_height)),
+ "city", ZERO_OR_ONE, expect_fvec2(flip_y_callback(assign_variable_callback(positions.city), map_height)),
+ "factory", ZERO_OR_ONE, expect_fvec2(flip_y_callback(assign_variable_callback(positions.factory), map_height)),
+
+ "building_construction", ZERO_OR_ONE,
+ expect_fvec2(flip_y_callback(assign_variable_callback(positions.building_construction), map_height)),
+ "military_construction", ZERO_OR_ONE,
+ expect_fvec2(flip_y_callback(assign_variable_callback(positions.military_construction), map_height)),
+
"building_position", ZERO_OR_ONE, building_type_manager.expect_building_type_dictionary_reserve_length(
positions.building_position,
- [this](BuildingType const& type, ast::NodeCPtr value) -> bool {
- return expect_fvec2(map_callback(positions.building_position, &type))(value);
+ [this, map_height](BuildingType const& type, ast::NodeCPtr value) -> bool {
+ return expect_fvec2(flip_y_callback(map_callback(positions.building_position, &type), map_height))(value);
}
),
"building_rotation", ZERO_OR_ONE, building_type_manager.expect_building_type_decimal_map(
- move_variable_callback(positions.building_rotation)
+ move_variable_callback(positions.building_rotation), std::negate {}
),
+
/* the below are esoteric clausewitz leftovers that either have no impact or whose functionality is lost to time */
"spawn_railway_track", ZERO_OR_ONE, success_callback,
"railroad_visibility", ZERO_OR_ONE, success_callback,
"building_nudge", ZERO_OR_ONE, success_callback
)(root);
- port = coastal && positions.building_position.contains(building_type_manager.get_port_building_type());
+ if (coastal) {
+ fvec2_t const* port_position = get_building_position(building_type_manager.get_port_building_type());
+ if (port_position != nullptr) {
+ const fixed_point_t rotation = get_building_rotation(building_type_manager.get_port_building_type());
+
+ /* At 0 rotation the port faces west, as rotation increases the port rotates anti-clockwise. */
+ const fvec2_t port_dir { -rotation.cos(), rotation.sin() };
+ const ivec2_t port_facing_position = static_cast<ivec2_t>(*port_position + port_dir / 4);
+
+ Province const* province = map.get_province_at(port_facing_position);
+
+ if (province != nullptr) {
+ if (province->is_water() && is_adjacent_to(province)) {
+ port = true;
+ port_adjacent_province = province;
+ } else {
+ /* Expected provinces with invalid ports: 39, 296, 1047, 1406, 2044 */
+ Logger::warning(
+ "Invalid port for province ", get_identifier(), ": facing province ", province,
+ " which has: water = ", province->is_water(), ", adjacent = ", is_adjacent_to(province)
+ );
+ }
+ } else {
+ Logger::warning("Invalid port for province ", get_identifier(), ": facing null province!");
+ }
+ }
+ }
return ret;
}
@@ -66,6 +103,28 @@ bool Province::expand_building(size_t building_index) {
return building->expand();
}
+fvec2_t const* Province::get_building_position(BuildingType const* building_type) const {
+ if (building_type != nullptr) {
+ const decltype(positions.building_position)::const_iterator it = positions.building_position.find(building_type);
+
+ if (it != positions.building_position.end()) {
+ return &it->second;
+ }
+ }
+ return nullptr;
+}
+
+fixed_point_t Province::get_building_rotation(BuildingType const* building_type) const {
+ if (building_type != nullptr) {
+ const decltype(positions.building_rotation)::const_iterator it = positions.building_rotation.find(building_type);
+
+ if (it != positions.building_rotation.end()) {
+ return it->second;
+ }
+ }
+ return 0;
+}
+
void Province::_add_pop(Pop pop) {
pop.set_location(this);
pops.push_back(std::move(pop));
@@ -179,7 +238,7 @@ bool Province::has_adjacency_going_through(Province const* province) const {
}
fvec2_t Province::get_unit_position() const {
- return positions.unit.value_or(positions.centre);
+ return positions.unit.value_or(centre);
}
bool Province::add_army(ArmyInstance& army) {