File: AAIMap.h

package info (click to toggle)
spring 105.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,860 kB
  • sloc: cpp: 467,785; ansic: 302,607; python: 12,925; java: 12,201; awk: 5,889; sh: 2,371; xml: 655; perl: 405; php: 276; objc: 194; makefile: 75; sed: 2
file content (317 lines) | stat: -rw-r--r-- 13,579 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------

#ifndef AAI_MAP_H
#define AAI_MAP_H

#include "aidef.h"
#include "AAITypes.h"
#include "AAIMapRelatedTypes.h"
#include "AAIMapTypes.h"
#include "AAIUnitTypes.h"
#include "AAISector.h"
#include "System/float3.h"

#include <vector>
#include <list>
#include <string>
using namespace std;

class AAI;

namespace springLegacyAI {
	struct UnitDef;
}
using namespace springLegacyAI;

class AAIMap
{
	friend AAIScoutedUnitsMap;

public:
	AAIMap(AAI *ai);
	~AAIMap(void);

	void Init();

	//! @brief Returns the map type
	const AAIMapType& GetMapType() const { return s_mapType; }

	//! @brief Returns max distance (in sectors) a sector can have to base
	int GetMaxSectorDistanceToBase() const { return (xSectors + ySectors - 2); }

	//! @brief Returns the approximated map coordinates of the center of the enemy base (determined based on scouted enemy buildings)
	const MapPos& GetCenterOfEnemyBase() const { return m_centerOfEnemyBase; }

	//! @brief Returns the distance to the estimated center of enemy base
	float GetDistanceToCenterOfEnemyBase(const float3& position) const;

	//! @brief Converts given position to final building position for the given unit type
	void Pos2FinalBuildPos(float3 *pos, const UnitDef *def) const;

	//! @brief Returns whether x/y specify a valid sector
	bool IsValidSector(int x, int y) const { return( (x >= 0) && (y >= 0) && (x < xSectors) && (y < ySectors) ); }

	//! @brief Returns true if the given sector is a neighbour to the current base
	bool IsSectorBorderToBase(int x, int y) const;

	//! @brief Returns continent id with respect to the unit's movement type (e.g. ground (=non amphibious) unit being in shallow water will return id of nearest land continent)
	int DetermineSmartContinentID(float3 pos, const AAIMovementType& moveType) const;

	//! @brief Returns whether continent to which given sector mainly belongs is sea 
	bool IsSectorOnWaterContinent(const AAISector* sector) const { return s_continents[sector->GetContinentID()].water; }

	//! @brief Returns whether the position is located on a small continent (meant to detect "ponds" or "small islands")
	bool LocatedOnSmallContinent(const float3& pos) const { return (s_continents[s_continentMap.GetContinentID(pos)].size < (avg_land_continent_size + avg_water_continent_size)/4); }

	//! @brief Returns the id of continent the given position belongs to
	static int GetContinentID(const float3& pos) { return s_continentMap.GetContinentID(pos); }

	//! @brief Returns the number of continents
	static int GetNumberOfContinents() { return s_continents.size(); }

	//! @brief Determines the total number of spotted (= currently known) enemy buildings on land / sea
	void DetermineSpottedEnemyBuildingsOnContinentType(int& enemyBuildingsOnLand, int& enemyBuildingsOnSea) const;

	//! @brief Returns a bitmask storing which movement types are suitable for the map type
	uint32_t GetSuitableMovementTypesForMap() const { return GetSuitableMovementTypes(s_mapType); }

	//! @brief Returns the sector in which the given position lies (nullptr if out of sector map -> e.g. aircraft flying outside of the map) 
	AAISector* GetSectorOfPos(const float3& pos);

	//! @brief Returns distance to closest edge of the map (in unit map coordinates)
	float GetEdgeDistance(const float3& pos) const;

	//! @brief Returns the maximum number of units lost in any sector of the map
	float GetMaximumNumberOfLostUnits() const;

	float3 GetRandomBuildsite(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, int tries, bool water = false);

	//!  @brief Searches for a buildiste in given sector starting from top left corner 
	float3 DetermineBuildsiteInSector(UnitDefId buildingDefId, const AAISector* sector) const;

	// prefer buildsites that are on plateus and not too close to the edge of the map
	float3 GetRadarArtyBuildsite(const UnitDef *def, int xStart, int xEnd, int yStart, int yEnd, float range, bool water);

	//! @brief Determines the most suitable buidliste for the given static defence in the given sector (returns ZeroVector if no buildsite found)
	float3 DetermineBuildsiteForStaticDefence(UnitDefId staticDefence, const AAISector* sector, const AAITargetType& targetType, float terrainModifier) const;

	//! @brief Updates buildmap & defence map (for static defences) and building data of target sector 
	//!        Return true if building will be placed at a valid position, i.e. inside sectors
	bool InitBuilding(const UnitDef *def, const float3& position);

	//! @brief Updates the buildmap: (un)block cells + insert/remove spaces (factory exits get some extra space)
	void UpdateBuildMap(const float3& buildPos, const UnitDef *def, bool block);

	// returns number of cells with big slope
	int GetCliffyCells(int xPos, int yPos, int xSize, int ySize) const;

	//! @brief Triggers an update of the current units in LOS if there are enough frames since the last update or it is enforced
	void CheckUnitsInLOSUpdate(bool forceUpdate = false);

	//! @brief Returns whether given position lies within current LOS
	bool IsPositionInLOS(const float3& position) const;

	//! @brief Returns whether given position lies within map (e.g. aircraft may leave map)
	bool IsPositionWithinMap(const float3& position) const;

	//! @brief Returns whether a water tile belonging to an ocean (i.e. large water continent) lies within the given rectangle
	bool IsConnectedToOcean(int xStart, int xEnd, int yStart, int yEnd) const;

	//! @brief Returns position of first enemy building found in the part of the map (in build map coordinates)
	float3 DeterminePositionOfEnemyBuildingInSector(int xStart, int xEnd, int yStart, int yEnd) const;

	//! @brief Decreases the lost units and updates the the "center of gravity" of the enemy base(s)
	void UpdateSectors();

	//! @brief Checks for new neighbours (and removes old ones if necessary)
	void UpdateNeighbouringSectors(std::vector< std::list<AAISector*> >& sectorsInDistToBase);

	//! @brief Adds or removes a defence buidling to/from the defence map
	void AddOrRemoveStaticDefence(const float3& position, UnitDefId defence, bool addDefence);

	//! @brief Determines to which location a given scout schould be sent to next
	float3 GetNewScoutDest(UnitId scoutUnitId);

	//! @brief Returns a sector to proceed with attack (nullptr if none found)
	const AAISector* DetermineSectorToContinueAttack(const AAISector *currentSector, const MobileTargetTypeValues& targetTypeOfUnits, AAIMovementType moveTypeOfUnits) const;

	//! @brief Returns the sector which is the highest rated attack target (or nullptr if none found)
	const AAISector* DetermineSectorToAttack(const std::vector<float>& globalCombatPower, const std::vector< std::vector<float> >& continentCombatPower, const MobileTargetTypeValues& assaultGroupsOfType) const;

	//! The sectors of the map
	std::vector< std::vector<AAISector> > m_sector;

	// used for scouting, used to get all friendly/enemy units in los
	std::vector<int> unitsInLOS;

	//! Maximum squared distance on map in unit coordinates (i.e. from one corner to the other, xSize*xSize+ySize*ySize)
	static float maxSquaredMapDist; 

	//! x and y size of the map (unit coordinates)
	static int xSize, ySize;

	//! x and y size of the map (map coordinates, i.e. map tiles)
	static int xMapSize, yMapSize;

	//! Number of sectors in x/y direction
	static int xSectors, ySectors;

	//! Size of sectors (in unit coordinates)
	static int xSectorSize, ySectorSize;

	//! Size of sectors (in map coordinates, i.e. tiles = 1/8 xSize/ySize)
	static int xSectorSizeMap, ySectorSizeMap;

	//! Ration of land tiles
	static float s_landTilesRatio;

	//! Ratio of water tiles
	static float s_waterTilesRatio;

	//! Number of metal spots in sea
	static int water_metal_spots;

	//! Number of metal spots on land
	static int land_metal_spots;

	//! Indicates if map is considered to be a metal map (i.e. exctractors can be built anywhere)
	static bool metalMap;
	
	//! The map storing which sector has been occupied by what team
	static AAITeamSectorMap s_teamSectorMap;

	//! The buildmap stores the type/occupation status of every cell;
	static std::vector<BuildMapTileType> s_buildmap;

	static int avg_water_continent_size;

	static constexpr int ignoreContinentID = -1;

private:
	//! @brief Updates spotted enemy buildings/units on the map (incl. data per sector)
	void UpdateEnemyUnitsInLOS();

	//! @brief Updates own/allied buildings/units on the map (in each sector)
	void UpdateFriendlyUnitsInLos();

	//! @brief Updates enemy buildings/enemy combat power in sectors based on scout map entris updated by UpdateEnemyUnitsInLOS()
	void UpdateEnemyScoutingData();

	//! @brief Converts the given position (in map coordinates) to a position in buildmap coordinates
	void Pos2BuildMapPos(float3* position, const UnitDef* def) const;

	// krogothe's metal spot finder
	void DetectMetalSpots();

	//! @brief Returns descriptor for map type (used to save map type)
	const char* GetMapTypeString(const AAIMapType& mapType) const;

	//! @brief Returns which movement types are suitable for the given map type
	uint32_t GetSuitableMovementTypes(const AAIMapType& mapType) const;

	//! @brief Determine the type of every map tile (e.g. water, flat. cliff) and calculates the plateue map
	void AnalyseMap();

	//! @brief Determines the type of map
	void DetermineMapType();

	// calculates learning effect
	void Learn();

	//! @brief Read the learning data for this map (or initialize with defualt data if none are available)
	void ReadMapLearnFile();

	// reads continent cache file (and creates new one if necessary)
	void ReadContinentFile();

	// reads map cache file (and creates new one if necessary)
	// loads mex spots, cliffs etc. from file or creates new one
	void ReadMapCacheFile();

	//! @brief Returns true if buildmap allows construction of unit with given footprint at goven position
	bool CanBuildAt(int xPos, int yPos, const UnitFootprint& size, bool water = false) const;

	//! @brief Blocks/unblocks map tiles (to prevent AAI from packing buildings too close to each other)
	//!        Automatically clamps given values to map size (avoids running over any map edges)
	void BlockTiles(int xPos, int yPos, int width, int height, bool block);

	//! @brief Prevents AAI from building too many buildings in a row by adding blocking spaces if necessary
	void CheckRows(int xPos, int yPos, int xSize, int ySize, bool add);

	//! @brief Returns the size which is needed for this building (building size + exit for factories)
	UnitFootprint DetermineRequiredFreeBuildspace(UnitDefId unitDefId) const;

	//! @brief Returns distance to closest edge of the map (in build_map coordinates)
	int GetEdgeDistance(int xPos, int yPos) const;

	//! @brief Occupies/frees the given cells of the buildmap
	void ChangeBuildMapOccupation(int xPos, int yPos, int xSize, int ySize, bool occupy);

public:
	void BuildMapPos2Pos(float3 *pos, const UnitDef* def) const;

private:
	std::string LocateMapLearnFile() const;
	std::string LocateMapCacheFile() const;

	AAI *ai;

	//! Stores the defId of the building or combat unit placed on that cell (0 if none), same resolution as los map
	AAIScoutedUnitsMap m_scoutedEnemyUnitsMap;

	//! The number of scouted enemy units on the given continent
	std::vector<int> m_buildingsOnContinent;

	//! Approximate center of enemy base in build map coordinates (not reliable if enemy buldings are spread over map)
	MapPos m_centerOfEnemyBase;

	//! The frame in which the last update of the units in LOS has been performed
	int m_lastLOSUpdateInFrame;

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// static (shared with other ai players)
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////

	//! The defence maps (storing combat power by static defences vs the different mobile target types)
	static AAIDefenceMaps s_defenceMaps;

	//! Stores the id of the continent every tiles belongs to and additional information about continents
	static AAIContinentMap s_continentMap;

	//! An array storing the detected continents on the map
	static std::vector<AAIContinent> s_continents;

	//! The map type
	static AAIMapType s_mapType;

	static int losMapRes;				// resolution of the LOS map
	static int xLOSMapSize, yLOSMapSize;		// x and y size of the LOS map
	static int xDefMapSize, yDefMapSize;		// x and y size of the defence maps (1/4 resolution of map)
	static std::list<AAIMetalSpot> metal_spots;
	static float flat_land_ratio;
	static vector<int> blockmap;		// number of buildings which ordered a cell to blocked
	static vector<float> plateau_map;	// positive values indicate plateaus, same resolution as continent map 1/4 of resolution of blockmap/buildmap

	static vector<int> ship_movement_map;	// movement maps for different categories, 1/4 of resolution of blockmap/buildmap
	static vector<int> kbot_movement_map;
	static vector<int> vehicle_movement_map;
	static vector<int> hover_movement_map;
	static int land_continents;
	static int water_continents;

	static int avg_land_continent_size;
	static int max_land_continent_size;
	static int max_water_continent_size;
	static int min_land_continent_size;
	static int min_water_continent_size;
};

#endif