diff options
author | hop311 <hop3114@gmail.com> | 2024-06-04 00:39:34 +0200 |
---|---|---|
committer | hop311 <hop3114@gmail.com> | 2024-06-06 19:39:35 +0200 |
commit | 37cdd775ac738b2a1264e32471385376e5a34f3a (patch) | |
tree | f3a9a107f1bd4b6b6d8035a96ac659bcc15f176b /src/openvic-simulation/map/ProvinceDefinition.hpp | |
parent | e286cfef29d7c431ba33cd77283e838e6fba05d2 (diff) |
Province const/mutable separation + State cleanupconst-mutable
Diffstat (limited to 'src/openvic-simulation/map/ProvinceDefinition.hpp')
-rw-r--r-- | src/openvic-simulation/map/ProvinceDefinition.hpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/openvic-simulation/map/ProvinceDefinition.hpp b/src/openvic-simulation/map/ProvinceDefinition.hpp new file mode 100644 index 0000000..a4076fe --- /dev/null +++ b/src/openvic-simulation/map/ProvinceDefinition.hpp @@ -0,0 +1,134 @@ +#pragma once + +#include <optional> + +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/types/fixed_point/FixedPointMap.hpp" +#include "openvic-simulation/types/HasIdentifier.hpp" +#include "openvic-simulation/types/OrderedContainers.hpp" +#include "openvic-simulation/types/Vector.hpp" + +namespace OpenVic { + + struct Map; + struct Region; + struct TerrainType; + struct ProvinceSetModifier; + using Climate = ProvinceSetModifier; + using Continent = ProvinceSetModifier; + struct BuildingType; + struct BuildingTypeManager; + + /* REQUIREMENTS: + * MAP-5, MAP-7, MAP-8, MAP-43, MAP-47 + * POP-22 + */ + struct ProvinceDefinition : HasIdentifierAndColour { + friend struct Map; + + using index_t = uint16_t; + using distance_t = fixed_point_t; // should this go inside adjacency_t? + + struct adjacency_t { + using data_t = uint8_t; + static constexpr data_t NO_CANAL = 0; + + enum struct type_t : uint8_t { + LAND, /* Between two land provinces */ + WATER, /* Between two water provinces */ + COASTAL, /* Between a land province and a water province */ + IMPASSABLE, /* Between two land provinces (non-traversable) */ + STRAIT, /* Between two land provinces with a water through province */ + CANAL /* Between two water provinces with a land through province */ + }; + + /* Type display name used for logging */ + static std::string_view get_type_name(type_t type); + + private: + ProvinceDefinition const* PROPERTY(to); + ProvinceDefinition const* PROPERTY(through); + distance_t PROPERTY(distance); + type_t PROPERTY(type); + data_t PROPERTY(data); // represents canal index, 0 for non-canal adjacencies + + public: + adjacency_t( + ProvinceDefinition const* new_to, distance_t new_distance, type_t new_type, + ProvinceDefinition const* new_through, data_t new_data + ); + adjacency_t(adjacency_t const&) = delete; + adjacency_t(adjacency_t&&) = default; + adjacency_t& operator=(adjacency_t const&) = delete; + adjacency_t& operator=(adjacency_t&&) = default; + }; + + struct province_positions_t { + /* Province name placement */ + std::optional<fvec2_t> text_position; + std::optional<fixed_point_t> text_rotation; + std::optional<fixed_point_t> text_scale; + + /* Model positions */ + std::optional<fvec2_t> unit; + std::optional<fvec2_t> city; + std::optional<fvec2_t> factory; + std::optional<fvec2_t> building_construction; + std::optional<fvec2_t> military_construction; + ordered_map<BuildingType const*, fvec2_t> building_position; + fixed_point_map_t<BuildingType const*> building_rotation; + }; + + static constexpr index_t NULL_INDEX = 0, MAX_INDEX = std::numeric_limits<index_t>::max(); + + private: + /* Immutable attributes (unchanged after initial game load) */ + const index_t PROPERTY(index); + Region const* PROPERTY(region); + Climate const* PROPERTY(climate); + Continent const* PROPERTY(continent); + bool PROPERTY(on_map); + bool PROPERTY_CUSTOM_PREFIX(water, is); + bool PROPERTY_CUSTOM_PREFIX(coastal, is); + bool PROPERTY_CUSTOM_PREFIX(port, has); + ProvinceDefinition const* PROPERTY(port_adjacent_province); + /* Terrain type calculated from terrain image */ + TerrainType const* PROPERTY(default_terrain_type); + + std::vector<adjacency_t> PROPERTY(adjacencies); + /* Calculated mean pixel position. */ + fvec2_t PROPERTY(centre); + province_positions_t positions; + + ProvinceDefinition(std::string_view new_identifier, colour_t new_colour, index_t new_index); + + public: + ProvinceDefinition(ProvinceDefinition&&) = default; + + bool operator==(ProvinceDefinition const& other) const; + std::string to_string() const; + + inline constexpr bool has_region() const { + return region != nullptr; + } + + /* The positions' y coordinates need to be inverted. */ + bool load_positions(Map const& map, BuildingTypeManager const& building_type_manager, ast::NodeCPtr root); + + fvec2_t get_text_position() const; + fixed_point_t get_text_rotation() const; + fixed_point_t get_text_scale() const; + + /* This returns a pointer to the position of the specified building type, or nullptr if none exists. */ + fvec2_t const* get_building_position(BuildingType const* building_type) const; + fixed_point_t get_building_rotation(BuildingType const* building_type) const; + + adjacency_t const* get_adjacency_to(ProvinceDefinition const* province) const; + bool is_adjacent_to(ProvinceDefinition const* province) const; + std::vector<adjacency_t const*> get_adjacencies_going_through(ProvinceDefinition const* province) const; + bool has_adjacency_going_through(ProvinceDefinition const* province) const; + + fvec2_t get_unit_position() const; + }; +} |