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_BUILDTABLE_H 11 #define AAI_BUILDTABLE_H 12 13 class AAI; 14 15 namespace springLegacyAI { 16 struct UnitDef; 17 } 18 using namespace springLegacyAI; 19 20 21 #include "aidef.h" 22 #include <assert.h> 23 #include <list> 24 #include <vector> 25 #include <string> 26 27 using namespace std; 28 29 struct UnitTypeDynamic 30 { 31 int under_construction; // how many units of that type are under construction 32 int requested; // how many units of that type have been requested 33 int active; // how many units of that type are currently alive 34 int constructorsAvailable; // how many factories/builders available being able to build that unit 35 int constructorsRequested; // how many factories/builders requested being able to build that unit 36 }; 37 38 struct UnitTypeStatic 39 { 40 int def_id; 41 int side; // 0 if side has not been set 42 list<int> canBuildList; 43 list<int> builtByList; 44 vector<float> efficiency; // 0 -> ground assault, 1 -> air assault, 2 -> hover assault 45 // 3 -> sea assault, 4 -> submarine , 5 -> stat. defences 46 float range; // max weapon range (0 for unarmed units) 47 float cost; 48 float builder_cost; 49 UnitCategory category; 50 51 unsigned int unit_type; 52 unsigned int movement_type; 53 }; 54 55 56 class AAIBuildTable 57 { 58 public: 59 AAIBuildTable(AAI* ai); 60 ~AAIBuildTable(void); 61 62 // call before you want to use the buildtable 63 // loads everything from a cache file or creates a new one 64 void Init(); 65 66 void SaveBuildTable(int game_period, MapType map_type); 67 // cache for combat eff (needs side, thus initialized later) 68 void InitCombatEffCache(int side); 69 70 // returns true, if a builder can build a certain unit (use UnitDef.id) 71 bool CanBuildUnit(int id_builder, int id_unit); 72 73 // returns side of a certian unittype (use UnitDef->id) 74 int GetSideByID(int unit_id); 75 76 // return unit type (for groups) 77 UnitType GetUnitType(int def_id); 78 79 // ****************************************************************************************************** 80 // the following functions are used to determine units that suit a certain purpose 81 // if water == true, only water based units/buildings will be returned 82 // randomness == 1 means no randomness at all; never set randomnes to zero -> crash 83 // ****************************************************************************************************** 84 // returns power plant 85 int GetPowerPlant(int side, float cost, float urgency, float max_power, float current_energy, bool water, bool geo, bool canBuild); 86 87 // returns a extractor from the list based on certain factors 88 int GetMex(int side, float cost, float effiency, bool armed, bool water, bool canBuild); 89 90 // returns mex with the biggest yardmap 91 int GetBiggestMex(); 92 93 // return defence buildings to counter a certain category 94 int GetDefenceBuilding(int side, double efficiency, double combat_power, double cost, double ground_eff, double air_eff, double hover_eff, double sea_eff, double submarine_eff, double urgency, double range, int randomness, bool water, bool canBuild); 95 96 // returns a cheap defence building (= avg_cost taken 97 int GetCheapDefenceBuilding(int side, double efficiency, double combat_power, double cost, double urgency, double ground_eff, double air_eff, double hover_eff, double sea_eff, double submarine_eff, bool water); 98 99 // returns a metal maker 100 int GetMetalMaker(int side, float cost, float efficiency, float metal, float urgency, bool water, bool canBuild); 101 102 // returns a storage 103 int GetStorage(int side, float cost, float metal, float energy, float urgency, bool water, bool canBuild); 104 105 // return repair pad 106 int GetAirBase(int side, float cost, bool water, bool canBuild); 107 108 // returns a ground unit according to the following criteria 109 int GetGroundAssault(int side, float power, float gr_eff, float air_eff, float hover_eff, float sea_eff, float stat_eff, float efficiency, float speed, float range, float cost, int randomness, bool canBuild); 110 111 int GetHoverAssault(int side, float power, float gr_eff, float air_eff, float hover_eff, float sea_eff, float stat_eff, float efficiency, float speed, float range, float cost, int randomness, bool canBuild); 112 113 // returns an air unit according to the following criteria 114 int GetAirAssault(int side, float power, float gr_eff, float air_eff, float hover_eff, float sea_eff, float stat_eff, float efficiency, float speed, float range, float cost, int randomness, bool canBuild); 115 116 int GetSeaAssault(int side, float power, float gr_eff, float air_eff, float hover_eff, float sea_eff, float submarine_eff, float stat_eff, float efficiency, float speed, float range, float cost, int randomness, bool canBuild); 117 118 int GetSubmarineAssault(int side, float power, float sea_eff, float submarine_eff, float stat_eff, float efficiency, float speed, float range, float cost, int randomness, bool canBuild); 119 120 // returns a random unit from the list 121 int GetRandomUnit(list<int> unit_list); 122 123 // compares two units with respect to their combat power 124 int DetermineBetterUnit(int unit1, int unit2, float ground_eff, float air_eff, float hover_eff, float sea_eff, float submarine_eff, float speed, float range, float cost); 125 126 int GetRandomDefence(int side, UnitCategory category); 127 128 int GetStationaryArty(int side, float cost, float range, float efficiency, bool water, bool canBuild); 129 130 // returns a scout 131 int GetScout(int side, float los, float cost, unsigned int allowed_movement_types, int randomness, bool cloakable, bool canBuild); 132 133 int GetRadar(int side, float cost, float range, bool water, bool canBuild); 134 135 int GetJammer(int side, float cost, float range, bool water, bool canBuild); 136 137 // checks which factory is needed for a specific unit and orders it to be built 138 void BuildFactoryFor(int unit_def_id); 139 140 // tries to build another builder for a certain building 141 void BuildBuilderFor(int building_def_id); 142 143 // tries to build an assistant for the specified kind of unit 144 void AddAssistant(unsigned int allowed_movement_types, bool canBuild); 145 146 // returns the allowed movement types for an assisters to assist constrcution of a specified building 147 unsigned int GetAllowedMovementTypesForAssister(int building); 148 149 float GetFactoryRating(int def_id); 150 float GetBuilderRating(int def_id); 151 152 // updates unit table 153 void UpdateTable(const UnitDef* def_killer, int killer, const UnitDef *def_killed, int killed); 154 155 // updates max and average eff. values of the different categories 156 void UpdateMinMaxAvgEfficiency(); 157 158 // returns max range of all weapons 159 float GetMaxRange(int unit_id); 160 161 // returns max damage of all weapons 162 float GetMaxDamage(int unit_id); 163 164 // returns true, if unit is arty 165 bool IsArty(int id); 166 167 // returns true, if unit is a scout 168 bool IsScout(int id); 169 170 // returns true if the unit is marked as attacker (so that it won't be classed as something else even if it can build etc.) 171 bool IsAttacker(int id); 172 173 bool IsMissileLauncher(int def_id); 174 175 bool IsDeflectionShieldEmitter(int def_id); 176 177 // returns false if unit is a member of the dont_build list 178 bool AllowedToBuild(int id); 179 180 //sadly can't detect metal makers anymore, read them from config 181 bool IsMetalMaker(int id); 182 183 // returns true, if unit is a transporter 184 bool IsTransporter(int id); 185 186 // return a units eff. against a certain category 187 float GetEfficiencyAgainst(int unit_def_id, UnitCategory category); 188 189 // returns true if unit is starting unit 190 bool IsStartingUnit(int def_id); 191 192 bool IsCommander(int def_id); 193 194 bool IsBuilder(int def_id); 195 bool IsFactory(int def_id); 196 197 bool IsGround(int def_id); 198 bool IsAir(int def_id); 199 bool IsHover(int def_id); 200 bool IsSea(int def_id); 201 bool IsStatic(int def_id); 202 203 bool CanMoveLand(int def_id); 204 bool CanMoveWater(int def_id); 205 206 bool CanPlacedLand(int def_id); 207 bool CanPlacedWater(int def_id); 208 209 // returns id of assault category 210 int GetIDOfAssaultCategory(UnitCategory category); 211 UnitCategory GetAssaultCategoryOfID(int id); 212 213 214 // 215 // these data are shared by several instances of aai 216 // 217 218 // number of assault categories 219 static const int ass_categories = 5; 220 221 // number of assault cat + arty & stat defences 222 static const int combat_categories = 6; 223 224 // path/name of the file in which AAI stores the build table 225 static char buildtable_filename[500]; 226 227 // cached values of average costs and buildtime 228 static vector<vector<float>> avg_cost; 229 static vector<vector<float>> avg_buildtime; 230 static vector<vector<float>> avg_value; // used for different things, range of weapons, radar range, mex efficiency 231 static vector<vector<float>> max_cost; 232 static vector<vector<float>> max_buildtime; 233 static vector<vector<float>> max_value; 234 static vector<vector<float>> min_cost; 235 static vector<vector<float>> min_buildtime; 236 static vector<vector<float>> min_value; 237 238 static vector<vector<float>> avg_speed; 239 static vector<vector<float>> min_speed; 240 static vector<vector<float>> max_speed; 241 static vector<vector<float>> group_speed; 242 243 // combat categories that attacked AI in certain game period attacked_by_category_learned[map_type][period][cat] 244 static vector< vector< vector<float> > > attacked_by_category_learned; 245 246 // combat categories that attacked AI in certain game period attacked_by_category_current[period][cat] 247 static vector< vector<float> > attacked_by_category_current; 248 249 // units of the different categories 250 static vector<vector<list<int>>> units_of_category; 251 252 // AAI unit defs (static things like id, side, etc.) 253 static vector<UnitTypeStatic> units_static; 254 255 // storage for def. building selection 256 static vector<vector<double> > def_power; 257 static vector<double> max_pplant_eff; 258 259 // cached combat efficiencies 260 static vector< vector< vector<float> > > avg_eff; 261 static vector< vector< vector<float> > > max_eff; 262 static vector< vector< vector<float> > > min_eff; 263 static vector< vector< vector<float> > > total_eff; 264 265 // stores the combat eff. of units at the beginning of the game. due to learning these values will change during the game 266 // however for some purposes its necessary to have constant values (e.g. adding and subtracting stationary defences to/from the defense map) 267 static vector< vector<float> > fixed_eff; 268 269 // 270 // non static variales 271 // 272 273 // number of sides 274 int numOfSides; 275 276 // side names 277 vector<string> sideNames; 278 279 // start units of each side (e.g. commander) 280 vector<int> startUnits; 281 282 283 vector<float> combat_eff; 284 285 // true if initialized correctly 286 bool initialized; 287 288 289 // AAI unit defs with aai-instance specific information (number of requested, active units, etc.) 290 vector<UnitTypeDynamic> units_dynamic; 291 292 // for internal use 293 const char* GetCategoryString(int def_id); 294 const char* GetCategoryString2(UnitCategory category); 295 296 // all assault unit categories 297 list<UnitCategory> assault_categories; 298 GetUnitDef(int i)299 const UnitDef& GetUnitDef(int i) { assert(IsValidUnitDefID(i)); return *unitList[i];} IsValidUnitDefID(int i)300 bool IsValidUnitDefID(int i) { return (i>=0) && (i<=unitList.size()); } 301 private: 302 std::string GetBuildCacheFileName(); 303 // precaches speed/cost/buildtime/range stats 304 void PrecacheStats(); 305 306 // only precaches costs (called after possible cost multipliers have been assigned) 307 void PrecacheCosts(); 308 309 // returns side of a unit 310 int GetSide(int unit); 311 312 // returns true, if unitid is in the list 313 bool MemberOf(int unit_id, list<int> unit_list); 314 // for internal use 315 void CalcBuildTree(int unit); 316 bool LoadBuildTable(); 317 float GetUnitRating(int unit, float ground_eff, float air_eff, float hover_eff, float sea_eff, float submarine_eff); 318 void DebugPrint(); 319 320 AAI * ai; 321 322 // FILE *file; 323 324 // all the unit defs, FIXME: this can't be made static as spring seems to free the memory returned by GetUnitDefList() 325 std::vector<const UnitDef*> unitList; 326 }; 327 328 #endif 329 330