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_MAP_H 11 #define AAI_MAP_H 12 13 #include "aidef.h" 14 #include "System/float3.h" 15 16 #include <vector> 17 #include <list> 18 using namespace std; 19 20 class AAIBuildTable; 21 class AAI; 22 class AAISector; 23 24 namespace springLegacyAI { 25 struct UnitDef; 26 } 27 using namespace springLegacyAI; 28 29 struct AAIContinent 30 { 31 int id; 32 int size; // number of cells 33 bool water; 34 }; 35 36 class AAIMap 37 { 38 public: 39 AAIMap(AAI *ai); 40 ~AAIMap(void); 41 42 void Init(); 43 void Pos2FinalBuildPos(float3 *pos, const UnitDef *def); 44 45 // returns id of continent the cell belongs to 46 int GetContinentID(int x, int y); 47 int GetContinentID(float3 *pos); 48 49 // returns true if pos is located on s small continent (= pond or island) 50 bool LocatedOnSmallContinent(float3 *pos); 51 52 // returns continent id with respect to the units movement type (e.g. land, non amphib unit being in shallow water will return id of nearest land continent) 53 int GetSmartContinentID(float3 *pos, unsigned int unit_movement_type); 54 55 56 // returns sector (0 if out of sector map -> e.g. aircraft flying outside of the map) of a position 57 AAISector* GetSectorOfPos(float3 *pos); 58 59 60 float GetEdgeDistance(float3 *pos); 61 62 // returns buildsites for normal and defence buildings 63 float3 GetHighestBuildsite(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd); 64 float3 GetCenterBuildsite(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, bool water = false); 65 float3 GetRandomBuildsite(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, int tries, bool water = false); 66 float3 GetBuildSiteInRect(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, bool water = false); 67 68 // prefer buildsites that are on plateus and not too close to the edge of the map 69 float3 GetRadarArtyBuildsite(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, float range, bool water); 70 71 // return rating of a the best buidliste fpr a def. building vs category within specified rect (and stores pos in pointer) 72 float GetDefenceBuildsite(float3 *best_pos, const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, UnitCategory category, float terrain_modifier, bool water); 73 74 float3 GetClosestBuildsite(const UnitDef *def, float3 pos, int max_distance, bool water); 75 76 // updates buildmap ((un)block cells + insert/remove spaces) if regular building is added/removed (factories need some extra space) 77 void UpdateBuildMap(float3 build_pos, const UnitDef *def, bool block, bool water, bool factory); 78 79 // returns number of cells with big slope 80 int GetCliffyCells(int xPos, int yPos, int xSize, int ySize); 81 82 // updates spotted ennemy/ally buildings/units on the map 83 void UpdateRecon(); 84 85 // updates enemy buildings/enemy stat. combat strength in sectors based on scouted_buildings_map 86 void UpdateEnemyScoutingData(); 87 88 void UpdateSectors(); 89 90 91 // adds/removes a defence buidling to the defence map 92 void AddDefence(float3 *pos, int defence); 93 void RemoveDefence(float3 *pos, int defence); 94 95 // updates number of lost units in sector 96 void UnitKilledAt(float3 *pos, UnitCategory category); 97 98 // sectors 99 vector<vector<AAISector> > sector; 100 101 // used for scouting, used to get all friendly/enemy units in los 102 vector<int> units_in_los; 103 static int xMapSize, yMapSize; // x and y size of the map (map coordinates) 104 static int xSectors, ySectors; // number of sectors 105 static int xSectorSize, ySectorSize; // size of sectors (in unit pos coordinates) 106 static int xSectorSizeMap, ySectorSizeMap; // size of sectors (in map coodrinates = 1/8 xSize) 107 static float land_ratio; 108 static int water_metal_spots; 109 static int land_metal_spots; 110 static bool metalMap; 111 static float water_ratio; 112 static MapType map_type; // 0 -> unknown ,1-> land map (default), 2 -> air map, 113 // 3 -> water map with land connections 114 // 4 -> "full water map 115 116 static vector< vector<int> > team_sector_map; // stores the number of ai player which has taken that sector (-1 if none) 117 // this helps preventing aai from expanding into sectors of other aai players 118 119 120 static vector<int> buildmap; // map of the cells in the sector; 121 // 0 unoccupied, flat terrain 122 // 1 occupied flat terrain, 123 // 2 spaces between buildings 124 // 3 terrain not suitable for constr. 125 // 4 water 126 // 5 occupied water 127 static vector<AAIContinent> continents; 128 static int avg_water_continent_size; 129 static list<int> map_categories_id; 130 131 132 private: 133 // defence maps 134 vector<float> defence_map; // ground/sea defence map has 1/2 of resolution of blockmap/buildmap 135 vector<float> air_defence_map; // air defence map has 1/2 of resolution of blockmap/buildmap 136 vector<float> submarine_defence_map; // submarine defence map has 1/2 of resolution of blockmap/buildmap 137 // converts map-pos to unit-pos and vice versa 138 void Pos2BuildMapPos(float3 *pos, const UnitDef* def); 139 140 // stores the def_id of the building or combat unit placed on that cell (0 if none), same resolution as los map (= 1/2 resolution of buildmap) 141 vector<unsigned short> scout_map; 142 143 // stores the frame of the last update of a cell (same resolution as los map) 144 vector<int> last_updated_map; 145 146 // indicates whether sector is within los (to prevent unnecessary updates) 0 = no los, > 0 = los 147 vector<unsigned short> sector_in_los; 148 vector<unsigned short> sector_in_los_with_enemies; 149 150 // temp for scouting 151 vector<unsigned short> enemy_combat_units_spotted; 152 153 bool initialized; 154 // krogothe's metal spot finder 155 void SearchMetalSpots(); 156 // determines type of map (land, land/water or water map) 157 void DetectMapType(); 158 159 void CalculateWaterRatio(); 160 161 // calculates which parts of the are connected 162 void CalculateContinentMaps(); 163 164 // determines water, high slopes, defence map 165 void AnalyseMap(); 166 167 // calculates learning effect 168 void Learn(); 169 170 // if auto_set == true, the loaded values are assigned to the current sectordata as well 171 void ReadMapLearnFile(bool auto_set); 172 173 // reads continent cache file (and creates new one if necessary) 174 void ReadContinentFile(); 175 176 // reads map cache file (and creates new one if necessary) 177 // loads mex spots, cliffs etc. from file or creates new one 178 void ReadMapCacheFile(); 179 180 // returns true if buildmap allows construction 181 bool CanBuildAt(int xPos, int yPos, int xSize, int ySize, bool water = false); 182 183 // return next cell in direction with a certain value 184 int GetNextX(int direction, int xPos, int yPos, int value); // 0 means left, other right; returns -1 if not found 185 int GetNextY(int direction, int xPos, int yPos, int value); // 0 means up, other down; returns -1 if not found 186 187 const char* GetMapTypeString(MapType map_type); 188 189 const char* GetMapTypeTextString(MapType map_type); 190 191 int GetCliffyCellsInSector(AAISector *sector); 192 193 // blocks/unblocks cells (to prevent AAI from packing buildings too close to each other) 194 void BlockCells(int xPos, int yPos, int width, int height, bool block, bool water); 195 196 // prevents ai from building too many buildings in a row 197 void CheckRows(int xPos, int yPos, int xSize, int ySize, bool add, bool water); 198 199 // returns footprint size of a building 200 void GetSize(const UnitDef *def, int *xSize, int *ySize); 201 // returns distance to closest edge of the map (in build_map coordinates) 202 int GetEdgeDistance(int xPos, int yPos); 203 // true if x/y are a valid sector 204 bool ValidSector(int x, int y); 205 // sets cells of the builmap to value 206 bool SetBuildMap(int xPos, int yPos, int xSize, int ySize, int value, int ignore_value = -1); 207 208 void BuildMapPos2Pos(float3 *pos, const UnitDef* def); 209 210 std::string LocateMapLearnFile() const; 211 std::string LocateMapCacheFile() const; 212 213 AAI *ai; 214 215 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// 216 // static (shared with other ai players) 217 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// 218 219 static int aai_instances; // how many AAI instances have been initialized 220 221 static int xSize, ySize; // x and y size of the map (unit coordinates) 222 static int losMapRes; // resolution of the LOS map 223 static int xLOSMapSize, yLOSMapSize; // x and y size of the LOS map 224 static int xDefMapSize, yDefMapSize; // x and y size of the defence maps (1/4 resolution of map) 225 static int xContMapSize, yContMapSize; // x and y size of the continent maps (1/4 resolution of map) 226 static list<AAIMetalSpot> metal_spots; 227 static float flat_land_ratio; 228 static vector<int> blockmap; // number of buildings which ordered a cell to blocked 229 static vector<float> plateau_map; // positive values indicate plateaus, 1/4 of resolution of blockmap/buildmap 230 static vector<int> continent_map; // id of continent a cell belongs to 231 232 static vector<int> ship_movement_map; // movement maps for different categories, 1/4 of resolution of blockmap/buildmap 233 static vector<int> kbot_movement_map; 234 static vector<int> vehicle_movement_map; 235 static vector<int> hover_movement_map; 236 static int land_continents; 237 static int water_continents; 238 239 240 static int avg_land_continent_size; 241 static int max_land_continent_size; 242 static int max_water_continent_size; 243 static int min_land_continent_size; 244 static int min_water_continent_size; 245 246 static list<UnitCategory> map_categories; 247 }; 248 249 #endif 250 251