1 // -------------------------------------------------------------------------
2 // AAI
3 //
4 // A skirmish AI for the Spring engine.
5 // Copyright Alexander Seizinger
6 //
7 // Released under GPL license: see LICENSE.html for more information.
8 // -------------------------------------------------------------------------
9 
10 #ifndef AAI_EXECUTE_H
11 #define AAI_EXECUTE_H
12 
13 #include "aidef.h"
14 
15 namespace springLegacyAI {
16 	struct UnitDef;
17 }
18 using namespace springLegacyAI;
19 
20 enum BuildOrderStatus {BUILDORDER_FAILED, BUILDORDER_NOBUILDPOS, BUILDORDER_NOBUILDER, BUILDORDER_SUCCESFUL};
21 
22 class AAI;
23 class AAIBuildTable;
24 class AAIBrain;
25 class AAIMap;
26 class AAIUnitTable;
27 class AAISector;
28 
29 class AAIExecute
30 {
31 public:
32 	AAIExecute(AAI* ai);
33 	~AAIExecute(void);
34 
35 	void InitAI(int commander_unit_id, const UnitDef *commander_def);
36 
37 	// return true if building will be placed at a valid pos = inside sectors
38 	bool InitBuildingAt(const UnitDef *def, float3 *pos, bool water);
39 
40 	void CreateBuildTask(int unit, const UnitDef *def, float3 *pos);
41 
42 	void MoveUnitTo(int unit, float3 *position);
43 
44 	void AddUnitToGroup(int unit_id, int def_id, UnitCategory category);
45 
46 	void BuildScouts();
47 
48 	void SendScoutToNewDest(int scout);
49 
50 	// returns a position to retreat unit of certain type
51 	float3 GetSafePos(int def_id, float3 unit_pos);
52 
53 	// updates average ressource usage
54 	void UpdateRessources();
55 
56 	// checks if ressources are sufficient and orders construction of new buildings
57 	void CheckRessources();
58 
59 
60 	// checks if buildings of that type could be replaced with more efficient one (e.g. mex -> moho)
61 	void CheckMexUpgrade();
62 	void CheckRadarUpgrade();
63 	void CheckJammerUpgrade();
64 
65 	// checks which building type is most important to be constructed and tries to start construction
66 	void CheckConstruction();
67 
68 	// the following functions determine how urgent it is to build a further building of the specified type
69 	void CheckFactories();
70 	void CheckAirBase();
71 	void CheckRecon();
72 	void CheckJammer();
73 	void CheckStationaryArty();
74 
75 	// checks length of buildqueues and adjusts rate of unit production
76 	void CheckBuildqueues();
77 
78 	//
79 	void CheckDefences();
80 
81 	// builds all kind of buildings
82 
83 //	void BuildUnit(UnitCategory category, float speed, float cost, float range, float power, float ground_eff, float air_eff, float hover_eff, float sea_eff, float submarine_eff, float stat_eff, float eff, bool urgent);
84 
85 	// called when building has been finished / contruction failed
86 	void ConstructionFailed(float3 build_pos, int def_id);
87 	void ConstructionFinished();
88 
89 	// builds defences around mex spot if necessary
90 	void DefendMex(int mex, int def_id);
91 
92 	// returns a position for the unit to withdraw from close quarters combat (but try to keep enemies in weapons range)
93 	// returns ZeroVector if no suitable pos found (or no enemies close enough)
94 	void GetFallBackPos(float3 *pos, int unit_id, float max_weapon_range) const;
95 
96 	void CheckFallBack(int unit_id, int def_id);
97 
98 
99 	// tries to call support vs air (returns true if succesful)
100 	void DefendUnitVS(int unit, unsigned int enemy_movement_type, float3 *enemy_pos, int importance);
101 
102 
103 	// adds a unit to the correct wishlist
104 	bool AddUnitToBuildqueue(int def_id, int number, bool urgent);
105 
106 	// returns buildque for a certain factory
107 	list<int>* GetBuildqueueOfFactory(int def_id);
108 
109 
110 	float3 GetRallyPoint(unsigned int unit_movement_type, int continent_id, int min_dist, int max_dist);
111 	float3 GetUnitBuildsite(int builder, int unit);
112 
113 	int unitProductionRate;
114 
115 	// ressource management
116 	// tells ai, how many times additional metal/energy has been requested
117 	float futureRequestedMetal;
118 	float futureRequestedEnergy;
119 	float futureAvailableMetal;
120 	float futureAvailableEnergy;
121 	float futureStoredMetal;
122 	float futureStoredEnergy;
123 	float averageMetalSurplus;
124 	float averageEnergySurplus;
125 	int disabledMMakers;
126 
127 
128 	// urgency of construction of building of the different categories
129 	float urgency[METAL_MAKER+1];
130 
131 	// sector where next def vs category needs to be built (0 if none)
132 
133 	// debug
134 	void GiveOrder(Command *c, int unit, const char *owner);
135 
136 private:
137 	// accelerates game startup
138 	void AddStartFactory();
139 
140 	// custom relations
141 	float static sector_threat(AAISector *);
142 
143 	bool static least_dangerous(AAISector *left, AAISector *right);
144 	bool static suitable_for_power_plant(AAISector *left, AAISector *right);
145 	bool static suitable_for_ground_factory(AAISector *left, AAISector *right);
146 	bool static suitable_for_sea_factory(AAISector *left, AAISector *right);
147 	bool static defend_vs_ground(AAISector *left, AAISector *right);
148 	bool static defend_vs_air(AAISector *left, AAISector *right);
149 	bool static defend_vs_hover(AAISector *left, AAISector *right);
150 	bool static defend_vs_sea(AAISector *left, AAISector *right);
151 	bool static defend_vs_submarine(AAISector *left, AAISector *right);
152 	bool static suitable_for_ground_rallypoint(AAISector *left, AAISector *right);
153 	bool static suitable_for_sea_rallypoint(AAISector *left, AAISector *right);
154 	bool static suitable_for_all_rallypoint(AAISector *left, AAISector *right);
155 
156 	// cache to speed things up a bit
157 	float static learned;
158 	float static current;
159 	// buildques for the factories
160 	vector<list<int> > buildques;
161 	// number of factories (both mobile and sationary)
162 
163 	int numOfFactories;
164 
165 	// tries to build a defence building vs category in the specified sector
166 	// returns BUILDORDER_SUCCESFUL if succesful
167 	BuildOrderStatus BuildStationaryDefenceVS(UnitCategory category, AAISector *dest);
168 
169 	// returns true if successfully assisting construction
170 	bool AssistConstructionOfCategory(UnitCategory category, int importance = 5);
171 
172 	// returns the the total ground offensive power of all units
173 
174 
175 
176 	float GetTotalGroundPower();
177 
178 	// returns the the total air defence power of all units
179 	float GetTotalAirPower();
180 
181 	// chooses a starting sector close to specified sector
182 	void ChooseDifferentStartingSector(int x, int y);
183 
184 	// returns closest (taking into account movement speed) group with units of specified unit type that may reach the location
185 
186 	AAIGroup* GetClosestGroupForDefence(UnitType group_type, float3 *pos, int continent, int importance);
187 	float3 GetRallyPointCloseTo(UnitCategory category, unsigned int unit_movement_type, int continent_id, float3 pos, int min_dist, int max_dist);
188 	float3 GetBuildsite(int builder, int building, UnitCategory category);
189 	void InitBuildques();
190 
191 	void stopUnit(int unit);
192 	void ConstructBuildingAt(int building, int builder, float3 position);
193 	bool IsBusy(int unit);
194 
195 	float GetEnergyUrgency();
196 
197 	float GetMetalUrgency();
198 	float GetEnergyStorageUrgency();
199 	float GetMetalStorageUrgency();
200 
201 	bool BuildFactory();
202 	bool BuildDefences();
203 	bool BuildRadar();
204 	bool BuildJammer();
205 	bool BuildExtractor();
206 	bool BuildMetalMaker();
207 	bool BuildStorage();
208 	bool BuildPowerPlant();
209 	bool BuildArty();
210 	bool BuildAirBase();
211 
212 	float averageMetalUsage;
213 	float averageEnergyUsage;
214 	int counter;
215 	float metalSurplus[8];
216 	float energySurplus[8];
217 	AAISector *next_defence;
218 	UnitCategory def_category;
219 
220 	int issued_orders;
221 
222 	AAI *ai;
223 
224 	// stores which buildque belongs to what kind of factory
225 	vector<int> factory_table;
226 };
227 
228 #endif
229 
230