mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
NKAI: configurable object graph
This commit is contained in:
parent
5f8a157c6d
commit
6245adb9a4
@ -373,7 +373,11 @@ void AIGateway::objectRemoved(const CGObjectInstance * obj, const PlayerColor &
|
||||
return;
|
||||
|
||||
nullkiller->memory->removeFromMemory(obj);
|
||||
nullkiller->baseGraph->removeObject(obj);
|
||||
|
||||
if(nullkiller->baseGraph && nullkiller->settings->isObjectGraphAllowed())
|
||||
{
|
||||
nullkiller->baseGraph->removeObject(obj);
|
||||
}
|
||||
|
||||
if(obj->ID == Obj::HERO && obj->tempOwner == playerID)
|
||||
{
|
||||
|
@ -178,8 +178,11 @@ Goals::TGoalVec CaptureObjectsBehavior::decompose() const
|
||||
#endif
|
||||
|
||||
const int3 pos = objToVisit->visitablePos();
|
||||
bool useObjectGraph = ai->nullkiller->settings->isObjectGraphAllowed()
|
||||
&& ai->nullkiller->getScanDepth() != ScanDepth::SMALL;
|
||||
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos, useObjectGraph);
|
||||
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos, true);
|
||||
std::vector<std::shared_ptr<ExecuteHeroChain>> waysToVisitObj;
|
||||
std::shared_ptr<ExecuteHeroChain> closestWay;
|
||||
|
||||
@ -210,7 +213,7 @@ Goals::TGoalVec CaptureObjectsBehavior::decompose() const
|
||||
{
|
||||
captureObjects(ai->nullkiller->objectClusterizer->getNearbyObjects());
|
||||
|
||||
if(tasks.empty())
|
||||
if(tasks.empty() || ai->nullkiller->getScanDepth() != ScanDepth::SMALL)
|
||||
captureObjects(ai->nullkiller->objectClusterizer->getFarObjects());
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ Goals::TGoalVec ClusterBehavior::decompose() const
|
||||
Goals::TGoalVec ClusterBehavior::decomposeCluster(std::shared_ptr<ObjectCluster> cluster) const
|
||||
{
|
||||
auto center = cluster->calculateCenter();
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(center->visitablePos(), true);
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(center->visitablePos(), ai->nullkiller->settings->isObjectGraphAllowed());
|
||||
auto blockerPos = cluster->blocker->visitablePos();
|
||||
std::vector<AIPath> blockerPaths;
|
||||
|
||||
|
@ -443,6 +443,10 @@ void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitM
|
||||
heroToDismiss = town->garrisonHero.get();
|
||||
}
|
||||
}
|
||||
|
||||
// avoid dismissing one weak hero in order to recruit another.
|
||||
if(heroToDismiss && heroToDismiss->getArmyStrength() + 500 > hero->getArmyStrength())
|
||||
continue;
|
||||
}
|
||||
else if(ai->nullkiller->heroManager->heroCapReached())
|
||||
{
|
||||
|
@ -125,7 +125,7 @@ void Nullkiller::resetAiState()
|
||||
dangerHitMap->reset();
|
||||
useHeroChain = true;
|
||||
|
||||
if(!baseGraph)
|
||||
if(!baseGraph && ai->nullkiller->settings->isObjectGraphAllowed())
|
||||
{
|
||||
baseGraph = std::make_unique<ObjectGraph>();
|
||||
baseGraph->updateGraph(this);
|
||||
@ -172,20 +172,24 @@ void Nullkiller::updateAiState(int pass, bool fast)
|
||||
cfg.useHeroChain = useHeroChain;
|
||||
cfg.allowBypassObjects = true;
|
||||
|
||||
if(scanDepth == ScanDepth::SMALL)
|
||||
if(scanDepth == ScanDepth::SMALL || settings->isObjectGraphAllowed())
|
||||
{
|
||||
cfg.mainTurnDistanceLimit = ai->nullkiller->settings->getMainHeroTurnDistanceLimit();
|
||||
cfg.mainTurnDistanceLimit = settings->getMainHeroTurnDistanceLimit();
|
||||
}
|
||||
|
||||
if(scanDepth != ScanDepth::ALL_FULL)
|
||||
if(scanDepth != ScanDepth::ALL_FULL || settings->isObjectGraphAllowed())
|
||||
{
|
||||
cfg.scoutTurnDistanceLimit = ai->nullkiller->settings->getScoutHeroTurnDistanceLimit();
|
||||
cfg.scoutTurnDistanceLimit =settings->getScoutHeroTurnDistanceLimit();
|
||||
}
|
||||
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
pathfinder->updatePaths(activeHeroes, cfg);
|
||||
pathfinder->updateGraphs(activeHeroes);
|
||||
|
||||
if(settings->isObjectGraphAllowed())
|
||||
{
|
||||
pathfinder->updateGraphs(activeHeroes);
|
||||
}
|
||||
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
@ -299,7 +303,8 @@ void Nullkiller::makeTurn()
|
||||
|
||||
// TODO: better to check turn distance here instead of priority
|
||||
if((heroRole != HeroRole::MAIN || bestTask->priority < SMALL_SCAN_MIN_PRIORITY)
|
||||
&& scanDepth == ScanDepth::MAIN_FULL)
|
||||
&& scanDepth == ScanDepth::MAIN_FULL
|
||||
&& !settings->isObjectGraphAllowed())
|
||||
{
|
||||
useHeroChain = false;
|
||||
scanDepth = ScanDepth::SMALL;
|
||||
@ -312,22 +317,25 @@ void Nullkiller::makeTurn()
|
||||
|
||||
if(bestTask->priority < MIN_PRIORITY)
|
||||
{
|
||||
auto heroes = cb->getHeroesInfo();
|
||||
auto hasMp = vstd::contains_if(heroes, [](const CGHeroInstance * h) -> bool
|
||||
{
|
||||
return h->movementPointsRemaining() > 100;
|
||||
});
|
||||
|
||||
if(hasMp && scanDepth != ScanDepth::ALL_FULL)
|
||||
if(!settings->isObjectGraphAllowed())
|
||||
{
|
||||
logAi->trace(
|
||||
"Goal %s has too low priority %f so increasing scan depth to full.",
|
||||
taskDescription,
|
||||
bestTask->priority);
|
||||
auto heroes = cb->getHeroesInfo();
|
||||
auto hasMp = vstd::contains_if(heroes, [](const CGHeroInstance * h) -> bool
|
||||
{
|
||||
return h->movementPointsRemaining() > 100;
|
||||
});
|
||||
|
||||
scanDepth = ScanDepth::ALL_FULL;
|
||||
useHeroChain = false;
|
||||
continue;
|
||||
if(hasMp && scanDepth != ScanDepth::ALL_FULL)
|
||||
{
|
||||
logAi->trace(
|
||||
"Goal %s has too low priority %f so increasing scan depth to full.",
|
||||
taskDescription,
|
||||
bestTask->priority);
|
||||
|
||||
scanDepth = ScanDepth::ALL_FULL;
|
||||
useHeroChain = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
logAi->trace("Goal %s has too low priority. It is not worth doing it. Ending turn.", taskDescription);
|
||||
|
@ -27,7 +27,8 @@ namespace NKAI
|
||||
mainHeroTurnDistanceLimit(10),
|
||||
scoutHeroTurnDistanceLimit(5),
|
||||
maxGoldPreasure(0.3f),
|
||||
maxpass(30)
|
||||
maxpass(30),
|
||||
allowObjectGraph(false)
|
||||
{
|
||||
ResourcePath resource("config/ai/nkai/nkai-settings", EResType::JSON);
|
||||
|
||||
@ -74,5 +75,10 @@ namespace NKAI
|
||||
{
|
||||
maxGoldPreasure = node.Struct()["maxGoldPreasure"].Float();
|
||||
}
|
||||
|
||||
if(!node.Struct()["allowObjectGraph"].isNull())
|
||||
{
|
||||
allowObjectGraph = node.Struct()["allowObjectGraph"].Bool();
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ namespace NKAI
|
||||
int scoutHeroTurnDistanceLimit;
|
||||
int maxpass;
|
||||
float maxGoldPreasure;
|
||||
bool allowObjectGraph;
|
||||
|
||||
public:
|
||||
Settings();
|
||||
@ -35,6 +36,7 @@ namespace NKAI
|
||||
int getMaxRoamingHeroes() const { return maxRoamingHeroes; }
|
||||
int getMainHeroTurnDistanceLimit() const { return mainHeroTurnDistanceLimit; }
|
||||
int getScoutHeroTurnDistanceLimit() const { return scoutHeroTurnDistanceLimit; }
|
||||
bool isObjectGraphAllowed() const { return allowObjectGraph; }
|
||||
|
||||
private:
|
||||
void loadFromMod(const std::string & modName, const ResourcePath & resource);
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#define NKAI_PATHFINDER_TRACE_LEVEL 0
|
||||
#define NKAI_GRAPH_TRACE_LEVEL 0
|
||||
#define NKAI_TRACE_LEVEL 0
|
||||
#define NKAI_TRACE_LEVEL 1
|
||||
|
||||
#include "../../../lib/pathfinder/CGPathNode.h"
|
||||
#include "../../../lib/pathfinder/INodeStorage.h"
|
||||
@ -27,11 +27,9 @@ namespace NKAI
|
||||
{
|
||||
namespace AIPathfinding
|
||||
{
|
||||
|
||||
const int BUCKET_COUNT = 5;
|
||||
const int BUCKET_COUNT = 5;
|
||||
const int BUCKET_SIZE = 3;
|
||||
const int NUM_CHAINS = BUCKET_COUNT * BUCKET_SIZE;
|
||||
const int THREAD_COUNT = 8;
|
||||
const int CHAIN_MAX_DEPTH = 4;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user