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