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