aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/history/DiplomaticHistory.hpp
blob: 7ae5114cf038475657afa10bc6cd397caa5d579e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#pragma once

#include <optional>
#include <vector>

#include "openvic-simulation/dataloader/NodeTools.hpp"
#include "openvic-simulation/history/Period.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/utility/Getters.hpp"

namespace OpenVic {
   struct DiplomaticHistoryManager;
   struct Country;
   struct WargoalType;
   struct ProvinceDefinition;

   struct WarHistory {
      friend struct DiplomaticHistoryManager;

      struct added_wargoal_t {
         friend struct DiplomaticHistoryManager;

      private:
         Date PROPERTY_CUSTOM_PREFIX(added, get_date);
         Country const* PROPERTY(actor);
         Country const* PROPERTY(receiver);
         WargoalType const* PROPERTY(wargoal);

         // TODO - could these just be nullptr when unset rather than using optionals?
         std::optional<Country const*> PROPERTY(third_party);
         std::optional<ProvinceDefinition const*> PROPERTY(target);

         added_wargoal_t(
            Date new_added, Country const* new_actor, Country const* new_receiver, WargoalType const* new_wargoal,
            std::optional<Country const*> new_third_party, std::optional<ProvinceDefinition const*> new_target
         );
      };

      struct war_participant_t {
         friend struct DiplomaticHistoryManager;

      private:
         Country const* PROPERTY(country);
         Period PROPERTY(period);

         war_participant_t(Country const* new_country, const Period period);
      };

   private:
      /* Edge cases where this is empty/undef for some reason,
       * probably need to just generate war names like usual for that. */
      std::string PROPERTY(war_name);
      std::vector<war_participant_t> PROPERTY(attackers);
      std::vector<war_participant_t> PROPERTY(defenders);
      std::vector<added_wargoal_t> PROPERTY(wargoals);

      WarHistory(
         std::string_view new_war_name, std::vector<war_participant_t>&& new_attackers,
         std::vector<war_participant_t>&& new_defenders, std::vector<added_wargoal_t>&& new_wargoals
      );
   };

   struct AllianceHistory {
      friend struct DiplomaticHistoryManager;

   private:
      Country const* PROPERTY(first);
      Country const* PROPERTY(second);
      const Period PROPERTY(period);

      AllianceHistory(Country const* new_first, Country const* new_second, const Period period);
   };

   struct ReparationsHistory {
      friend struct DiplomaticHistoryManager;

   private:
      Country const* PROPERTY(receiver);
      Country const* PROPERTY(sender);
      const Period PROPERTY(period);

      ReparationsHistory(Country const* new_receiver, Country const* new_sender, const Period period);
   };

   struct SubjectHistory {
      friend struct DiplomaticHistoryManager;

      enum class type_t {
         VASSAL,
         UNION,
         SUBSTATE
      };

   private:
      Country const* PROPERTY(overlord);
      Country const* PROPERTY(subject);
      const type_t PROPERTY_CUSTOM_PREFIX(type, get_subject);
      const Period PROPERTY(period);

      SubjectHistory(Country const* new_overlord, Country const* new_subject, const type_t new_type, const Period period);
   };

   struct CountryManager;
   struct GameManager;

   struct DiplomaticHistoryManager {
   private:
      std::vector<AllianceHistory> alliances;
      std::vector<ReparationsHistory> reparations;
      std::vector<SubjectHistory> subjects;
      std::vector<WarHistory> wars;
      bool locked = false;

   public:
      DiplomaticHistoryManager() {}

      void reserve_more_wars(size_t size);
      void lock_diplomatic_history();
      bool is_locked() const;

      std::vector<AllianceHistory const*> get_alliances(Date date) const;
      std::vector<ReparationsHistory const*> get_reparations(Date date) const;
      std::vector<SubjectHistory const*> get_subjects(Date date) const;
      /* Returns all wars that begin before date. NOTE: Some wargoals may be added or countries may join after date,
       * should be checked for by functions that use get_wars() */
      std::vector<WarHistory const*> get_wars(Date date) const;

      bool load_diplomacy_history_file(CountryManager const& country_manager, ast::NodeCPtr root);
      bool load_war_history_file(GameManager const& game_manager, ast::NodeCPtr root);
   };
}