| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #pragma once
- #include "../units/troop_type.h"
- #include <QVector3D>
- #include <memory>
- #include <string>
- #include <unordered_map>
- #include <vector>
- namespace Engine::Core {
- using EntityID = unsigned int;
- class World;
- } // namespace Engine::Core
- namespace Game::Systems {
- enum class FormationType { Roman, Barbarian, Carthage };
- struct UnitFormationInfo {
- Engine::Core::EntityID entity_id;
- Game::Units::TroopType troop_type;
- QVector3D current_position;
- };
- struct FormationPosition {
- QVector3D position;
- float facing_angle;
- Engine::Core::EntityID entity_id{0};
- };
- } // namespace Game::Systems
- namespace std {
- template <> struct hash<Game::Systems::FormationType> {
- auto operator()(const Game::Systems::FormationType &ft) const -> std::size_t {
- return std::hash<int>()(static_cast<int>(ft));
- }
- };
- } // namespace std
- namespace Game::Systems {
- class IFormation {
- public:
- virtual ~IFormation() = default;
- [[nodiscard]] virtual auto calculate_positions(
- int unit_count, const QVector3D ¢er,
- float base_spacing = 1.0F) const -> std::vector<QVector3D> = 0;
- [[nodiscard]] virtual auto calculate_formation_positions(
- const std::vector<UnitFormationInfo> &units, const QVector3D ¢er,
- float base_spacing = 1.0F) const -> std::vector<FormationPosition> = 0;
- [[nodiscard]] virtual auto get_type() const -> FormationType = 0;
- };
- class RomanFormation : public IFormation {
- public:
- [[nodiscard]] auto calculate_positions(
- int unit_count, const QVector3D ¢er,
- float base_spacing = 1.0F) const -> std::vector<QVector3D> override;
- [[nodiscard]] auto
- calculate_formation_positions(const std::vector<UnitFormationInfo> &units,
- const QVector3D ¢er,
- float base_spacing = 1.0F) const
- -> std::vector<FormationPosition> override;
- [[nodiscard]] auto get_type() const -> FormationType override {
- return FormationType::Roman;
- }
- };
- class BarbarianFormation : public IFormation {
- public:
- [[nodiscard]] auto calculate_positions(
- int unit_count, const QVector3D ¢er,
- float base_spacing = 1.0F) const -> std::vector<QVector3D> override;
- [[nodiscard]] auto
- calculate_formation_positions(const std::vector<UnitFormationInfo> &units,
- const QVector3D ¢er,
- float base_spacing = 1.0F) const
- -> std::vector<FormationPosition> override;
- [[nodiscard]] auto get_type() const -> FormationType override {
- return FormationType::Barbarian;
- }
- };
- class CarthageFormation : public IFormation {
- public:
- [[nodiscard]] auto calculate_positions(
- int unit_count, const QVector3D ¢er,
- float base_spacing = 1.0F) const -> std::vector<QVector3D> override;
- [[nodiscard]] auto
- calculate_formation_positions(const std::vector<UnitFormationInfo> &units,
- const QVector3D ¢er,
- float base_spacing = 1.0F) const
- -> std::vector<FormationPosition> override;
- [[nodiscard]] auto get_type() const -> FormationType override {
- return FormationType::Carthage;
- }
- };
- class FormationSystem {
- public:
- static auto instance() -> FormationSystem &;
- auto
- get_formation_positions(FormationType type, int unit_count,
- const QVector3D ¢er,
- float base_spacing = 1.0F) -> std::vector<QVector3D>;
- auto get_formation_positions_with_facing(
- FormationType type, const std::vector<UnitFormationInfo> &units,
- const QVector3D ¢er,
- float base_spacing = 1.0F) -> std::vector<FormationPosition>;
- void register_formation(FormationType type,
- std::unique_ptr<IFormation> formation);
- auto get_formation(FormationType type) const -> const IFormation *;
- private:
- FormationSystem();
- void initialize_defaults();
- std::unordered_map<FormationType, std::unique_ptr<IFormation>> m_formations;
- };
- } // namespace Game::Systems
|