File: AAIExecute.h

package info (click to toggle)
spring 106.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 55,260 kB
  • sloc: cpp: 543,946; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (235 lines) | stat: -rw-r--r-- 10,170 bytes parent folder | download | duplicates (2)
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
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------

#ifndef AAI_EXECUTE_H
#define AAI_EXECUTE_H

#include "aidef.h"
#include "AAITypes.h"
#include "AAIUnitTypes.h"
#include "AAIBuildTable.h"

namespace springLegacyAI {
	struct UnitDef;
}
using namespace springLegacyAI;

enum class BuildOrderStatus : int {BUILDING_INVALID, NO_BUILDSITE_FOUND, NO_BUILDER_AVAILABLE, SUCCESSFUL};

class AAI;
class AAIBuildTable;
class AAIBrain;
class AAIMap;
class AAIUnitTable;
class AAISector;

struct AvailableMetalSpot
{
	AvailableMetalSpot(AAIMetalSpot* metalSpot, AAIConstructor* builder, UnitDefId extractor) :
		metalSpot(metalSpot),
		builder(builder),
		extractor(extractor)
		{}

	AAIMetalSpot*   metalSpot;
	AAIConstructor* builder;
	UnitDefId       extractor;
};

class AAIExecute
{
public:
	AAIExecute(AAI* ai);
	~AAIExecute(void);

	//! @brief Determines starting sector, adds another sector to base and initializes buildqueues
	void InitAI(UnitId commanderUnitId, UnitDefId commanderDefId);

	//! @brief Orders the unit to move to the given position
	void SendUnitToPosition(UnitId unitId, const float3& position) const;

	//! @brief Add the given unit to an existing group (or create new one if necessary)
	void AddUnitToGroup(const UnitId& unitId, const UnitDefId& unitDefId);

	//! @brief Selects combat unit according to given criteria and tries to order its construction
	void BuildCombatUnitOfCategory(const AAIMovementType& moveType, const TargetTypeValues& combatPowerCriteria, const UnitSelectionCriteria& unitSelectionCriteria, const std::vector<float>& factoryUtilization, bool urgent);

	void BuildScouts();

	//! @brief Looks for the next suitable destination for the given scout and orders it to move there
	void SendScoutToNewDest(UnitId scoutId) const;

	//! @brief Returns the current unit production rate (i.e. how many unit AAI tries to order per unit production update step)
	int GetUnitProductionRate() const { return m_unitProductionRate; }

	//! @brief Adjusts the unit production rate based on the current average length of the buildqueues of active factories
	void AdjustUnitProductionRate();

	//! @brief Returns the number of Build Tasks that could not be linked to a construction unit (for debugging only - should be zero)
	unsigned int GetLinkingBuildTaskToBuilderFailedCounter() const { return m_linkingBuildTaskToBuilderFailed; };

	//! @brief Searches for a position to retreat unit of certain type
	float3 DetermineSafePos(UnitDefId unitDefId, float3 unit_pos) const;

	// checks if ressources are sufficient and orders construction of new buildings
	void CheckRessources();

	// checks if buildings of that type could be replaced with more efficient one (e.g. mex -> moho)
	void CheckExtractorUpgrade();
	void CheckRadarUpgrade();
	void CheckJammerUpgrade();

	// checks which building type is most important to be constructed and tries to start construction
	void CheckConstruction();

	// the following functions determine how urgent it is to build a further building of the specified type
	void CheckFactories();

	void CheckRecon();

	void CheckStationaryArty();

	//
	void CheckDefences();

	//! @brief Check if construction nano turrets shall be ordered to support busy static constructors
	void CheckConstructionOfNanoTurret();

	//! @brief Cleans up buildmap/updates internal counters/frees metalspots if contruction has failed
	void ConstructionFailed(const float3& buildsite, UnitDefId unitDefId);

	//! @brief Orders construction of static defence to protect metal extractor
	void BuildStaticDefenceForExtractor(UnitId extractorId, UnitDefId extractorDefId) const;

	//! @brief Returns a position for the unit to withdraw from close quarters combat (but try to keep enemies in weapons range)
	//!        Returns ZeroVector if no suitable pos found (or no enemies close enough)
	float3 GetFallBackPos(const float3& pos, float maxFallbackDist) const;

	//! @brief Checks if a combat unit attacked by given enemy shall move back a little to maintain distance to attacker
	void CheckKeepDistanceToEnemy(UnitId unitId, UnitDefId unitDefId, UnitDefId enemyDefId);

	//! @brief Tries to call support against specific attacker (e.g. air)
	void DefendUnitVS(const UnitId& unitId, const AAITargetType& attackerTargetType, const float3& attackerPosition, float urgency) const;

	//! @brief Tries to add the given number of units to the most suitable buildqueue (returns whether units have been successfully added)
	bool TryAddingUnitsToBuildqueue(UnitDefId unitDefId, int number, BuildQueuePosition queuePosition, bool ignoreMaxQueueLength = false);

	//! @brief Adds the given number of units to the given buildqueue
	bool AddUnitsToBuildqueue(UnitDefId unitDefId, int number, Buildqueue buildqueue, BuildQueuePosition position, bool ignoreMaxQueueLength);

	//! @brief Determines buildsite for a unit (not building) that shall be constructed by the given construction unit
	BuildSite DetermineBuildsiteForUnit(UnitId constructor, UnitDefId unitDefId) const;

	//! @brief Sets urgency to construct building of given category to given value if larger than current value
	void SetConstructionUrgencyIfHigher(const AAIUnitCategory& category, float urgency)
	{
		if(m_constructionUrgency[category.GetArrayIndex()] < urgency)
			m_constructionUrgency[category.GetArrayIndex()] = urgency;
	}

	// debug
	void GiveOrder(Command *c, int unit, const char *owner) const;

private:
	// custom relations
	float static sector_threat(const AAISector *sector);

	bool static least_dangerous(const AAISector *left, const AAISector *right);
	bool static suitable_for_power_plant(AAISector *left, AAISector *right);
	bool static suitable_for_ground_factory(AAISector *left, AAISector *right);
	bool static suitable_for_sea_factory(AAISector *left, AAISector *right);
	bool static defend_vs_ground(const AAISector *left, const AAISector *right);
	bool static defend_vs_air(const AAISector *left, const AAISector *right);
	bool static defend_vs_hover(const AAISector *left, const AAISector *right);
	bool static defend_vs_sea(const AAISector *left, const AAISector *rightt);
	bool static defend_vs_submarine(const AAISector *left, const AAISector *right);

	float static learned;
	float static current;

	//! @brief Calls construction fucntion for given category and resets urgency to 0.0f if construction order has been given
	void TryConstruction(const AAIUnitCategory& category);

	//! @brief Tries to build a defence building vs target type in the specified sector
	//!        returns BUILDORDER_SUCCESSFUL if successful
	BuildOrderStatus BuildStationaryDefenceVS(const AAITargetType& targetType, const AAISector *dest);

	//! @brief Tries to build a defence fitting to given criteria
	BuildOrderStatus BuildStaticDefence(const AAISector* sector, const StaticDefenceSelectionCriteria& selectionCriteria, bool water) const;

	//! @brief Returns true if a construction unit was ordered to assist construction of a building of givn category
	bool AssistConstructionOfCategory(const AAIUnitCategory& category);

	// chooses a starting sector close to specified sector
	void ChooseDifferentStartingSector(int x, int y);

	//! @brief Returns closest (taking into account movement speed) group with units of specified unit type that may reach the location
	AAIGroup* GetClosestGroupForDefence(const AAITargetType& attackerTargetType, const float3& pos, int importance)  const;
	
	//! @brief Determines buildsite for a building that shall be constructed by the given construction unit
	BuildSite DetermineBuildsite(UnitId builder, UnitDefId buildingDefId) const;

	//! @brief Determines buildiste for the given building in the given sector, returns ZeroVector if none found
	BuildSite DetermineBuildsiteInSector(UnitDefId building, const AAISector* sector) const;

	void stopUnit(int unit);
	void ConstructBuildingAt(int building, int builder, float3 position);
	bool IsBusy(int unit);

	//! @brief Determine sectors that are suitable to construct eco (power plants, storage, metal makers); highest ranked sector is first in the list
	void DetermineSectorsToConstructEco(std::list<AAISector*>& sectors) const;

	//! @brief Tries to order construction of given building in one of the given sectors
	BuildOrderStatus ConstructBuildingInSectors(UnitDefId building, std::list<AAISector*>& availableSectors);

	//! @brief Helper function for construction of buildings
	BuildOrderStatus TryConstructionOfBuilding(UnitDefId building, AAISector* sector);

	//! @brief Tries to find a suitable buildsite and builder to start the construction of the given building;
	BuildOrderStatus TryConstructionOf(UnitDefId building, const AAISector* sector);

	BuildOrderStatus TryConstructionOf(UnitDefId landBuilding, UnitDefId seaBuilding, const AAISector* sector);

	bool BuildStaticConstructor();
	bool BuildDefences();
	bool BuildRadar();
	bool BuildJammer();
	bool BuildExtractor();
	bool BuildMetalMaker();
	bool BuildStorage();
	bool BuildPowerPlant();
	bool BuildArty();
	bool BuildAirBase();

	//! Urgency of construction of building of the different categories
	std::vector<float> m_constructionUrgency;

	//! Pointer to correspondind construction function for each category (or nullptr if none)
	std::vector< bool (AAIExecute::*) ()> m_constructionFunctions;

	//! Sector where next static defence shall be build (nullptr if none)
	AAISector*    m_sectorToBuildNextDefence;

	//! Target type against which which next defence shall be effective
	AAITargetType m_nextDefenceVsTargetType;

	//! The number of units the AI tries to order in every unit production update step
	int m_unitProductionRate;

	//! The total number of issued orders (primarily for debug purposes)
	mutable int m_numberOfIssuedOrders;

	//! Number of times a building was created but no suitable builder could be identfied (should be zero - just for debug purposes)
	unsigned int m_linkingBuildTaskToBuilderFailed;

	AAI *ai;
};

#endif