-
Notifications
You must be signed in to change notification settings - Fork 1
/
AAIUnitTypes.h
336 lines (240 loc) · 15.6 KB
/
AAIUnitTypes.h
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------
#ifndef AAI_UNIT_CATEGORY_H
#define AAI_UNIT_CATEGORY_H
#include <string>
#include <vector>
#include <array>
typedef unsigned int uint32_t;
//! Different categories that are used to group units with similar/same purpose
enum class EUnitCategory : int
{
UNKNOWN = 0, //! Unknown unit category, i.e. not set
STATIC_DEFENCE = 1, //!
STATIC_ARTILLERY = 2, //!
STORAGE = 3, //!
STATIC_CONSTRUCTOR = 4, //! factories
STATIC_ASSISTANCE = 5, //! nano turrets
STATIC_SUPPORT = 6, //! jammer, air base, missile launcher, shields
STATIC_SENSOR = 7, //! radar, sonar, seismic
POWER_PLANT = 8, //!
METAL_EXTRACTOR = 9, //!
METAL_MAKER = 10, //!
COMMANDER = 11, //!
GROUND_COMBAT = 12, //!
AIR_COMBAT = 13, //!
HOVER_COMBAT = 14, //!
SEA_COMBAT = 15, //!
SUBMARINE_COMBAT = 16,
MOBILE_ARTILLERY = 17, //!
SCOUT = 18, //!
TRANSPORT = 19, //!
MOBILE_CONSTRUCTOR = 20, //!
MOBILE_SUPPORT = 21, //! mobile radar, jammer, anti-nukes
NUMBER_OF_CATEGORIES = 22
};
//! The unit category is a coarse classification used to differentiate between different types of units.
//! Statistical data (e.g. buildcost) is calculated for each category. Further differentiation
//! (e.g. combat vs. anti air units) is given by AAIUnitType.
class AAIUnitCategory
{
public:
AAIUnitCategory() : m_unitCategory(EUnitCategory::UNKNOWN) {};
AAIUnitCategory(EUnitCategory unitCategory) : m_unitCategory(unitCategory) {};
bool operator==(const AAIUnitCategory& rhs) const { return (m_unitCategory == rhs.GetUnitCategory()); };
void SetUnitCategory(EUnitCategory unitCategory) { m_unitCategory = unitCategory; };
EUnitCategory GetUnitCategory() const { return m_unitCategory; };
bool IsValid() const { return (m_unitCategory != EUnitCategory::UNKNOWN) ? true : false; };
bool IsStaticDefence() const { return (m_unitCategory == EUnitCategory::STATIC_DEFENCE) ? true : false; };
bool IsStaticArtillery() const { return (m_unitCategory == EUnitCategory::STATIC_ARTILLERY) ? true : false; };
bool IsStorage() const { return (m_unitCategory == EUnitCategory::STORAGE) ? true : false; };
bool IsStaticConstructor() const { return (m_unitCategory == EUnitCategory::STATIC_CONSTRUCTOR) ? true : false; };
bool IsStaticAssistance() const { return (m_unitCategory == EUnitCategory::STATIC_ASSISTANCE) ? true : false; };
bool IsStaticSupport() const { return (m_unitCategory == EUnitCategory::STATIC_SUPPORT) ? true : false; };
bool IsStaticSensor() const { return (m_unitCategory == EUnitCategory::STATIC_SENSOR) ? true : false; };
bool IsPowerPlant() const { return (m_unitCategory == EUnitCategory::POWER_PLANT) ? true : false; };
bool IsMetalExtractor() const { return (m_unitCategory == EUnitCategory::METAL_EXTRACTOR) ? true : false; };
bool IsMetalMaker() const { return (m_unitCategory == EUnitCategory::METAL_MAKER) ? true : false; };
bool IsCommander() const { return (m_unitCategory == EUnitCategory::COMMANDER) ? true : false; };
bool IsGroundCombat() const { return (m_unitCategory == EUnitCategory::GROUND_COMBAT) ? true : false; };
bool IsAirCombat() const { return (m_unitCategory == EUnitCategory::AIR_COMBAT) ? true : false; };
bool IsHoverCombat() const { return (m_unitCategory == EUnitCategory::HOVER_COMBAT) ? true : false; };
bool IsSeaCombat() const { return (m_unitCategory == EUnitCategory::SEA_COMBAT) ? true : false; };
bool IsSubmarineCombat() const { return (m_unitCategory == EUnitCategory::SUBMARINE_COMBAT) ? true : false; };
bool IsMobileArtillery() const { return (m_unitCategory == EUnitCategory::MOBILE_ARTILLERY) ? true : false; };
bool IsScout() const { return (m_unitCategory == EUnitCategory::SCOUT) ? true : false; };
bool IsTransport() const { return (m_unitCategory == EUnitCategory::TRANSPORT) ? true : false; };
bool IsMobileConstructor() const { return (m_unitCategory == EUnitCategory::MOBILE_CONSTRUCTOR) ? true : false; };
bool IsMobileSupport() const { return (m_unitCategory == EUnitCategory::MOBILE_SUPPORT) ? true : false; };
bool IsBuilding() const { return (static_cast<int>(m_unitCategory) >= static_cast<int>(EUnitCategory::STATIC_DEFENCE) )
&& (static_cast<int>(m_unitCategory) <= static_cast<int>(EUnitCategory::METAL_MAKER) ); };
bool IsCombatUnit() const { return (static_cast<int>(m_unitCategory) >= static_cast<int>(EUnitCategory::GROUND_COMBAT) )
&& (static_cast<int>(m_unitCategory) <= static_cast<int>(EUnitCategory::SUBMARINE_COMBAT) ); };
static constexpr int numberOfUnitCategories = static_cast<int>(EUnitCategory::NUMBER_OF_CATEGORIES);
static EUnitCategory GetFirst() { return EUnitCategory::UNKNOWN; };
void Next() { m_unitCategory = static_cast<EUnitCategory>( static_cast<int>(m_unitCategory) + 1 ); };
bool End() const { return (m_unitCategory == EUnitCategory::NUMBER_OF_CATEGORIES); };
//! Returns unit category as index (to access arrays)
int GetArrayIndex() const {return static_cast<int>(m_unitCategory); };
private:
//! The unit category
EUnitCategory m_unitCategory;
};
//! Different categories of combat units
enum class ECombatUnitCategory : int
{
SURFACE = 0,
AIR = 1,
SEA = 2,
NUMBER_OF_CATEGORIES = 3,
};
//! The CombatUnitCategory uis used to differentiate between units that may fight on land, air, or sea
class AAICombatUnitCategory
{
public:
AAICombatUnitCategory() : m_combatUnitCategory(ECombatUnitCategory::SURFACE) {}
AAICombatUnitCategory(ECombatUnitCategory category) : m_combatUnitCategory(category) {}
ECombatUnitCategory GetCombatUnitCategory() const { return m_combatUnitCategory; }
void SetCategory(ECombatUnitCategory combatUnitCategory) { m_combatUnitCategory = combatUnitCategory; }
static constexpr int numberOfCombatUnitCategories = static_cast<int>(ECombatUnitCategory::NUMBER_OF_CATEGORIES);
static constexpr std::array<ECombatUnitCategory, 3> m_combatUnitCategories = {ECombatUnitCategory::SURFACE, ECombatUnitCategory::AIR, ECombatUnitCategory::SEA};
//! Returns index to access arrays storing combat unit data, i.e. ranging from 0 to numberOfCombatUnitCategories-1
int GetArrayIndex() const {return static_cast<int>(m_combatUnitCategory); }
static constexpr int surfaceIndex = static_cast<int>(ECombatUnitCategory::SURFACE);
static constexpr int airIndex = static_cast<int>(ECombatUnitCategory::AIR);
static constexpr int seaIndex = static_cast<int>(ECombatUnitCategory::SEA);
static const std::vector<std::string> m_combatCategoryNames;
//const static std::vector<std::string> m_combatCategoryNames = {"Surface", "Air", "Sea"};
private:
//! The unit category
ECombatUnitCategory m_combatUnitCategory;
};
//! The target category describes what kind of target class a unit belongs to
enum class ETargetType : int
{
SURFACE = 0, //! Units on ground (move type ground, amphibious, hover, land buildings)
AIR = 1, //! Air units
FLOATER = 2, //! Units moving above water (ships, hover) or floating buildings
SUBMERGED = 3, //! Units moving below water (submarines) or submerged buildings
STATIC = 4, //! Static units (= buildings)
NUMBER_OF_CATEGORIES = 5, //! The number of combat categories (unknown/invalid not used)
UNKNOWN = 6, //! This value will be treated as invalid
};
//! This class handles the target category which describes
class AAITargetType
{
public:
AAITargetType(ETargetType targetType) : m_targetType(targetType) {}
AAITargetType() : AAITargetType(ETargetType::UNKNOWN) {}
void SetType(ETargetType targetType) { m_targetType = targetType; }
bool IsValid() const { return (m_targetType != ETargetType::UNKNOWN); }
bool IsSurface() const { return (m_targetType == ETargetType::SURFACE); }
bool IsAir() const { return (m_targetType == ETargetType::AIR); }
bool IsFloater() const { return (m_targetType == ETargetType::FLOATER); }
bool IsSubmerged() const { return (m_targetType == ETargetType::SUBMERGED); }
bool IsStatic() const { return (m_targetType == ETargetType::STATIC); }
int GetArrayIndex() const {return static_cast<int>(m_targetType); }
static int GetArrayIndex(ETargetType targetType) { return static_cast<int>(targetType); }
bool operator==(const AAITargetType& rhs) const { return (m_targetType == rhs.m_targetType); }
static constexpr int surfaceIndex = static_cast<int>(ETargetType::SURFACE);
static constexpr int airIndex = static_cast<int>(ETargetType::AIR);
static constexpr int floaterIndex = static_cast<int>(ETargetType::FLOATER);
static constexpr int submergedIndex = static_cast<int>(ETargetType::SUBMERGED);
static constexpr int staticIndex = static_cast<int>(ETargetType::STATIC);
static constexpr int numberOfMobileTargetTypes = static_cast<int>(ETargetType::NUMBER_OF_CATEGORIES)-1;
static constexpr int numberOfTargetTypes = static_cast<int>(ETargetType::NUMBER_OF_CATEGORIES);
static constexpr std::array<ETargetType, 4> m_mobileTargetTypes = {ETargetType::SURFACE, ETargetType::AIR, ETargetType::FLOATER, ETargetType::SUBMERGED};
static constexpr std::array<ETargetType, 5> m_targetTypes = {ETargetType::SURFACE, ETargetType::AIR, ETargetType::FLOATER, ETargetType::SUBMERGED, ETargetType::STATIC};
const std::string& GetName() const { return m_targetTypeNames[GetArrayIndex()]; }
static const std::vector<std::string> m_targetTypeNames;
//const static std::vector<std::string> m_targetTypeNames = {"surface", "air", "floater", "submerged", "static"};
private:
ETargetType m_targetType;
};
//! The type of the unit (may further specifiy the purpose of a unit, e.g. anti ground vs anti air for combat units)
enum class EUnitType : int
{
UNKNOWN = 0x0000, //! Unknown unit type, i.e. not set
BUILDING = 0x0001, //! Static unit aka building
MOBILE_UNIT = 0x0002, //! Mobile unit
ANTI_SURFACE = 0x0004, //! Used for combat units/static defences that can fight land/hover/floating units
ANTI_AIR = 0x0008, //! Anti air combat units/static defences
ANTI_SHIP = 0x0010, //! Anti ship combat units/static defences
ANTI_SUBMERGED = 0x0020, //! Anti submarine combat units/static defences
ANTI_STATIC = 0x0040, //! Anti building
RADAR = 0x0080, //! Radar
SONAR = 0x0100, //! Sonar
SEISMIC = 0x0200, //! Seismic detector
RADAR_JAMMER = 0x0400, //! Radar jammer
SONAR_JAMMER = 0x0800, //! Sonar jammer
BUILDER = 0x1000, //! Can construct buildings
FACTORY = 0x2000, //! Can construct units
CONSTRUCTION_ASSIST = 0x4000, //! Can assists with construction of units/buildings
MELEE_UNIT = 0x8000, //! Combat units that directly charge for enemy and do not try to keep it at distance
};
//! @brief Unit type with convenience functions (works as bitmask)
class AAIUnitType
{
public:
AAIUnitType() : m_unitType(static_cast<int>(EUnitType::UNKNOWN)) {}
AAIUnitType(EUnitType unitType) : m_unitType(static_cast<int>(unitType)) {}
//! @brief Sets the given unit type
void SetUnitType(EUnitType unitType) { m_unitType = static_cast<int>(unitType); }
//! @brief Adds the given unit type
void AddUnitType(EUnitType unitType) { m_unitType |= static_cast<int>(unitType); }
//! @brief Returns whether given unit type is set
bool IsUnitTypeSet(EUnitType unitType) const { return static_cast<bool>(m_unitType & static_cast<int>(unitType)); }
//! @brief Returns whether unit is a building (i.e. static)
bool IsBuilding() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::BUILDING)); }
//! @brief Returns whether unit is mobile
bool IsMobileUnit() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::MOBILE_UNIT)); }
//! @brief Returns whether unit is considered to be able to fight against surface units (ground, hover, ships)
bool IsAntiSurface() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::ANTI_SURFACE)); }
//! @brief Returns whether unit is considered to be an anti air unit
bool IsAntiAir() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::ANTI_AIR)); }
//! @brief Returns whether unit is considered to be able to fight submerged units (submarines)
bool IsAntiShip() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::ANTI_SHIP)); }
//! @brief Returns whether unit is considered to be able to fight submerged units (submarines)
bool IsAntiSubmerged() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::ANTI_SUBMERGED)); }
//! @brief Returns whether unit is considered to be able to fight static units more efficiently (e.g. bombers, missile launchers)
bool IsAntiStatic() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::ANTI_STATIC)); }
//! @brief Returns true if radar flag is set
bool IsRadar() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::RADAR)); }
//! @brief Returns true if sonar flag is set
bool IsSonar() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::SONAR)); }
//! @brief Returns true if seismic detector flag is set
bool IsSeismicDetector() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::SEISMIC)); }
//! @brief Returns true if radar jammer flag is set
bool IsRadarJammer() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::RADAR_JAMMER)); }
//! @brief Returns true if radar jammer flag is set
bool IsSonarJammer() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::SONAR_JAMMER)); }
//! @brief Returns true if unit can construct at least one building
bool IsBuilder() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::BUILDER)); }
//! @brief Returns true if unit can construct at least one mobile unit
bool IsFactory() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::FACTORY)); }
//! @brief Returns true if unit can help with costruction of other units/buildings
bool IsConstructionAssist() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::CONSTRUCTION_ASSIST)); }
//! @brief Returns true if unit is considered to be melee (suitable to engage in close quarters combat)
bool IsMeleeCombatUnit() const { return static_cast<bool>(m_unitType & static_cast<int>(EUnitType::MELEE_UNIT)); }
//! @brief Returns whether unit is considered to be able to fight against surface or submerged units (not anti air)
bool IsAssaultUnit() const { return static_cast<bool>(m_unitType & (static_cast<int>(EUnitType::ANTI_SURFACE) + static_cast<int>(EUnitType::ANTI_SHIP) + static_cast<int>(EUnitType::ANTI_SUBMERGED) )); }
//! @brief Returns whether unit type is suitable to fight given target type
bool CanFightTargetType(const AAITargetType& targetType) const
{
return (targetType.IsSurface() && IsAntiSurface())
|| (targetType.IsAir() && IsAntiAir())
|| (targetType.IsFloater() && IsAntiShip())
|| (targetType.IsSubmerged() && IsAntiSubmerged())
|| (targetType.IsStatic() && IsAntiStatic());
}
private:
//! Unit type
int m_unitType;
};
#endif