mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-15 11:46:56 +02:00
NKAI: mana recovery
This commit is contained in:
parent
2dd0d76412
commit
ebe155fa95
@ -190,6 +190,41 @@ bool HeroManager::heroCapReached() const
|
|||||||
|| heroCount >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP);
|
|| heroCount >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float HeroManager::getMagicStrength(const CGHeroInstance * hero) const
|
||||||
|
{
|
||||||
|
auto hasFly = hero->spellbookContainsSpell(SpellID::FLY);
|
||||||
|
auto hasTownPortal = hero->spellbookContainsSpell(SpellID::TOWN_PORTAL);
|
||||||
|
auto manaLimit = hero->manaLimit();
|
||||||
|
auto spellPower = hero->getPrimSkillLevel(PrimarySkill::SPELL_POWER);
|
||||||
|
auto hasEarth = hero->getSpellSchoolLevel(SpellID(SpellID::TOWN_PORTAL).toSpell()) > 0;
|
||||||
|
|
||||||
|
auto score = 0.0f;
|
||||||
|
|
||||||
|
for(auto spellId : hero->getSpellsInSpellbook())
|
||||||
|
{
|
||||||
|
auto spell = spellId.toSpell();
|
||||||
|
auto schoolLevel = hero->getSpellSchoolLevel(spell);
|
||||||
|
|
||||||
|
score += (spell->getLevel() + 1) * (schoolLevel + 1) * 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
vstd::amin(score, 1);
|
||||||
|
|
||||||
|
score *= std::min(1.0f, spellPower / 10.0f);
|
||||||
|
|
||||||
|
if(hasFly)
|
||||||
|
score += 0.3f;
|
||||||
|
|
||||||
|
if(hasTownPortal && hasEarth)
|
||||||
|
score += 0.6f;
|
||||||
|
|
||||||
|
vstd::amin(score, 1);
|
||||||
|
|
||||||
|
score *= std::min(1.0f, manaLimit / 100.0f);
|
||||||
|
|
||||||
|
return std::min(score, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
bool HeroManager::canRecruitHero(const CGTownInstance * town) const
|
bool HeroManager::canRecruitHero(const CGTownInstance * town) const
|
||||||
{
|
{
|
||||||
if(!town)
|
if(!town)
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
virtual bool heroCapReached() const = 0;
|
virtual bool heroCapReached() const = 0;
|
||||||
virtual const CGHeroInstance * findHeroWithGrail() const = 0;
|
virtual const CGHeroInstance * findHeroWithGrail() const = 0;
|
||||||
virtual const CGHeroInstance * findWeakHeroToDismiss(uint64_t armyLimit) const = 0;
|
virtual const CGHeroInstance * findWeakHeroToDismiss(uint64_t armyLimit) const = 0;
|
||||||
|
virtual float getMagicStrength(const CGHeroInstance * hero) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT ISecondarySkillRule
|
class DLL_EXPORT ISecondarySkillRule
|
||||||
@ -76,6 +77,7 @@ public:
|
|||||||
bool heroCapReached() const override;
|
bool heroCapReached() const override;
|
||||||
const CGHeroInstance * findHeroWithGrail() const override;
|
const CGHeroInstance * findHeroWithGrail() const override;
|
||||||
const CGHeroInstance * findWeakHeroToDismiss(uint64_t armyLimit) const override;
|
const CGHeroInstance * findWeakHeroToDismiss(uint64_t armyLimit) const override;
|
||||||
|
float getMagicStrength(const CGHeroInstance * hero) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float evaluateFightingStrength(const CGHeroInstance * hero) const;
|
float evaluateFightingStrength(const CGHeroInstance * hero) const;
|
||||||
|
@ -93,9 +93,14 @@ std::vector<std::shared_ptr<ObjectCluster>> ObjectClusterizer::getLockedClusters
|
|||||||
const CGObjectInstance * ObjectClusterizer::getBlocker(const AIPath & path) const
|
const CGObjectInstance * ObjectClusterizer::getBlocker(const AIPath & path) const
|
||||||
{
|
{
|
||||||
for(auto node = path.nodes.rbegin(); node != path.nodes.rend(); node++)
|
for(auto node = path.nodes.rbegin(); node != path.nodes.rend(); node++)
|
||||||
|
{
|
||||||
|
std::vector<const CGObjectInstance *> blockers = {};
|
||||||
|
|
||||||
|
if(node->layer == EPathfindingLayer::LAND || node->layer == EPathfindingLayer::SAIL)
|
||||||
{
|
{
|
||||||
auto guardPos = ai->cb->getGuardingCreaturePosition(node->coord);
|
auto guardPos = ai->cb->getGuardingCreaturePosition(node->coord);
|
||||||
auto blockers = ai->cb->getVisitableObjs(node->coord);
|
|
||||||
|
blockers = ai->cb->getVisitableObjs(node->coord);
|
||||||
|
|
||||||
if(guardPos.valid())
|
if(guardPos.valid())
|
||||||
{
|
{
|
||||||
@ -106,6 +111,7 @@ const CGObjectInstance * ObjectClusterizer::getBlocker(const AIPath & path) cons
|
|||||||
blockers.insert(blockers.begin(), guard);
|
blockers.insert(blockers.begin(), guard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(node->specialAction && node->actionIsBlocked)
|
if(node->specialAction && node->actionIsBlocked)
|
||||||
{
|
{
|
||||||
|
70
AI/Nullkiller/Behaviors/StayAtTownBehavior.cpp
Normal file
70
AI/Nullkiller/Behaviors/StayAtTownBehavior.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* StartupBehavior.cpp, 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "StayAtTownBehavior.h"
|
||||||
|
#include "../AIGateway.h"
|
||||||
|
#include "../AIUtility.h"
|
||||||
|
#include "../Goals/StayAtTown.h"
|
||||||
|
#include "../Goals/Composition.h"
|
||||||
|
#include "../Goals/ExecuteHeroChain.h"
|
||||||
|
#include "lib/mapObjects/MapObjects.h" //for victory conditions
|
||||||
|
#include "../Engine/Nullkiller.h"
|
||||||
|
|
||||||
|
namespace NKAI
|
||||||
|
{
|
||||||
|
|
||||||
|
using namespace Goals;
|
||||||
|
|
||||||
|
std::string StayAtTownBehavior::toString() const
|
||||||
|
{
|
||||||
|
return "StayAtTownBehavior";
|
||||||
|
}
|
||||||
|
|
||||||
|
Goals::TGoalVec StayAtTownBehavior::decompose() const
|
||||||
|
{
|
||||||
|
Goals::TGoalVec tasks;
|
||||||
|
auto towns = cb->getTownsInfo();
|
||||||
|
|
||||||
|
if(!towns.size())
|
||||||
|
return tasks;
|
||||||
|
|
||||||
|
for(auto town : towns)
|
||||||
|
{
|
||||||
|
if(!town->hasBuilt(BuildingID::MAGES_GUILD_1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto paths = ai->nullkiller->pathfinder->getPathInfo(town->visitablePos());
|
||||||
|
|
||||||
|
for(auto & path : paths)
|
||||||
|
{
|
||||||
|
if(town->visitingHero && town->visitingHero.get() != path.targetHero)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(path.turn() == 0 && !path.getFirstBlockedAction() && path.exchangeCount <= 1)
|
||||||
|
{
|
||||||
|
if(path.targetHero->mana == path.targetHero->manaLimit())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Composition stayAtTown;
|
||||||
|
|
||||||
|
stayAtTown.addNextSequence({
|
||||||
|
sptr(ExecuteHeroChain(path)),
|
||||||
|
sptr(StayAtTown(town, path))
|
||||||
|
});
|
||||||
|
|
||||||
|
tasks.push_back(sptr(stayAtTown));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
AI/Nullkiller/Behaviors/StayAtTownBehavior.h
Normal file
39
AI/Nullkiller/Behaviors/StayAtTownBehavior.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* StayAtTownBehavior.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 "lib/VCMI_Lib.h"
|
||||||
|
#include "../Goals/CGoal.h"
|
||||||
|
#include "../AIUtility.h"
|
||||||
|
|
||||||
|
namespace NKAI
|
||||||
|
{
|
||||||
|
namespace Goals
|
||||||
|
{
|
||||||
|
class StayAtTownBehavior : public CGoal<StayAtTownBehavior>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StayAtTownBehavior()
|
||||||
|
:CGoal(STAY_AT_TOWN_BEHAVIOR)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual TGoalVec decompose() const override;
|
||||||
|
virtual std::string toString() const override;
|
||||||
|
|
||||||
|
virtual bool operator==(const StayAtTownBehavior & other) const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -35,6 +35,7 @@ set(Nullkiller_SRCS
|
|||||||
Goals/ExecuteHeroChain.cpp
|
Goals/ExecuteHeroChain.cpp
|
||||||
Goals/ExchangeSwapTownHeroes.cpp
|
Goals/ExchangeSwapTownHeroes.cpp
|
||||||
Goals/CompleteQuest.cpp
|
Goals/CompleteQuest.cpp
|
||||||
|
Goals/StayAtTown.cpp
|
||||||
Markers/ArmyUpgrade.cpp
|
Markers/ArmyUpgrade.cpp
|
||||||
Markers/HeroExchange.cpp
|
Markers/HeroExchange.cpp
|
||||||
Markers/UnlockCluster.cpp
|
Markers/UnlockCluster.cpp
|
||||||
@ -53,6 +54,7 @@ set(Nullkiller_SRCS
|
|||||||
Behaviors/BuildingBehavior.cpp
|
Behaviors/BuildingBehavior.cpp
|
||||||
Behaviors/GatherArmyBehavior.cpp
|
Behaviors/GatherArmyBehavior.cpp
|
||||||
Behaviors/ClusterBehavior.cpp
|
Behaviors/ClusterBehavior.cpp
|
||||||
|
Behaviors/StayAtTownBehavior.cpp
|
||||||
Helpers/ArmyFormation.cpp
|
Helpers/ArmyFormation.cpp
|
||||||
AIGateway.cpp
|
AIGateway.cpp
|
||||||
)
|
)
|
||||||
@ -99,6 +101,7 @@ set(Nullkiller_HEADERS
|
|||||||
Goals/ExchangeSwapTownHeroes.h
|
Goals/ExchangeSwapTownHeroes.h
|
||||||
Goals/CompleteQuest.h
|
Goals/CompleteQuest.h
|
||||||
Goals/Goals.h
|
Goals/Goals.h
|
||||||
|
Goals/StayAtTown.h
|
||||||
Markers/ArmyUpgrade.h
|
Markers/ArmyUpgrade.h
|
||||||
Markers/HeroExchange.h
|
Markers/HeroExchange.h
|
||||||
Markers/UnlockCluster.h
|
Markers/UnlockCluster.h
|
||||||
@ -117,6 +120,7 @@ set(Nullkiller_HEADERS
|
|||||||
Behaviors/BuildingBehavior.h
|
Behaviors/BuildingBehavior.h
|
||||||
Behaviors/GatherArmyBehavior.h
|
Behaviors/GatherArmyBehavior.h
|
||||||
Behaviors/ClusterBehavior.h
|
Behaviors/ClusterBehavior.h
|
||||||
|
Behaviors/StayAtTownBehavior.h
|
||||||
Helpers/ArmyFormation.h
|
Helpers/ArmyFormation.h
|
||||||
AIGateway.h
|
AIGateway.h
|
||||||
)
|
)
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "../Behaviors/BuildingBehavior.h"
|
#include "../Behaviors/BuildingBehavior.h"
|
||||||
#include "../Behaviors/GatherArmyBehavior.h"
|
#include "../Behaviors/GatherArmyBehavior.h"
|
||||||
#include "../Behaviors/ClusterBehavior.h"
|
#include "../Behaviors/ClusterBehavior.h"
|
||||||
|
#include "../Behaviors/StayAtTownBehavior.h"
|
||||||
#include "../Goals/Invalid.h"
|
#include "../Goals/Invalid.h"
|
||||||
#include "../Goals/Composition.h"
|
#include "../Goals/Composition.h"
|
||||||
|
|
||||||
@ -262,7 +263,8 @@ void Nullkiller::makeTurn()
|
|||||||
choseBestTask(sptr(CaptureObjectsBehavior()), 1),
|
choseBestTask(sptr(CaptureObjectsBehavior()), 1),
|
||||||
choseBestTask(sptr(ClusterBehavior()), MAX_DEPTH),
|
choseBestTask(sptr(ClusterBehavior()), MAX_DEPTH),
|
||||||
choseBestTask(sptr(DefenceBehavior()), MAX_DEPTH),
|
choseBestTask(sptr(DefenceBehavior()), MAX_DEPTH),
|
||||||
choseBestTask(sptr(GatherArmyBehavior()), MAX_DEPTH)
|
choseBestTask(sptr(GatherArmyBehavior()), MAX_DEPTH),
|
||||||
|
choseBestTask(sptr(StayAtTownBehavior()), MAX_DEPTH)
|
||||||
};
|
};
|
||||||
|
|
||||||
if(cb->getDate(Date::DAY) == 1)
|
if(cb->getDate(Date::DAY) == 1)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "../../../lib/filesystem/Filesystem.h"
|
#include "../../../lib/filesystem/Filesystem.h"
|
||||||
#include "../Goals/ExecuteHeroChain.h"
|
#include "../Goals/ExecuteHeroChain.h"
|
||||||
#include "../Goals/BuildThis.h"
|
#include "../Goals/BuildThis.h"
|
||||||
|
#include "../Goals/StayAtTown.h"
|
||||||
#include "../Goals/ExchangeSwapTownHeroes.h"
|
#include "../Goals/ExchangeSwapTownHeroes.h"
|
||||||
#include "../Goals/DismissHero.h"
|
#include "../Goals/DismissHero.h"
|
||||||
#include "../Markers/UnlockCluster.h"
|
#include "../Markers/UnlockCluster.h"
|
||||||
@ -309,6 +310,9 @@ uint64_t RewardEvaluator::getArmyReward(
|
|||||||
: 0;
|
: 0;
|
||||||
case Obj::PANDORAS_BOX:
|
case Obj::PANDORAS_BOX:
|
||||||
return 5000;
|
return 5000;
|
||||||
|
case Obj::MAGIC_WELL:
|
||||||
|
case Obj::MAGIC_SPRING:
|
||||||
|
return getManaRecoveryArmyReward(hero);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -450,6 +454,11 @@ uint64_t RewardEvaluator::townArmyGrowth(const CGTownInstance * town) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t RewardEvaluator::getManaRecoveryArmyReward(const CGHeroInstance * hero) const
|
||||||
|
{
|
||||||
|
return ai->heroManager->getMagicStrength(hero) * 10000 * (1.0f - std::sqrt(static_cast<float>(hero->mana) / hero->manaLimit()));
|
||||||
|
}
|
||||||
|
|
||||||
float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) const
|
float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) const
|
||||||
{
|
{
|
||||||
if(!target)
|
if(!target)
|
||||||
@ -693,6 +702,22 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StayAtTownManaRecoveryEvaluator : public IEvaluationContextBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void buildEvaluationContext(EvaluationContext & evaluationContext, Goals::TSubgoal task) const override
|
||||||
|
{
|
||||||
|
if(task->goalType != Goals::STAY_AT_TOWN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Goals::StayAtTown & stayAtTown = dynamic_cast<Goals::StayAtTown &>(*task);
|
||||||
|
|
||||||
|
evaluationContext.armyReward += evaluationContext.evaluator.getManaRecoveryArmyReward(stayAtTown.getHero().get());
|
||||||
|
evaluationContext.movementCostByRole[evaluationContext.heroRole] += stayAtTown.getMovementWasted();
|
||||||
|
evaluationContext.movementCost += stayAtTown.getMovementWasted();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void addTileDanger(EvaluationContext & evaluationContext, const int3 & tile, uint8_t turn, uint64_t ourStrength)
|
void addTileDanger(EvaluationContext & evaluationContext, const int3 & tile, uint8_t turn, uint64_t ourStrength)
|
||||||
{
|
{
|
||||||
HitMapInfo enemyDanger = evaluationContext.evaluator.getEnemyHeroDanger(tile, turn);
|
HitMapInfo enemyDanger = evaluationContext.evaluator.getEnemyHeroDanger(tile, turn);
|
||||||
@ -998,6 +1023,7 @@ PriorityEvaluator::PriorityEvaluator(const Nullkiller * ai)
|
|||||||
evaluationContextBuilders.push_back(std::make_shared<DefendTownEvaluator>());
|
evaluationContextBuilders.push_back(std::make_shared<DefendTownEvaluator>());
|
||||||
evaluationContextBuilders.push_back(std::make_shared<ExchangeSwapTownHeroesContextBuilder>());
|
evaluationContextBuilders.push_back(std::make_shared<ExchangeSwapTownHeroesContextBuilder>());
|
||||||
evaluationContextBuilders.push_back(std::make_shared<DismissHeroContextBuilder>(ai));
|
evaluationContextBuilders.push_back(std::make_shared<DismissHeroContextBuilder>(ai));
|
||||||
|
evaluationContextBuilders.push_back(std::make_shared<StayAtTownManaRecoveryEvaluator>());
|
||||||
}
|
}
|
||||||
|
|
||||||
EvaluationContext PriorityEvaluator::buildEvaluationContext(Goals::TSubgoal goal) const
|
EvaluationContext PriorityEvaluator::buildEvaluationContext(Goals::TSubgoal goal) const
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
uint64_t getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const;
|
uint64_t getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const;
|
||||||
const HitMapInfo & getEnemyHeroDanger(const int3 & tile, uint8_t turn) const;
|
const HitMapInfo & getEnemyHeroDanger(const int3 & tile, uint8_t turn) const;
|
||||||
uint64_t townArmyGrowth(const CGTownInstance * town) const;
|
uint64_t townArmyGrowth(const CGTownInstance * town) const;
|
||||||
|
uint64_t getManaRecoveryArmyReward(const CGHeroInstance * hero) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_EXPORT EvaluationContext
|
struct DLL_EXPORT EvaluationContext
|
||||||
|
@ -71,7 +71,9 @@ namespace Goals
|
|||||||
ARMY_UPGRADE,
|
ARMY_UPGRADE,
|
||||||
DEFEND_TOWN,
|
DEFEND_TOWN,
|
||||||
CAPTURE_OBJECT,
|
CAPTURE_OBJECT,
|
||||||
SAVE_RESOURCES
|
SAVE_RESOURCES,
|
||||||
|
STAY_AT_TOWN_BEHAVIOR,
|
||||||
|
STAY_AT_TOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>
|
class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>
|
||||||
|
52
AI/Nullkiller/Goals/StayAtTown.cpp
Normal file
52
AI/Nullkiller/Goals/StayAtTown.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* ArmyUpgrade.cpp, 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "StayAtTown.h"
|
||||||
|
#include "../AIGateway.h"
|
||||||
|
#include "../Engine/Nullkiller.h"
|
||||||
|
#include "../AIUtility.h"
|
||||||
|
|
||||||
|
namespace NKAI
|
||||||
|
{
|
||||||
|
|
||||||
|
using namespace Goals;
|
||||||
|
|
||||||
|
StayAtTown::StayAtTown(const CGTownInstance * town, AIPath & path)
|
||||||
|
: ElementarGoal(Goals::STAY_AT_TOWN)
|
||||||
|
{
|
||||||
|
sethero(path.targetHero);
|
||||||
|
settown(town);
|
||||||
|
movementWasted = static_cast<float>(hero->movementPointsRemaining()) / hero->movementPointsLimit(!hero->boat) - path.movementCost();
|
||||||
|
vstd::amax(movementWasted, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StayAtTown::operator==(const StayAtTown & other) const
|
||||||
|
{
|
||||||
|
return hero == other.hero && town == other.town;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StayAtTown::toString() const
|
||||||
|
{
|
||||||
|
return "Stay at town " + town->getNameTranslated()
|
||||||
|
+ " hero " + hero->getNameTranslated()
|
||||||
|
+ ", mana: " + std::to_string(hero->mana);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StayAtTown::accept(AIGateway * ai)
|
||||||
|
{
|
||||||
|
if(hero->visitedTown != town)
|
||||||
|
{
|
||||||
|
logAi->error("Hero %s expected visiting town %s", hero->getNameTranslated(), town->getNameTranslated());
|
||||||
|
}
|
||||||
|
|
||||||
|
ai->nullkiller->lockHero(hero.get(), HeroLockedReason::DEFENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
AI/Nullkiller/Goals/StayAtTown.h
Normal file
36
AI/Nullkiller/Goals/StayAtTown.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* ArmyUpgrade.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 "../Goals/CGoal.h"
|
||||||
|
#include "../Pathfinding/AINodeStorage.h"
|
||||||
|
#include "../Analyzers/ArmyManager.h"
|
||||||
|
#include "../Analyzers/DangerHitMapAnalyzer.h"
|
||||||
|
|
||||||
|
namespace NKAI
|
||||||
|
{
|
||||||
|
namespace Goals
|
||||||
|
{
|
||||||
|
class DLL_EXPORT StayAtTown : public ElementarGoal<StayAtTown>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float movementWasted;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StayAtTown(const CGTownInstance * town, AIPath & path);
|
||||||
|
|
||||||
|
virtual bool operator==(const StayAtTown & other) const override;
|
||||||
|
virtual std::string toString() const override;
|
||||||
|
void accept(AIGateway * ai) override;
|
||||||
|
float getMovementWasted() const { return movementWasted; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -279,9 +279,10 @@ void AINodeStorage::commit(
|
|||||||
|
|
||||||
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
||||||
logAi->trace(
|
logAi->trace(
|
||||||
"Commited %s -> %s, cost: %f, turn: %s, mp: %d, hero: %s, mask: %x, army: %lld",
|
"Commited %s -> %s, layer: %d, cost: %f, turn: %s, mp: %d, hero: %s, mask: %x, army: %lld",
|
||||||
source->coord.toString(),
|
source->coord.toString(),
|
||||||
destination->coord.toString(),
|
destination->coord.toString(),
|
||||||
|
destination->layer,
|
||||||
destination->getCost(),
|
destination->getCost(),
|
||||||
std::to_string(destination->turns),
|
std::to_string(destination->turns),
|
||||||
destination->moveRemains,
|
destination->moveRemains,
|
||||||
@ -1343,6 +1344,7 @@ void AINodeStorage::fillChainInfo(const AIPathNode * node, AIPath & path, int pa
|
|||||||
pathNode.coord = node->coord;
|
pathNode.coord = node->coord;
|
||||||
pathNode.parentIndex = parentIndex;
|
pathNode.parentIndex = parentIndex;
|
||||||
pathNode.actionIsBlocked = false;
|
pathNode.actionIsBlocked = false;
|
||||||
|
pathNode.layer = node->layer;
|
||||||
|
|
||||||
if(pathNode.specialAction)
|
if(pathNode.specialAction)
|
||||||
{
|
{
|
||||||
|
@ -65,6 +65,7 @@ struct AIPathNodeInfo
|
|||||||
float cost;
|
float cost;
|
||||||
uint8_t turns;
|
uint8_t turns;
|
||||||
int3 coord;
|
int3 coord;
|
||||||
|
EPathfindingLayer layer;
|
||||||
uint64_t danger;
|
uint64_t danger;
|
||||||
const CGHeroInstance * targetHero;
|
const CGHeroInstance * targetHero;
|
||||||
int parentIndex;
|
int parentIndex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user