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
|
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------
#ifndef AAI_UNITTABLE_H
#define AAI_UNITTABLE_H
#include <set>
#include "aidef.h"
#include "AAIBuildTable.h"
class AAI;
class AAIExecute;
class AAIConstructor;
//! Used to store the information of a construction unit that is currently available
class AvailableConstructor
{
public:
AvailableConstructor(AAIConstructor* constructor, float travelTimeToBuildSite) : m_constructor(constructor), m_travelTimeToBuildSite(travelTimeToBuildSite) {}
AvailableConstructor() : AvailableConstructor(nullptr, 0.0f) {}
void SetAvailableConstructor(AAIConstructor* constructor, float travelTimeToBuildSite)
{
m_constructor = constructor;
m_travelTimeToBuildSite = travelTimeToBuildSite;
}
bool IsValid() const { return m_constructor != nullptr; }
AAIConstructor* Constructor() const { return m_constructor; }
float TravelTimeToBuildSite() const { return m_travelTimeToBuildSite; }
private:
AAIConstructor* m_constructor;
float m_travelTimeToBuildSite;
};
class AAIUnitTable
{
public:
AAIUnitTable(AAI *ai);
~AAIUnitTable(void);
//! @brief Returns the number of active (i.e. not under construction anymore) units of the given category
int GetNumberOfActiveUnitsOfCategory(const AAIUnitCategory& category) const { return m_activeUnitsOfCategory[category.GetArrayIndex()]; };
//! @brief Returns the number of units under construction of the given category
int GetNumberOfUnitsUnderConstructionOfCategory(const AAIUnitCategory& category) const { return m_underConstructionUnitsOfCategory[category.GetArrayIndex()]; };
//! @brief Returns the number of requested (i.e. construction has not started yet) units of the given category
int GetNumberOfRequestedUnitsOfCategory(const AAIUnitCategory& category) const { return m_requestedUnitsOfCategory[category.GetArrayIndex()]; };
//! @brief Returns the number of units requested or under construction of the given category
int GetNumberOfFutureUnitsOfCategory(const AAIUnitCategory& category) const { return ( m_requestedUnitsOfCategory[category.GetArrayIndex()]
+ m_underConstructionUnitsOfCategory[category.GetArrayIndex()]); };
//! @brief Returns the number of units of the given category that are active, requested or under construction
int GetTotalNumberOfUnitsOfCategory(const AAIUnitCategory& category) const { return ( m_requestedUnitsOfCategory[category.GetArrayIndex()]
+ m_underConstructionUnitsOfCategory[category.GetArrayIndex()]
+ m_activeUnitsOfCategory[category.GetArrayIndex()]); };
//! @brief Returns the UnitDefId of the given (own) unit
UnitDefId GetUnitDefId(UnitId unitId) const { return UnitDefId(units[unitId.id].def_id); }
bool AddUnit(int unit_id, int def_id, AAIGroup *group = 0, AAIConstructor *cons = 0);
void RemoveUnit(int unit_id);
void AddScout(int unit_id);
void RemoveScout(int unit_id);
void AddConstructor(UnitId unitId, UnitDefId unitDefId);
void RemoveConstructor(UnitId unitId, UnitDefId unitDefId);
const std::set<UnitId>& GetConstructors() const { return m_constructors; }
void AddExtractor(int unit_id);
void RemoveExtractor(int unit_id);
void AddPowerPlant(UnitId unitId, UnitDefId unitDefId);
void RemovePowerPlant(int unit_id);
void AddMetalMaker(int unit_id, int def_id);
void RemoveMetalMaker(int unit_id);
void AddJammer(int unit_id, int def_id);
void RemoveJammer(int unit_id);
void AddStaticSensor(UnitId unitId);
void RemoveStaticSensor(UnitId unitId);
const std::set<UnitId>& GetStaticSensors() const { return m_staticSensors; }
void AddStationaryArty(int unit_id, int def_id);
void RemoveStationaryArty(int unit_id);
//! @brief Returns the number of active builders (incl. commander)
int GetNumberOfActiveBuilders() const { return m_activeUnitsOfCategory[AAIUnitCategory(EUnitCategory::COMMANDER).GetArrayIndex()] + m_activeUnitsOfCategory[AAIUnitCategory(EUnitCategory::MOBILE_CONSTRUCTOR).GetArrayIndex()]; }
//! @brief Returns any available builder for the given unit
AAIConstructor* FindBuilder(UnitDefId building, bool commander);
//! @brief Finds the closest builder and stores the time it needs to reach the given positon
AvailableConstructor FindClosestBuilder(UnitDefId building, const float3& position, bool commander);
//! @brief Finds the closests assistance suitable to assist cosntruction at given position (nullptr if none found)
AAIConstructor* FindClosestAssistant(const float3& pos, int importance, bool commander);
void EnemyKilled(int unit);
void SetUnitStatus(int unit, UnitTask status);
//! @brief Sets the given (enemy) unit as target for the given group (to allow targeting of next unit when enemy is destroyed)
void SetEnemyUnitAsTargetOfGroup(UnitId unitId, AAIGroup *group);
//! @brief Shall be called when unit have been requested (i.e. added to buildqueue)
void UnitRequested(const AAIUnitCategory& category, int number = 1);
// called when unit request failed (e.g. builder has been killed on the way to the crash site)
void UnitRequestFailed(const AAIUnitCategory& category);
// called when unit of specified catgeory has been created (= construction started)
void ConstructionStarted(const AAIUnitCategory& category);
//! @brief Shall be called when a unit under construction has been killed to update internal counters
void UnitUnderConstructionKilled(const AAIUnitCategory& category);
//! @brief Shall be called when construction of unit has been finished
void UnitFinished(const AAIUnitCategory& category);
//! @brief Shall be called when an active (i.e. construction finished) unit has been killed to update internal counters
void ActiveUnitKilled(const AAIUnitCategory& category);
//! @brief Calls the update() fucntion for every active constructor (e.g. looks for assistants for constructions, checks if factories are idle, ...)
void UpdateConstructors();
//! @brief Checks if a given enemy unit may be added as target for bombers (only enemy buildings will be considered)
void CheckBombTarget(UnitId unitId, UnitDefId defId, const AAIUnitCategory& category, const float3& position);
AAIUnit& GetUnit(UnitId unitId) { return units[unitId.id]; }
// units[i].unitId = -1 -> not used , -2 -> enemy unit
std::vector<AAIUnit> units;
std::set<int> metal_makers;
std::set<int> jammers;
// number of active/under construction units of all different types
int activeFactories, futureFactories;
private:
//! Number of active (i.e. not under construction anymore) units of each unit category
std::vector<int> m_activeUnitsOfCategory;
//! Number of units under contsruction of each unit category
std::vector<int> m_underConstructionUnitsOfCategory;
//! Number of requested units (i.e. construction has not started yet) of each unit category
std::vector<int> m_requestedUnitsOfCategory;
std::set<int> scouts;
std::set<int> extractors;
std::set<int> power_plants;
std::set<int> stationary_arty;
//! A list of all constructors (mobile and static)
std::set<UnitId> m_constructors;
//! A list of all static sensors (radar, seismic, jammer)
std::set<UnitId> m_staticSensors;
AAI *ai;
};
#endif
|