aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/military/UnitInstance.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/military/UnitInstance.hpp')
-rw-r--r--src/openvic-simulation/military/UnitInstance.hpp116
1 files changed, 102 insertions, 14 deletions
diff --git a/src/openvic-simulation/military/UnitInstance.hpp b/src/openvic-simulation/military/UnitInstance.hpp
index dcca18a..e3d541a 100644
--- a/src/openvic-simulation/military/UnitInstance.hpp
+++ b/src/openvic-simulation/military/UnitInstance.hpp
@@ -3,7 +3,9 @@
#include <concepts>
#include <string_view>
#include <vector>
+
#include "openvic-simulation/map/Province.hpp"
+#include "openvic-simulation/military/Deployment.hpp"
#include "openvic-simulation/military/Leader.hpp"
#include "openvic-simulation/military/UnitType.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
@@ -11,7 +13,7 @@
namespace OpenVic {
template<std::derived_from<UnitType> T>
struct UnitInstance {
- protected:
+ private:
std::string PROPERTY(unit_name);
T const& PROPERTY(unit_type); //can't change
@@ -26,23 +28,35 @@ namespace OpenVic {
organisation { new_unit_type.get_default_organisation() }, //TODO: modifiers
morale { 0 }, //TODO: modifiers
strength { new_unit_type.get_max_strength() } {}
+
public:
+ UnitInstance(UnitInstance&&) = default;
+
void set_unit_name(std::string_view new_unit_name) {
unit_name = new_unit_name;
}
};
struct RegimentInstance : UnitInstance<RegimentType> {
+ friend struct UnitInstanceManager;
+
private:
- Pop& PROPERTY(pop);
+ Pop* PROPERTY(pop);
+
+ RegimentInstance(std::string_view new_name, RegimentType const& new_regiment_type, Pop* new_pop);
public:
- RegimentInstance(std::string_view new_name, RegimentType const& new_regiment_type, Pop& new_pop);
+ RegimentInstance(RegimentInstance&&) = default;
};
struct ShipInstance : UnitInstance<ShipType> {
- public:
+ friend struct UnitInstanceManager;
+
+ private:
ShipInstance(std::string_view new_name, ShipType const& new_ship_type);
+
+ public:
+ ShipInstance(ShipInstance&&) = default;
};
struct MovementInfo {
@@ -55,56 +69,130 @@ namespace OpenVic {
MovementInfo(Province const* starting_province, Province const* target_province); // contains/calls pathfinding logic
};
+ struct CountryInstance;
+
template<utility::is_derived_from_specialization_of<UnitInstance> I>
struct UnitInstanceGroup {
private:
std::string PROPERTY(name);
const UnitType::branch_t PROPERTY(branch);
std::vector<I*> PROPERTY(units);
- Leader const* PROPERTY_RW(leader);
- Province const* PROPERTY_RW(position);
+ Leader const* PROPERTY(leader);
MovementInfo PROPERTY_REF(movement_info);
protected:
+ Province* PROPERTY_ACCESS(position, protected);
+ CountryInstance* PROPERTY_ACCESS(country, protected);
+
UnitInstanceGroup(
std::string_view new_name,
UnitType::branch_t new_branch,
std::vector<I*>&& new_units,
Leader const* new_leader,
- Province const* new_position
+ CountryInstance* new_country
) : name { new_name },
branch { new_branch },
units { std::move(new_units) },
leader { new_leader },
- position { new_position } {}
-
+ position { nullptr },
+ country { new_country } {}
+
public:
+ UnitInstanceGroup(UnitInstanceGroup&&) = default;
+ UnitInstanceGroup(UnitInstanceGroup const&) = delete;
+
void set_name(std::string_view new_name) {
name = new_name;
}
+
+ size_t get_unit_count() const {
+ return units.size();
+ }
+
+ bool empty() const {
+ return units.empty();
+ }
+
+ size_t get_unit_category_count(UnitType::unit_category_t unit_category) const {
+ return std::count_if(units.begin(), units.end(), [unit_category](I const* unit) {
+ return unit->unit_type.get_unit_category() == unit_category;
+ });
+ }
+
+ UnitType const* get_display_unit_type() const {
+ if (units.empty()) {
+ return nullptr;
+ }
+
+ fixed_point_map_t<UnitType const*> weighted_unit_types;
+
+ for (I const* unit : units) {
+ UnitType const& unit_type = unit->get_unit_type();
+ weighted_unit_types[&unit_type] += unit_type.get_weighted_value();
+ }
+
+ return get_largest_item_tie_break(
+ weighted_unit_types,
+ [](UnitType const* lhs, UnitType const* rhs) -> bool {
+ return lhs->get_weighted_value() < rhs->get_weighted_value();
+ }
+ )->first;
+ }
+
+ virtual void set_position(Province* new_position) = 0;
};
struct ArmyInstance : UnitInstanceGroup<RegimentInstance> {
- public:
+ friend struct UnitInstanceManager;
+
+ private:
ArmyInstance(
std::string_view new_name,
std::vector<RegimentInstance*>&& new_units,
Leader const* new_leader,
- Province const* new_position
+ CountryInstance* new_country
);
+
+ public:
+ ArmyInstance(ArmyInstance&&) = default;
+
+ void set_position(Province* new_position) override;
};
struct NavyInstance : UnitInstanceGroup<ShipInstance> {
+ friend struct UnitInstanceManager;
+
private:
std::vector<ArmyInstance const*> PROPERTY(carried_armies);
- public:
NavyInstance(
std::string_view new_name,
std::vector<ShipInstance*>&& new_ships,
Leader const* new_leader,
- Province const* new_position
+ CountryInstance* new_country
);
+
+ public:
+ NavyInstance(NavyInstance&&) = default;
+
+ void set_position(Province* new_position) override;
+ };
+
+ struct UnitInstanceManager {
+ private:
+ std::deque<RegimentInstance> PROPERTY(regiments);
+ std::deque<ShipInstance> PROPERTY(ships);
+
+ std::deque<ArmyInstance> PROPERTY(armies);
+ std::deque<NavyInstance> PROPERTY(navies);
+
+ bool generate_regiment(RegimentDeployment const& regiment_deployment, RegimentInstance*& regiment);
+ bool generate_ship(ShipDeployment const& ship_deployment, ShipInstance*& ship);
+ bool generate_army(Map& map, CountryInstance& country, ArmyDeployment const& army_deployment);
+ bool generate_navy(Map& map, CountryInstance& country, NavyDeployment const& navy_deployment);
+
+ public:
+ bool generate_deployment(Map& map, CountryInstance& country, Deployment const* deployment);
};
-} \ No newline at end of file
+}