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
|
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------
#ifndef AAI_MAP_TYPES_H
#define AAI_MAP_TYPES_H
#include "AAIUnitTypes.h"
#include "AAISector.h"
#include "AAIMapRelatedTypes.h"
#include <vector>
//! The map storing which sector has been taken (as base) by which AAI team. Used to avoid that multiple AAI instances expand
//! into the same sector or build defences in the sector of an allied player.
class AAITeamSectorMap
{
public:
AAITeamSectorMap() {}
//! @brief Initializes all sectors as unoccupied
void Init(int xSectors, int ySectors) { m_teamMap.resize(xSectors, std::vector<int>(ySectors, sectorUnoccupied) ); }
//! Returns whether sector has been occupied by any AAI player (allied, enemy, or own instance)
bool IsSectorOccupied(const SectorIndex& sector) const { return (m_teamMap[sector.x][sector.y] != sectorUnoccupied); }
//! @brief Returns true is sector is occupied by given team
bool IsOccupiedByTeam(const SectorIndex& sector, int team) const { return (m_teamMap[sector.x][sector.y] == team); }
//! @brief Returns true if sector is occupied by a team other than the given one
bool IsOccupiedByOtherTeam(const SectorIndex& sector, int team) const { return (m_teamMap[sector.x][sector.y] != team) && (m_teamMap[sector.x][sector.y] != sectorUnoccupied);}
//! @brief Returns the team that currently occupied the given sector
int GetTeam(const SectorIndex& sector) const { return m_teamMap[sector.x][sector.y]; }
//! @brief Set sector as occupied by given (ally) team
void SetSectorAsOccupiedByTeam(const SectorIndex& sector, int team) { m_teamMap[sector.x][sector.y] = team; }
//! @brief Set sector as unoccupied
void SetSectorAsUnoccupied(const SectorIndex& sector) { m_teamMap[sector.x][sector.y] = sectorUnoccupied; }
private:
//! Stores the number of ai player which has taken that sector (-1 if none)
std::vector< std::vector<int> > m_teamMap;
//! Valuefor unoccupied sector
static constexpr int sectorUnoccupied = -1;
};
//! The defence map stores how well a certain map tile is covered by static defences
class AAIDefenceMaps
{
public:
//! @brief Initializes all sectors as unoccupied
void Init(int xMapSize, int yMapSize);
//! @brief Return the defence map value of a given map position
float GetValue(MapPos mapPosition, const AAITargetType& targetType) const
{
const int tileIndex = mapPosition.x/defenceMapResolution + m_xDefenceMapSize * (mapPosition.y/defenceMapResolution);
return m_defenceMaps[targetType.GetArrayIndex()][tileIndex];
}
//! @brief Modifies tiles within range of given position by combat power values
//! Used to add or remove defences
void ModifyTiles(const float3& position, float maxWeaponRange, const UnitFootprint& footprint, const TargetTypeValues& combatPower, bool addValues);
private:
//! @brief Adds combat power values to given tile
void AddDefence(int tile, const TargetTypeValues& combatPower);
//! @brief Removes combat power values to given tile
void RemoveDefence(int tile, const TargetTypeValues& combatPower);
//! The maps itself
std::vector< std::vector<float> > m_defenceMaps;
//! Horizontal size of the defence map
int m_xDefenceMapSize;
//! Vertical size of the defence map
int m_yDefenceMapSize;
//! Lower resolution factor with respect to map resolution
static constexpr int defenceMapResolution = 4;
};
//! This type is used to access a specific tile of a scout map
class ScoutMapTile
{
friend class AAIScoutedUnitsMap;
public:
ScoutMapTile(int tileIndex) : m_tileIndex(tileIndex) {}
bool IsValid() const { return (m_tileIndex >= 0); }
private:
//! The index of the tile
int m_tileIndex;
};
//! This map stores the id of scouted units
class AAIScoutedUnitsMap
{
public:
//! @brief Initializes all tiles as empty
AAIScoutedUnitsMap(int xMapSize, int yMapSize, int losMapResolution);
//! @brief Converts given build map coordinate to scout map coordinate
int BuildMapToScoutMapCoordinate(int buildMapCoordinate) const { return buildMapCoordinate/scoutMapResolution; }
//! @brief Converts given scout map coordinate to build map coordinate
int ScoutMapToBuildMapCoordinate(int scoutMapCoordinate) const { return scoutMapCoordinate*scoutMapResolution; }
//! @brief Returns id of unit at given tile
int GetUnitAt(int x, int y) const { return m_scoutedUnitsMap[x + y * m_xScoutMapSize]; }
int GetUnitAt(const ScoutMapTile& tile) const { return m_scoutedUnitsMap[tile.m_tileIndex]; }
//! @brief Adds unit to tile
void AddEnemyUnit(UnitDefId defId, ScoutMapTile tile) { m_scoutedUnitsMap[tile.m_tileIndex] = defId.id; }
//! @brief Erases the given tiles
void ResetTiles(int xLosMap, int yLosMap, int frame);
//! @brief Return tile index to corresponding position (int unit coordinates)
ScoutMapTile GetScoutMapTile(const float3& position) const
{
const int xPos = static_cast<int>(position.x) / (scoutMapResolution * SQUARE_SIZE);
const int yPos = static_cast<int>(position.z) / (scoutMapResolution * SQUARE_SIZE);
if( (xPos >= 0) && (xPos < m_xScoutMapSize) && (yPos >= 0) && (yPos < m_yScoutMapSize) )
return ScoutMapTile(xPos + yPos * m_xScoutMapSize);
else
return ScoutMapTile(-1);
}
//! @brief Updates the scouted units within the given sector
void UpdateSectorWithScoutedUnits(AAISector *sector, std::vector<int>& buildingsOnContinent, int currentFrame);
private:
//! Horizontal size of the scouted units map
int m_xScoutMapSize;
//! Vertical size of the scouted units map
int m_yScoutMapSize;
//! Factor how much larger the resolution of the scout map is compared to the LOS map
int m_losToScoutMapResolution;
//! Lower resolution factor with respect to map resolution
static constexpr int scoutMapResolution = 2;
//! The map containing the unit definition id of a scouted unit on occupying this tile (or 0 if none)
std::vector<int> m_scoutedUnitsMap;
//! The map storing the frame of the last update of each tile
std::vector<int> m_lastUpdateInFrameMap;
};
//! This class stores the continent map
class AAIContinentMap
{
public:
//! @brief Initializes all tiles as not belonging to any continent
void Init(int xMapSize, int yMapSize);
//! @brief Loads continent map from given file
void LoadFromFile(FILE* file);
//! @brief Stores continent map to given file
void SaveToFile(FILE* file);
//! @brief Returns the id of continent the cell belongs to
int GetContinentID(const MapPos& mapPosition) const { return m_continentMap[(mapPosition.y/continentMapResolution) * m_xContMapSize + mapPosition.x / continentMapResolution]; }
//! @brief Returns the id of continent the given position belongs to
int GetContinentID(const float3& pos) const;
//! @brief Returns the number of tiles of the continent map
int GetSize() const { return m_xContMapSize * m_yContMapSize; }
//! @brief Determines the continents, i.e. which parts of the map are connected
void DetectContinents(std::vector<AAIContinent>& continents, const float *heightMap, const int xMapSize, const int yMapSize);
private:
//! @brief Helper function for detection of continents - checks if a given tile belongs to a continent and sets values accordingly
void CheckIfTileBelongsToLandContinent(int continentMapTileIndex, float tileHeight, std::vector<AAIContinent>& continents, int continentId, std::vector<int>* nextEdgeCells);
//! @brief Helper function for detection of continents - checks if a given tile belongs to a sea continent and sets values accordingly
void CheckIfTileBelongsToSeaContinent(int continentMapTileIndex, float tileHeight, std::vector<AAIContinent>& continents, int continentId, std::vector<int>* nextEdgeCells);
//! Id of continent a map tile belongs to
std::vector<int> m_continentMap;
//! x size of the continent map (1/4 resolution of map)
int m_xContMapSize;
//! y size of the continent map (1/4 resolution of map)
int m_yContMapSize;
//! Lower resolution factor with respect to map resolution
static constexpr int continentMapResolution = 4;
};
#endif
|