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
|
/*
* Nullkiller.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "PriorityEvaluator.h"
#include "FuzzyHelper.h"
#include "Settings.h"
#include "AIMemory.h"
#include "DeepDecomposer.h"
#include "../Analyzers/DangerHitMapAnalyzer.h"
#include "../Analyzers/BuildAnalyzer.h"
#include "../Analyzers/ArmyManager.h"
#include "../Analyzers/HeroManager.h"
#include "../Analyzers/ObjectClusterizer.h"
#include "../Helpers/ArmyFormation.h"
VCMI_LIB_NAMESPACE_BEGIN
class PathfinderCache;
VCMI_LIB_NAMESPACE_END
namespace NKAI
{
const float MIN_PRIORITY = 0.01f;
const float SMALL_SCAN_MIN_PRIORITY = 0.4f;
enum class HeroLockedReason
{
NOT_LOCKED = 0,
STARTUP = 1,
DEFENCE = 2,
HERO_CHAIN = 3
};
enum class ScanDepth
{
MAIN_FULL = 0,
SMALL = 1,
ALL_FULL = 2
};
struct TaskPlanItem
{
std::vector<ObjectInstanceID> affectedObjects;
Goals::TSubgoal task;
TaskPlanItem(Goals::TSubgoal goal);
};
class TaskPlan
{
private:
std::vector<TaskPlanItem> tasks;
public:
Goals::TTaskVec getTasks() const;
void merge(Goals::TSubgoal task);
};
class Nullkiller
{
private:
const CGHeroInstance * activeHero;
int3 targetTile;
ObjectInstanceID targetObject;
std::map<const CGHeroInstance *, HeroLockedReason> lockedHeroes;
std::unique_ptr<PathfinderCache> pathfinderCache;
ScanDepth scanDepth;
TResources lockedResources;
bool useHeroChain;
AIGateway * gateway;
bool openMap;
bool useObjectGraph;
bool pathfinderInvalidated;
public:
static std::unique_ptr<ObjectGraph> baseGraph;
std::unique_ptr<DangerHitMapAnalyzer> dangerHitMap;
std::unique_ptr<BuildAnalyzer> buildAnalyzer;
std::unique_ptr<ObjectClusterizer> objectClusterizer;
std::unique_ptr<PriorityEvaluator> priorityEvaluator;
std::unique_ptr<SharedPool<PriorityEvaluator>> priorityEvaluators;
std::unique_ptr<AIPathfinder> pathfinder;
std::unique_ptr<HeroManager> heroManager;
std::unique_ptr<ArmyManager> armyManager;
std::unique_ptr<AIMemory> memory;
std::unique_ptr<FuzzyHelper> dangerEvaluator;
std::unique_ptr<DeepDecomposer> decomposer;
std::unique_ptr<ArmyFormation> armyFormation;
std::unique_ptr<Settings> settings;
PlayerColor playerID;
std::shared_ptr<CCallback> cb;
std::mutex aiStateMutex;
Nullkiller();
~Nullkiller();
void init(std::shared_ptr<CCallback> cb, AIGateway * gateway);
void makeTurn();
bool isActive(const CGHeroInstance * hero) const { return activeHero == hero; }
bool isHeroLocked(const CGHeroInstance * hero) const;
HeroPtr getActiveHero() { return activeHero; }
HeroLockedReason getHeroLockedReason(const CGHeroInstance * hero) const;
int3 getTargetTile() const { return targetTile; }
ObjectInstanceID getTargetObject() const { return targetObject; }
void setTargetObject(int objid) { targetObject = ObjectInstanceID(objid); }
void setActive(const CGHeroInstance * hero, int3 tile) { activeHero = hero; targetTile = tile; }
void lockHero(const CGHeroInstance * hero, HeroLockedReason lockReason) { lockedHeroes[hero] = lockReason; }
void unlockHero(const CGHeroInstance * hero) { lockedHeroes.erase(hero); }
bool arePathHeroesLocked(const AIPath & path) const;
TResources getFreeResources() const;
int32_t getFreeGold() const { return getFreeResources()[EGameResID::GOLD]; }
void lockResources(const TResources & res);
const TResources & getLockedResources() const { return lockedResources; }
ScanDepth getScanDepth() const { return scanDepth; }
bool isOpenMap() const { return openMap; }
bool isObjectGraphAllowed() const { return useObjectGraph; }
bool handleTrading();
void invalidatePathfinderData();
std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h) const;
void invalidatePaths();
private:
void resetAiState();
void updateAiState(int pass, bool fast = false);
void decompose(Goals::TGoalVec & result, Goals::TSubgoal behavior, int decompositionMaxDepth) const;
Goals::TTask choseBestTask(Goals::TGoalVec & tasks) const;
Goals::TTaskVec buildPlan(Goals::TGoalVec & tasks, int priorityTier) const;
bool executeTask(Goals::TTask task);
bool areAffectedObjectsPresent(Goals::TTask task) const;
HeroRole getTaskRole(Goals::TTask task) const;
};
}
|