mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
AI/Nullkiller/Behaviors/DefenceBehavior.{h,cpp}: treat -> threat
This commit is contained in:
parent
457e73ed12
commit
0a6c82c639
@ -15,7 +15,7 @@
|
|||||||
namespace NKAI
|
namespace NKAI
|
||||||
{
|
{
|
||||||
|
|
||||||
HitMapInfo HitMapInfo::NoTreat;
|
HitMapInfo HitMapInfo::NoThreat;
|
||||||
|
|
||||||
double HitMapInfo::value() const
|
double HitMapInfo::value() const
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@ void DangerHitMapAnalyzer::updateHitMap()
|
|||||||
hitMap.resize(boost::extents[mapSize.x][mapSize.y][mapSize.z]);
|
hitMap.resize(boost::extents[mapSize.x][mapSize.y][mapSize.z]);
|
||||||
|
|
||||||
enemyHeroAccessibleObjects.clear();
|
enemyHeroAccessibleObjects.clear();
|
||||||
townTreats.clear();
|
townThreats.clear();
|
||||||
|
|
||||||
std::map<PlayerColor, std::map<const CGHeroInstance *, HeroRole>> heroes;
|
std::map<PlayerColor, std::map<const CGHeroInstance *, HeroRole>> heroes;
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ void DangerHitMapAnalyzer::updateHitMap()
|
|||||||
|
|
||||||
for(auto town : ourTowns)
|
for(auto town : ourTowns)
|
||||||
{
|
{
|
||||||
townTreats[town->id]; // insert empty list
|
townThreats[town->id]; // insert empty list
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach_tile_pos([&](const int3 & pos){
|
foreach_tile_pos([&](const int3 & pos){
|
||||||
@ -91,21 +91,21 @@ void DangerHitMapAnalyzer::updateHitMap()
|
|||||||
|
|
||||||
auto & node = hitMap[pos.x][pos.y][pos.z];
|
auto & node = hitMap[pos.x][pos.y][pos.z];
|
||||||
|
|
||||||
HitMapInfo newTreat;
|
HitMapInfo newThreat;
|
||||||
|
|
||||||
newTreat.hero = path.targetHero;
|
newThreat.hero = path.targetHero;
|
||||||
newTreat.turn = path.turn();
|
newThreat.turn = path.turn();
|
||||||
newTreat.danger = path.getHeroStrength();
|
newThreat.danger = path.getHeroStrength();
|
||||||
|
|
||||||
if(newTreat.value() > node.maximumDanger.value())
|
if(newThreat.value() > node.maximumDanger.value())
|
||||||
{
|
{
|
||||||
node.maximumDanger = newTreat;
|
node.maximumDanger = newThreat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newTreat.turn < node.fastestDanger.turn
|
if(newThreat.turn < node.fastestDanger.turn
|
||||||
|| (newTreat.turn == node.fastestDanger.turn && node.fastestDanger.danger < newTreat.danger))
|
|| (newThreat.turn == node.fastestDanger.turn && node.fastestDanger.danger < newThreat.danger))
|
||||||
{
|
{
|
||||||
node.fastestDanger = newTreat;
|
node.fastestDanger = newThreat;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto objects = cb->getVisitableObjs(pos, false);
|
auto objects = cb->getVisitableObjs(pos, false);
|
||||||
@ -114,24 +114,24 @@ void DangerHitMapAnalyzer::updateHitMap()
|
|||||||
{
|
{
|
||||||
if(obj->ID == Obj::TOWN && obj->getOwner() == ai->playerID)
|
if(obj->ID == Obj::TOWN && obj->getOwner() == ai->playerID)
|
||||||
{
|
{
|
||||||
auto & treats = townTreats[obj->id];
|
auto & threats = townThreats[obj->id];
|
||||||
auto treat = std::find_if(treats.begin(), treats.end(), [&](const HitMapInfo & i) -> bool
|
auto threat = std::find_if(threats.begin(), threats.end(), [&](const HitMapInfo & i) -> bool
|
||||||
{
|
{
|
||||||
return i.hero.hid == path.targetHero->id;
|
return i.hero.hid == path.targetHero->id;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(treat == treats.end())
|
if(threat == threats.end())
|
||||||
{
|
{
|
||||||
treats.emplace_back();
|
threats.emplace_back();
|
||||||
treat = std::prev(treats.end(), 1);
|
threat = std::prev(threats.end(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newTreat.value() > treat->value())
|
if(newThreat.value() > threat->value())
|
||||||
{
|
{
|
||||||
*treat = newTreat;
|
*threat = newThreat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newTreat.turn == 0)
|
if(newThreat.turn == 0)
|
||||||
{
|
{
|
||||||
if(cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES)
|
if(cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES)
|
||||||
enemyHeroAccessibleObjects.emplace_back(path.targetHero, obj);
|
enemyHeroAccessibleObjects.emplace_back(path.targetHero, obj);
|
||||||
@ -240,13 +240,13 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<HitMapInfo> & DangerHitMapAnalyzer::getTownTreats(const CGTownInstance * town) const
|
const std::vector<HitMapInfo> & DangerHitMapAnalyzer::getTownThreats(const CGTownInstance * town) const
|
||||||
{
|
{
|
||||||
static const std::vector<HitMapInfo> empty = {};
|
static const std::vector<HitMapInfo> empty = {};
|
||||||
|
|
||||||
auto result = townTreats.find(town->id);
|
auto result = townThreats.find(town->id);
|
||||||
|
|
||||||
return result == townTreats.end() ? empty : result->second;
|
return result == townThreats.end() ? empty : result->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerColor DangerHitMapAnalyzer::getTileOwner(const int3 & tile) const
|
PlayerColor DangerHitMapAnalyzer::getTileOwner(const int3 & tile) const
|
||||||
@ -271,14 +271,14 @@ uint64_t DangerHitMapAnalyzer::enemyCanKillOurHeroesAlongThePath(const AIPath &
|
|||||||
|| (info.maximumDanger.turn <= turn && !isSafeToVisit(path.targetHero, path.heroArmy, info.maximumDanger.danger));
|
|| (info.maximumDanger.turn <= turn && !isSafeToVisit(path.targetHero, path.heroArmy, info.maximumDanger.danger));
|
||||||
}
|
}
|
||||||
|
|
||||||
const HitMapNode & DangerHitMapAnalyzer::getObjectTreat(const CGObjectInstance * obj) const
|
const HitMapNode & DangerHitMapAnalyzer::getObjectThreat(const CGObjectInstance * obj) const
|
||||||
{
|
{
|
||||||
auto tile = obj->visitablePos();
|
auto tile = obj->visitablePos();
|
||||||
|
|
||||||
return getTileTreat(tile);
|
return getTileThreat(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
const HitMapNode & DangerHitMapAnalyzer::getTileTreat(const int3 & tile) const
|
const HitMapNode & DangerHitMapAnalyzer::getTileThreat(const int3 & tile) const
|
||||||
{
|
{
|
||||||
const HitMapNode & info = hitMap[tile.x][tile.y][tile.z];
|
const HitMapNode & info = hitMap[tile.x][tile.y][tile.z];
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ struct AIPath;
|
|||||||
|
|
||||||
struct HitMapInfo
|
struct HitMapInfo
|
||||||
{
|
{
|
||||||
static HitMapInfo NoTreat;
|
static HitMapInfo NoThreat;
|
||||||
|
|
||||||
uint64_t danger;
|
uint64_t danger;
|
||||||
uint8_t turn;
|
uint8_t turn;
|
||||||
@ -74,7 +74,7 @@ private:
|
|||||||
bool hitMapUpToDate = false;
|
bool hitMapUpToDate = false;
|
||||||
bool tileOwnersUpToDate = false;
|
bool tileOwnersUpToDate = false;
|
||||||
const Nullkiller * ai;
|
const Nullkiller * ai;
|
||||||
std::map<ObjectInstanceID, std::vector<HitMapInfo>> townTreats;
|
std::map<ObjectInstanceID, std::vector<HitMapInfo>> townThreats;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DangerHitMapAnalyzer(const Nullkiller * ai) :ai(ai) {}
|
DangerHitMapAnalyzer(const Nullkiller * ai) :ai(ai) {}
|
||||||
@ -82,14 +82,14 @@ public:
|
|||||||
void updateHitMap();
|
void updateHitMap();
|
||||||
void calculateTileOwners();
|
void calculateTileOwners();
|
||||||
uint64_t enemyCanKillOurHeroesAlongThePath(const AIPath & path) const;
|
uint64_t enemyCanKillOurHeroesAlongThePath(const AIPath & path) const;
|
||||||
const HitMapNode & getObjectTreat(const CGObjectInstance * obj) const;
|
const HitMapNode & getObjectThreat(const CGObjectInstance * obj) const;
|
||||||
const HitMapNode & getTileTreat(const int3 & tile) const;
|
const HitMapNode & getTileThreat(const int3 & tile) const;
|
||||||
std::set<const CGObjectInstance *> getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const;
|
std::set<const CGObjectInstance *> getOneTurnAccessibleObjects(const CGHeroInstance * enemy) const;
|
||||||
void reset();
|
void reset();
|
||||||
void resetTileOwners() { tileOwnersUpToDate = false; }
|
void resetTileOwners() { tileOwnersUpToDate = false; }
|
||||||
PlayerColor getTileOwner(const int3 & tile) const;
|
PlayerColor getTileOwner(const int3 & tile) const;
|
||||||
const CGTownInstance * getClosestTown(const int3 & tile) const;
|
const CGTownInstance * getClosestTown(const int3 & tile) const;
|
||||||
const std::vector<HitMapInfo> & getTownTreats(const CGTownInstance * town) const;
|
const std::vector<HitMapInfo> & getTownThreats(const CGTownInstance * town) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
namespace NKAI
|
namespace NKAI
|
||||||
{
|
{
|
||||||
|
|
||||||
const float TREAT_IGNORE_RATIO = 2;
|
const float THREAT_IGNORE_RATIO = 2;
|
||||||
|
|
||||||
using namespace Goals;
|
using namespace Goals;
|
||||||
|
|
||||||
@ -46,20 +46,20 @@ Goals::TGoalVec DefenceBehavior::decompose() const
|
|||||||
return tasks;
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTreatUnderControl(const CGTownInstance * town, const HitMapInfo & treat, const std::vector<AIPath> & paths)
|
bool isThreatUnderControl(const CGTownInstance * town, const HitMapInfo & threat, const std::vector<AIPath> & paths)
|
||||||
{
|
{
|
||||||
int dayOfWeek = cb->getDate(Date::DAY_OF_WEEK);
|
int dayOfWeek = cb->getDate(Date::DAY_OF_WEEK);
|
||||||
|
|
||||||
for(const AIPath & path : paths)
|
for(const AIPath & path : paths)
|
||||||
{
|
{
|
||||||
bool treatIsWeak = path.getHeroStrength() / (float)treat.danger > TREAT_IGNORE_RATIO;
|
bool threatIsWeak = path.getHeroStrength() / (float)threat.danger > THREAT_IGNORE_RATIO;
|
||||||
bool needToSaveGrowth = treat.turn == 0 && dayOfWeek == 7;
|
bool needToSaveGrowth = threat.turn == 0 && dayOfWeek == 7;
|
||||||
|
|
||||||
if(treatIsWeak && !needToSaveGrowth)
|
if(threatIsWeak && !needToSaveGrowth)
|
||||||
{
|
{
|
||||||
if((path.exchangeCount == 1 && path.turn() < treat.turn)
|
if((path.exchangeCount == 1 && path.turn() < threat.turn)
|
||||||
|| path.turn() < treat.turn - 1
|
|| path.turn() < threat.turn - 1
|
||||||
|| (path.turn() < treat.turn && treat.turn >= 2))
|
|| (path.turn() < threat.turn && threat.turn >= 2))
|
||||||
{
|
{
|
||||||
#if NKAI_TRACE_LEVEL >= 1
|
#if NKAI_TRACE_LEVEL >= 1
|
||||||
logAi->trace(
|
logAi->trace(
|
||||||
@ -79,16 +79,16 @@ bool isTreatUnderControl(const CGTownInstance * town, const HitMapInfo & treat,
|
|||||||
|
|
||||||
void handleCounterAttack(
|
void handleCounterAttack(
|
||||||
const CGTownInstance * town,
|
const CGTownInstance * town,
|
||||||
const HitMapInfo & treat,
|
const HitMapInfo & threat,
|
||||||
const HitMapInfo & maximumDanger,
|
const HitMapInfo & maximumDanger,
|
||||||
Goals::TGoalVec & tasks)
|
Goals::TGoalVec & tasks)
|
||||||
{
|
{
|
||||||
if(treat.hero.validAndSet()
|
if(threat.hero.validAndSet()
|
||||||
&& treat.turn <= 1
|
&& threat.turn <= 1
|
||||||
&& (treat.danger == maximumDanger.danger || treat.turn < maximumDanger.turn))
|
&& (threat.danger == maximumDanger.danger || threat.turn < maximumDanger.turn))
|
||||||
{
|
{
|
||||||
auto heroCapturingPaths = ai->nullkiller->pathfinder->getPathInfo(treat.hero->visitablePos());
|
auto heroCapturingPaths = ai->nullkiller->pathfinder->getPathInfo(threat.hero->visitablePos());
|
||||||
auto goals = CaptureObjectsBehavior::getVisitGoals(heroCapturingPaths, treat.hero.get());
|
auto goals = CaptureObjectsBehavior::getVisitGoals(heroCapturingPaths, threat.hero.get());
|
||||||
|
|
||||||
for(int i = 0; i < heroCapturingPaths.size(); i++)
|
for(int i = 0; i < heroCapturingPaths.size(); i++)
|
||||||
{
|
{
|
||||||
@ -99,7 +99,7 @@ void handleCounterAttack(
|
|||||||
|
|
||||||
Composition composition;
|
Composition composition;
|
||||||
|
|
||||||
composition.addNext(DefendTown(town, treat, path, true)).addNext(goal);
|
composition.addNext(DefendTown(town, threat, path, true)).addNext(goal);
|
||||||
|
|
||||||
tasks.push_back(Goals::sptr(composition));
|
tasks.push_back(Goals::sptr(composition));
|
||||||
}
|
}
|
||||||
@ -152,19 +152,19 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
{
|
{
|
||||||
logAi->trace("Evaluating defence for %s", town->getNameTranslated());
|
logAi->trace("Evaluating defence for %s", town->getNameTranslated());
|
||||||
|
|
||||||
auto treatNode = ai->nullkiller->dangerHitMap->getObjectTreat(town);
|
auto threatNode = ai->nullkiller->dangerHitMap->getObjectThreat(town);
|
||||||
std::vector<HitMapInfo> treats = ai->nullkiller->dangerHitMap->getTownTreats(town);
|
std::vector<HitMapInfo> threats = ai->nullkiller->dangerHitMap->getTownThreats(town);
|
||||||
|
|
||||||
treats.push_back(treatNode.fastestDanger); // no guarantee that fastest danger will be there
|
threats.push_back(threatNode.fastestDanger); // no guarantee that fastest danger will be there
|
||||||
|
|
||||||
if(town->garrisonHero && handleGarrisonHeroFromPreviousTurn(town, tasks))
|
if(town->garrisonHero && handleGarrisonHeroFromPreviousTurn(town, tasks))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!treatNode.fastestDanger.hero)
|
if(!threatNode.fastestDanger.hero)
|
||||||
{
|
{
|
||||||
logAi->trace("No treat found for town %s", town->getNameTranslated());
|
logAi->trace("No threat found for town %s", town->getNameTranslated());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -179,23 +179,23 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
|
|
||||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(town->visitablePos());
|
auto paths = ai->nullkiller->pathfinder->getPathInfo(town->visitablePos());
|
||||||
|
|
||||||
for(auto & treat : treats)
|
for(auto & threat : threats)
|
||||||
{
|
{
|
||||||
logAi->trace(
|
logAi->trace(
|
||||||
"Town %s has treat %lld in %s turns, hero: %s",
|
"Town %s has threat %lld in %s turns, hero: %s",
|
||||||
town->getNameTranslated(),
|
town->getNameTranslated(),
|
||||||
treat.danger,
|
threat.danger,
|
||||||
std::to_string(treat.turn),
|
std::to_string(threat.turn),
|
||||||
treat.hero ? treat.hero->getNameTranslated() : std::string("<no hero>"));
|
threat.hero ? threat.hero->getNameTranslated() : std::string("<no hero>"));
|
||||||
|
|
||||||
handleCounterAttack(town, treat, treatNode.maximumDanger, tasks);
|
handleCounterAttack(town, threat, threatNode.maximumDanger, tasks);
|
||||||
|
|
||||||
if(isTreatUnderControl(town, treat, paths))
|
if(isThreatUnderControl(town, threat, paths))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluateRecruitingHero(tasks, treat, town);
|
evaluateRecruitingHero(tasks, threat, town);
|
||||||
|
|
||||||
if(paths.empty())
|
if(paths.empty())
|
||||||
{
|
{
|
||||||
@ -236,7 +236,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(path.turn() <= treat.turn - 2)
|
if(path.turn() <= threat.turn - 2)
|
||||||
{
|
{
|
||||||
#if NKAI_TRACE_LEVEL >= 1
|
#if NKAI_TRACE_LEVEL >= 1
|
||||||
logAi->trace("Defer defence of %s by %s because he has enough time to reach the town next trun",
|
logAi->trace("Defer defence of %s by %s because he has enough time to reach the town next trun",
|
||||||
@ -264,7 +264,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
{
|
{
|
||||||
tasks.push_back(
|
tasks.push_back(
|
||||||
Goals::sptr(Composition()
|
Goals::sptr(Composition()
|
||||||
.addNext(DefendTown(town, treat, path.targetHero))
|
.addNext(DefendTown(town, threat, path.targetHero))
|
||||||
.addNext(ExchangeSwapTownHeroes(town, town->visitingHero.get(), HeroLockedReason::DEFENCE))));
|
.addNext(ExchangeSwapTownHeroes(town, town->visitingHero.get(), HeroLockedReason::DEFENCE))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
|
|
||||||
tasks.push_back(
|
tasks.push_back(
|
||||||
Goals::sptr(Composition()
|
Goals::sptr(Composition()
|
||||||
.addNext(DefendTown(town, treat, path))
|
.addNext(DefendTown(town, threat, path))
|
||||||
.addNextSequence({
|
.addNextSequence({
|
||||||
sptr(ExchangeSwapTownHeroes(town, town->visitingHero.get())),
|
sptr(ExchangeSwapTownHeroes(town, town->visitingHero.get())),
|
||||||
sptr(ExecuteHeroChain(path, town)),
|
sptr(ExecuteHeroChain(path, town)),
|
||||||
@ -291,7 +291,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(treat.turn == 0 || (path.turn() <= treat.turn && path.getHeroStrength() * SAFE_ATTACK_CONSTANT >= treat.danger))
|
if(threat.turn == 0 || (path.turn() <= threat.turn && path.getHeroStrength() * SAFE_ATTACK_CONSTANT >= threat.danger))
|
||||||
{
|
{
|
||||||
if(ai->nullkiller->arePathHeroesLocked(path))
|
if(ai->nullkiller->arePathHeroesLocked(path))
|
||||||
{
|
{
|
||||||
@ -324,7 +324,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
}
|
}
|
||||||
Composition composition;
|
Composition composition;
|
||||||
|
|
||||||
composition.addNext(DefendTown(town, treat, path));
|
composition.addNext(DefendTown(town, threat, path));
|
||||||
TGoalVec sequence;
|
TGoalVec sequence;
|
||||||
|
|
||||||
if(town->garrisonHero && path.targetHero == town->garrisonHero.get() && path.exchangeCount == 1)
|
if(town->garrisonHero && path.targetHero == town->garrisonHero.get() && path.exchangeCount == 1)
|
||||||
@ -402,7 +402,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
logAi->debug("Found %d tasks", tasks.size());
|
logAi->debug("Found %d tasks", tasks.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & treat, const CGTownInstance * town) const
|
void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & threat, const CGTownInstance * town) const
|
||||||
{
|
{
|
||||||
if(town->hasBuilt(BuildingID::TAVERN)
|
if(town->hasBuilt(BuildingID::TAVERN)
|
||||||
&& cb->getResourceAmount(EGameResID::GOLD) > GameConstants::HERO_GOLD_COST)
|
&& cb->getResourceAmount(EGameResID::GOLD) > GameConstants::HERO_GOLD_COST)
|
||||||
@ -411,7 +411,7 @@ void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitM
|
|||||||
|
|
||||||
for(auto hero : heroesInTavern)
|
for(auto hero : heroesInTavern)
|
||||||
{
|
{
|
||||||
if(hero->getTotalStrength() < treat.danger)
|
if(hero->getTotalStrength() < threat.danger)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto myHeroes = cb->getHeroesInfo();
|
auto myHeroes = cb->getHeroesInfo();
|
||||||
@ -463,7 +463,7 @@ void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitM
|
|||||||
|
|
||||||
sequence.push_back(sptr(Goals::RecruitHero(town, hero)));
|
sequence.push_back(sptr(Goals::RecruitHero(town, hero)));
|
||||||
|
|
||||||
tasks.push_back(sptr(Goals::Composition().addNext(DefendTown(town, treat, hero)).addNextSequence(sequence)));
|
tasks.push_back(sptr(Goals::Composition().addNext(DefendTown(town, threat, hero)).addNextSequence(sequence)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* BuyArmyBehavior.h, part of VCMI engine
|
* DefenceBehavior.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
@ -39,7 +39,7 @@ namespace Goals
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void evaluateDefence(Goals::TGoalVec & tasks, const CGTownInstance * town) const;
|
void evaluateDefence(Goals::TGoalVec & tasks, const CGTownInstance * town) const;
|
||||||
void evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & treat, const CGTownInstance * town) const;
|
void evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & threat, const CGTownInstance * town) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,15 +593,15 @@ float RewardEvaluator::getSkillReward(const CGObjectInstance * target, const CGH
|
|||||||
|
|
||||||
const HitMapInfo & RewardEvaluator::getEnemyHeroDanger(const int3 & tile, uint8_t turn) const
|
const HitMapInfo & RewardEvaluator::getEnemyHeroDanger(const int3 & tile, uint8_t turn) const
|
||||||
{
|
{
|
||||||
auto & treatNode = ai->dangerHitMap->getTileTreat(tile);
|
auto & treatNode = ai->dangerHitMap->getTileThreat(tile);
|
||||||
|
|
||||||
if(treatNode.maximumDanger.danger == 0)
|
if(treatNode.maximumDanger.danger == 0)
|
||||||
return HitMapInfo::NoTreat;
|
return HitMapInfo::NoThreat;
|
||||||
|
|
||||||
if(treatNode.maximumDanger.turn <= turn)
|
if(treatNode.maximumDanger.turn <= turn)
|
||||||
return treatNode.maximumDanger;
|
return treatNode.maximumDanger;
|
||||||
|
|
||||||
return treatNode.fastestDanger.turn <= turn ? treatNode.fastestDanger : HitMapInfo::NoTreat;
|
return treatNode.fastestDanger.turn <= turn ? treatNode.fastestDanger : HitMapInfo::NoThreat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getArmyCost(const CArmedInstance * army)
|
int32_t getArmyCost(const CArmedInstance * army)
|
||||||
|
Loading…
Reference in New Issue
Block a user