#pragma once #include #include #include #include #include "openvic-simulation/military/UnitInstance.hpp" #include "openvic-simulation/military/UnitType.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" #include "openvic-simulation/utility/Getters.hpp" namespace OpenVic { struct ProvinceInstance; struct MovementInfo { private: std::vector PROPERTY(path); fixed_point_t PROPERTY(movement_progress); public: MovementInfo(); // contains/calls pathfinding logic MovementInfo(ProvinceInstance const* starting_province, ProvinceInstance const* target_province); }; template struct LeaderBranched; struct CountryInstance; template struct UnitInstanceGroup { using _UnitInstance = UnitInstanceBranched; using _Leader = LeaderBranched; private: std::string PROPERTY(name); std::vector<_UnitInstance*> PROPERTY(units); _Leader* PROPERTY(leader); MovementInfo PROPERTY_REF(movement_info); protected: ProvinceInstance* PROPERTY_ACCESS(position, protected); CountryInstance* PROPERTY_ACCESS(country, protected); UnitInstanceGroup( std::string_view new_name, std::vector<_UnitInstance*>&& new_units ); public: UnitInstanceGroup(UnitInstanceGroup&&) = default; UnitInstanceGroup(UnitInstanceGroup const&) = delete; size_t get_unit_count() const; bool empty() const; size_t get_unit_category_count(UnitType::unit_category_t unit_category) const; UnitType const* get_display_unit_type() const; void set_name(std::string_view new_name); bool set_position(ProvinceInstance* new_position); bool set_country(CountryInstance* new_country); bool set_leader(_Leader* new_leader); }; template struct UnitInstanceGroupBranched; template<> struct UnitInstanceGroupBranched : UnitInstanceGroup { friend struct UnitInstanceManager; private: UnitInstanceGroupBranched( std::string_view new_name, std::vector&& new_units ); public: UnitInstanceGroupBranched(UnitInstanceGroupBranched&&) = default; }; using ArmyInstance = UnitInstanceGroupBranched; template<> struct UnitInstanceGroupBranched : UnitInstanceGroup { friend struct UnitInstanceManager; private: std::vector PROPERTY(carried_armies); UnitInstanceGroupBranched( std::string_view new_name, std::vector&& new_ships ); public: UnitInstanceGroupBranched(UnitInstanceGroupBranched&&) = default; }; using NavyInstance = UnitInstanceGroupBranched; template struct UnitDeployment; template struct UnitDeploymentGroup; struct MapInstance; struct Deployment; struct UnitInstanceManager { private: plf::colony PROPERTY(regiments); plf::colony PROPERTY(ships); UNIT_BRANCHED_GETTER(get_unit_instances, regiments, ships); plf::colony PROPERTY(armies); plf::colony PROPERTY(navies); UNIT_BRANCHED_GETTER(get_unit_instance_groups, armies, navies); template bool generate_unit_instance( UnitDeployment const& unit_deployment, UnitInstanceBranched*& unit_instance ); template bool generate_unit_instance_group( MapInstance& map_instance, CountryInstance& country, UnitDeploymentGroup const& unit_deployment_group ); public: bool generate_deployment(MapInstance& map_instance, CountryInstance& country, Deployment const* deployment); }; }