mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-15 13:33:36 +02:00
Nullkiller: turn limit for main heroes
This commit is contained in:
parent
1f83569868
commit
0ffc7c3b94
@ -104,6 +104,7 @@ Goals::TTask Nullkiller::choseBestTask(Goals::TSubgoal behavior, int decompositi
|
||||
|
||||
void Nullkiller::resetAiState()
|
||||
{
|
||||
scanDepth = ScanDepth::SMALL;
|
||||
playerID = ai->playerID;
|
||||
lockedHeroes.clear();
|
||||
dangerHitMap->reset();
|
||||
@ -140,6 +141,11 @@ void Nullkiller::updateAiState(int pass)
|
||||
cfg.useHeroChain = true;
|
||||
cfg.scoutTurnDistanceLimit = SCOUT_TURN_DISTANCE_LIMIT;
|
||||
|
||||
if(scanDepth != ScanDepth::FULL)
|
||||
{
|
||||
cfg.mainTurnDistanceLimit = MAIN_TURN_DISTANCE_LIMIT * ((int)scanDepth + 1);
|
||||
}
|
||||
|
||||
pathfinder->updatePaths(activeHeroes, cfg);
|
||||
|
||||
armyManager->update();
|
||||
@ -215,6 +221,20 @@ void Nullkiller::makeTurn()
|
||||
}
|
||||
|
||||
Goals::TTask bestTask = choseBestTask(bestTasks);
|
||||
HeroPtr hero = bestTask->getHero();
|
||||
|
||||
if(bestTask->priority < NEXT_SCAN_MIN_PRIORITY
|
||||
&& hero.validAndSet()
|
||||
&& heroManager->getHeroRole(hero) == HeroRole::MAIN
|
||||
&& scanDepth != ScanDepth::FULL)
|
||||
{
|
||||
logAi->trace(
|
||||
"Goal %s has too low priority %f so increasing scan depth",
|
||||
bestTask->toString(),
|
||||
bestTask->priority);
|
||||
scanDepth = (ScanDepth)((int)scanDepth + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(bestTask->priority < MIN_PRIORITY)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
const float MAX_GOLD_PEASURE = 0.3f;
|
||||
const float MIN_PRIORITY = 0.01f;
|
||||
const float NEXT_SCAN_MIN_PRIORITY = 0.4f;
|
||||
|
||||
enum class HeroLockedReason
|
||||
{
|
||||
@ -33,12 +34,22 @@ enum class HeroLockedReason
|
||||
HERO_CHAIN = 3
|
||||
};
|
||||
|
||||
enum class ScanDepth
|
||||
{
|
||||
SMALL = 0,
|
||||
|
||||
MEDIUM = 1,
|
||||
|
||||
FULL = 2
|
||||
};
|
||||
|
||||
class Nullkiller
|
||||
{
|
||||
private:
|
||||
const CGHeroInstance * activeHero;
|
||||
int3 targetTile;
|
||||
std::map<const CGHeroInstance *, HeroLockedReason> lockedHeroes;
|
||||
ScanDepth scanDepth;
|
||||
|
||||
public:
|
||||
std::unique_ptr<DangerHitMapAnalyzer> dangerHitMap;
|
||||
|
@ -74,7 +74,6 @@ namespace Goals
|
||||
public:
|
||||
bool operator==(const TSubgoal & rhs) const;
|
||||
bool operator<(const TSubgoal & rhs) const;
|
||||
//TODO: serialize?
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ITask> TTask;
|
||||
@ -108,7 +107,6 @@ namespace Goals
|
||||
const CGTownInstance *town; VSETTER(CGTownInstance *, town)
|
||||
int bid; VSETTER(int, bid)
|
||||
TSubgoal parent; VSETTER(TSubgoal, parent)
|
||||
//EvaluationContext evaluationContext; VSETTER(EvaluationContext, evaluationContext)
|
||||
|
||||
AbstractGoal(EGoals goal = EGoals::INVALID)
|
||||
: goalType(goal), hero()
|
||||
@ -185,6 +183,7 @@ namespace Goals
|
||||
//TODO: make accept work for std::shared_ptr... somehow
|
||||
virtual void accept(VCAI * ai) = 0; //unhandled goal will report standard error
|
||||
virtual std::string toString() const = 0;
|
||||
virtual HeroPtr getHero() const = 0;
|
||||
virtual ~ITask() {}
|
||||
};
|
||||
}
|
||||
|
@ -97,10 +97,9 @@ namespace Goals
|
||||
return *((T *)this);
|
||||
}
|
||||
|
||||
virtual bool isElementar() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool isElementar() const override { return true; }
|
||||
|
||||
virtual HeroPtr getHero() const override { return hero; }
|
||||
};
|
||||
|
||||
class DLL_EXPORT Invalid : public ElementarGoal<Invalid>
|
||||
|
@ -108,7 +108,8 @@ void AINodeStorage::clear()
|
||||
heroChainPass = EHeroChainPass::INITIAL;
|
||||
heroChainTurn = 0;
|
||||
heroChainMaxTurns = 1;
|
||||
scoutTurnDistanceLimit = 255;
|
||||
turnDistanceLimit[HeroRole::MAIN] = 255;
|
||||
turnDistanceLimit[HeroRole::SCOUT] = 255;
|
||||
}
|
||||
|
||||
const AIPathNode * AINodeStorage::getAINode(const CGPathNode * node) const
|
||||
@ -703,15 +704,10 @@ bool AINodeStorage::isDistanceLimitReached(const PathNodeInfo & source, CDestina
|
||||
|
||||
auto aiNode = getAINode(destination.node);
|
||||
|
||||
if(heroChainPass == EHeroChainPass::FINAL)
|
||||
if(heroChainPass != EHeroChainPass::CHAIN
|
||||
&& destination.node->turns > turnDistanceLimit[aiNode->actor->heroRole])
|
||||
{
|
||||
if(aiNode->actor->heroRole == HeroRole::SCOUT && destination.node->turns > scoutTurnDistanceLimit)
|
||||
return true;
|
||||
}
|
||||
else if(heroChainPass == EHeroChainPass::INITIAL)
|
||||
{
|
||||
if(aiNode->actor->heroRole == HeroRole::SCOUT && destination.node->turns > scoutTurnDistanceLimit)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define PATHFINDER_TRACE_LEVEL 0
|
||||
#define AI_TRACE_LEVEL 0
|
||||
#define SCOUT_TURN_DISTANCE_LIMIT 3
|
||||
#define MAIN_TURN_DISTANCE_LIMIT 5
|
||||
|
||||
#include "../../../lib/CPathfinder.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
@ -147,7 +148,7 @@ private:
|
||||
int heroChainTurn;
|
||||
int heroChainMaxTurns;
|
||||
PlayerColor playerID;
|
||||
uint8_t scoutTurnDistanceLimit;
|
||||
uint8_t turnDistanceLimit[2];
|
||||
|
||||
public:
|
||||
/// more than 1 chain layer for each hero allows us to have more than 1 path to each tile so we can chose more optimal one.
|
||||
@ -204,7 +205,8 @@ public:
|
||||
std::vector<AIPath> getChainInfo(const int3 & pos, bool isOnLand) const;
|
||||
bool isTileAccessible(const HeroPtr & hero, const int3 & pos, const EPathfindingLayer layer) const;
|
||||
void setHeroes(std::map<const CGHeroInstance *, HeroRole> heroes);
|
||||
void setScoutTurnDistanceLimit(uint8_t distanceLimit) { scoutTurnDistanceLimit = distanceLimit; }
|
||||
void setScoutTurnDistanceLimit(uint8_t distanceLimit) { turnDistanceLimit[HeroRole::SCOUT] = distanceLimit; }
|
||||
void setMainTurnDistanceLimit(uint8_t distanceLimit) { turnDistanceLimit[HeroRole::MAIN] = distanceLimit; }
|
||||
void setTownsAndDwellings(
|
||||
const std::vector<const CGTownInstance *> & towns,
|
||||
const std::set<const CGObjectInstance *> & visitableObjs);
|
||||
|
@ -56,6 +56,7 @@ void AIPathfinder::updatePaths(std::map<const CGHeroInstance *, HeroRole> heroes
|
||||
storage->clear();
|
||||
storage->setHeroes(heroes);
|
||||
storage->setScoutTurnDistanceLimit(pathfinderSettings.scoutTurnDistanceLimit);
|
||||
storage->setMainTurnDistanceLimit(pathfinderSettings.mainTurnDistanceLimit);
|
||||
|
||||
if(pathfinderSettings.useHeroChain)
|
||||
{
|
||||
|
@ -19,10 +19,12 @@ struct PathfinderSettings
|
||||
{
|
||||
bool useHeroChain;
|
||||
uint8_t scoutTurnDistanceLimit;
|
||||
uint8_t mainTurnDistanceLimit;
|
||||
|
||||
PathfinderSettings()
|
||||
:useHeroChain(false),
|
||||
scoutTurnDistanceLimit(255)
|
||||
scoutTurnDistanceLimit(255),
|
||||
mainTurnDistanceLimit(255)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user