mirror of
https://github.com/vcmi/vcmi.git
synced 2026-05-22 09:55:17 +02:00
Merge pull request #3700 from vcmi/object-graph
NKAI: parallel capture objects
This commit is contained in:
@@ -21,6 +21,7 @@ namespace NKAI
|
||||
struct HeroPtr;
|
||||
class AIGateway;
|
||||
class FuzzyHelper;
|
||||
class Nullkiller;
|
||||
|
||||
namespace Goals
|
||||
{
|
||||
@@ -128,7 +129,7 @@ namespace Goals
|
||||
return const_cast<AbstractGoal *>(this);
|
||||
}
|
||||
|
||||
virtual TGoalVec decompose() const
|
||||
virtual TGoalVec decompose(const Nullkiller * ai) const
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ namespace Goals
|
||||
|
||||
virtual bool operator==(const T & other) const = 0;
|
||||
|
||||
TGoalVec decompose() const override
|
||||
TGoalVec decompose(const Nullkiller * ai) const override
|
||||
{
|
||||
TSubgoal single = decomposeSingle();
|
||||
TSubgoal single = decomposeSingle(ai);
|
||||
|
||||
if(!single || single->invalid())
|
||||
return {};
|
||||
@@ -65,7 +65,7 @@ namespace Goals
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual TSubgoal decomposeSingle() const
|
||||
virtual TSubgoal decomposeSingle(const Nullkiller * ai) const
|
||||
{
|
||||
return TSubgoal();
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ std::string CaptureObject::toString() const
|
||||
return "Capture " + name + " at " + tile.toString();
|
||||
}
|
||||
|
||||
TGoalVec CaptureObject::decompose() const
|
||||
TGoalVec CaptureObject::decompose(const Nullkiller * ai) const
|
||||
{
|
||||
return CaptureObjectsBehavior(cb->getObj(ObjectInstanceID(objid))).decompose();
|
||||
return CaptureObjectsBehavior(ai->cb->getObj(ObjectInstanceID(objid))).decompose(ai);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Goals
|
||||
}
|
||||
|
||||
bool operator==(const CaptureObject & other) const override;
|
||||
Goals::TGoalVec decompose() const override;
|
||||
Goals::TGoalVec decompose(const Nullkiller * ai) const override;
|
||||
std::string toString() const override;
|
||||
bool hasHash() const override { return true; }
|
||||
uint64_t getHash() const override;
|
||||
|
||||
@@ -29,36 +29,36 @@ std::string CompleteQuest::toString() const
|
||||
return "Complete quest " + questToString();
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::decompose() const
|
||||
TGoalVec CompleteQuest::decompose(const Nullkiller * ai) const
|
||||
{
|
||||
if(isKeyMaster(q))
|
||||
{
|
||||
return missionKeymaster();
|
||||
return missionKeymaster(ai);
|
||||
}
|
||||
|
||||
logAi->debug("Trying to realize quest: %s", questToString());
|
||||
|
||||
if(!q.quest->mission.artifacts.empty())
|
||||
return missionArt();
|
||||
return missionArt(ai);
|
||||
|
||||
if(!q.quest->mission.heroes.empty())
|
||||
return missionHero();
|
||||
return missionHero(ai);
|
||||
|
||||
if(!q.quest->mission.creatures.empty())
|
||||
return missionArmy();
|
||||
return missionArmy(ai);
|
||||
|
||||
if(q.quest->mission.resources.nonZero())
|
||||
return missionResources();
|
||||
return missionResources(ai);
|
||||
|
||||
if(q.quest->killTarget != ObjectInstanceID::NONE)
|
||||
return missionDestroyObj();
|
||||
return missionDestroyObj(ai);
|
||||
|
||||
for(auto & s : q.quest->mission.primary)
|
||||
if(s)
|
||||
return missionIncreasePrimaryStat();
|
||||
return missionIncreasePrimaryStat(ai);
|
||||
|
||||
if(q.quest->mission.heroLevel > 0)
|
||||
return missionLevel();
|
||||
return missionLevel(ai);
|
||||
|
||||
return TGoalVec();
|
||||
}
|
||||
@@ -103,21 +103,21 @@ std::string CompleteQuest::questToString() const
|
||||
return ms.toString();
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::tryCompleteQuest() const
|
||||
TGoalVec CompleteQuest::tryCompleteQuest(const Nullkiller * ai) const
|
||||
{
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(q.obj->visitablePos());
|
||||
auto paths = ai->pathfinder->getPathInfo(q.obj->visitablePos());
|
||||
|
||||
vstd::erase_if(paths, [&](const AIPath & path) -> bool
|
||||
{
|
||||
return !q.quest->checkQuest(path.targetHero);
|
||||
});
|
||||
|
||||
return CaptureObjectsBehavior::getVisitGoals(paths, q.obj);
|
||||
return CaptureObjectsBehavior::getVisitGoals(paths, ai, q.obj);
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionArt() const
|
||||
TGoalVec CompleteQuest::missionArt(const Nullkiller * ai) const
|
||||
{
|
||||
TGoalVec solutions = tryCompleteQuest();
|
||||
TGoalVec solutions = tryCompleteQuest(ai);
|
||||
|
||||
if(!solutions.empty())
|
||||
return solutions;
|
||||
@@ -132,9 +132,9 @@ TGoalVec CompleteQuest::missionArt() const
|
||||
return solutions;
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionHero() const
|
||||
TGoalVec CompleteQuest::missionHero(const Nullkiller * ai) const
|
||||
{
|
||||
TGoalVec solutions = tryCompleteQuest();
|
||||
TGoalVec solutions = tryCompleteQuest(ai);
|
||||
|
||||
if(solutions.empty())
|
||||
{
|
||||
@@ -145,43 +145,43 @@ TGoalVec CompleteQuest::missionHero() const
|
||||
return solutions;
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionArmy() const
|
||||
TGoalVec CompleteQuest::missionArmy(const Nullkiller * ai) const
|
||||
{
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(q.obj->visitablePos());
|
||||
auto paths = ai->pathfinder->getPathInfo(q.obj->visitablePos());
|
||||
|
||||
vstd::erase_if(paths, [&](const AIPath & path) -> bool
|
||||
{
|
||||
return !CQuest::checkMissionArmy(q.quest, path.heroArmy);
|
||||
});
|
||||
|
||||
return CaptureObjectsBehavior::getVisitGoals(paths, q.obj);
|
||||
return CaptureObjectsBehavior::getVisitGoals(paths, ai, q.obj);
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionIncreasePrimaryStat() const
|
||||
TGoalVec CompleteQuest::missionIncreasePrimaryStat(const Nullkiller * ai) const
|
||||
{
|
||||
return tryCompleteQuest();
|
||||
return tryCompleteQuest(ai);
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionLevel() const
|
||||
TGoalVec CompleteQuest::missionLevel(const Nullkiller * ai) const
|
||||
{
|
||||
return tryCompleteQuest();
|
||||
return tryCompleteQuest(ai);
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionKeymaster() const
|
||||
TGoalVec CompleteQuest::missionKeymaster(const Nullkiller * ai) const
|
||||
{
|
||||
if(isObjectPassable(q.obj))
|
||||
if(isObjectPassable(ai, q.obj))
|
||||
{
|
||||
return CaptureObjectsBehavior(q.obj).decompose();
|
||||
return CaptureObjectsBehavior(q.obj).decompose(ai);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CaptureObjectsBehavior().ofType(Obj::KEYMASTER, q.obj->subID).decompose();
|
||||
return CaptureObjectsBehavior().ofType(Obj::KEYMASTER, q.obj->subID).decompose(ai);
|
||||
}
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionResources() const
|
||||
TGoalVec CompleteQuest::missionResources(const Nullkiller * ai) const
|
||||
{
|
||||
TGoalVec solutions = tryCompleteQuest();
|
||||
TGoalVec solutions = tryCompleteQuest(ai);
|
||||
|
||||
/*auto heroes = cb->getHeroesInfo(); //TODO: choose best / free hero from among many possibilities?
|
||||
|
||||
@@ -208,14 +208,14 @@ TGoalVec CompleteQuest::missionResources() const
|
||||
return solutions;
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionDestroyObj() const
|
||||
TGoalVec CompleteQuest::missionDestroyObj(const Nullkiller * ai) const
|
||||
{
|
||||
auto obj = cb->getObj(q.quest->killTarget);
|
||||
auto obj = ai->cb->getObj(q.quest->killTarget);
|
||||
|
||||
if(!obj)
|
||||
return CaptureObjectsBehavior(q.obj).decompose();
|
||||
return CaptureObjectsBehavior(q.obj).decompose(ai);
|
||||
|
||||
auto relations = cb->getPlayerRelations(ai->playerID, obj->tempOwner);
|
||||
auto relations = ai->cb->getPlayerRelations(ai->playerID, obj->tempOwner);
|
||||
|
||||
//if(relations == PlayerRelations::SAME_PLAYER)
|
||||
//{
|
||||
@@ -226,7 +226,7 @@ TGoalVec CompleteQuest::missionDestroyObj() const
|
||||
//else
|
||||
if(relations == PlayerRelations::ENEMIES)
|
||||
{
|
||||
return CaptureObjectsBehavior(obj).decompose();
|
||||
return CaptureObjectsBehavior(obj).decompose(ai);
|
||||
}
|
||||
|
||||
return TGoalVec();
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Goals
|
||||
{
|
||||
}
|
||||
|
||||
Goals::TGoalVec decompose() const override;
|
||||
Goals::TGoalVec decompose(const Nullkiller * ai) const override;
|
||||
std::string toString() const override;
|
||||
bool hasHash() const override { return true; }
|
||||
uint64_t getHash() const override;
|
||||
@@ -37,15 +37,15 @@ namespace Goals
|
||||
bool operator==(const CompleteQuest & other) const override;
|
||||
|
||||
private:
|
||||
TGoalVec tryCompleteQuest() const;
|
||||
TGoalVec missionArt() const;
|
||||
TGoalVec missionHero() const;
|
||||
TGoalVec missionArmy() const;
|
||||
TGoalVec missionResources() const;
|
||||
TGoalVec missionDestroyObj() const;
|
||||
TGoalVec missionIncreasePrimaryStat() const;
|
||||
TGoalVec missionLevel() const;
|
||||
TGoalVec missionKeymaster() const;
|
||||
TGoalVec tryCompleteQuest(const Nullkiller * ai) const;
|
||||
TGoalVec missionArt(const Nullkiller * ai) const;
|
||||
TGoalVec missionHero(const Nullkiller * ai) const;
|
||||
TGoalVec missionArmy(const Nullkiller * ai) const;
|
||||
TGoalVec missionResources(const Nullkiller * ai) const;
|
||||
TGoalVec missionDestroyObj(const Nullkiller * ai) const;
|
||||
TGoalVec missionIncreasePrimaryStat(const Nullkiller * ai) const;
|
||||
TGoalVec missionLevel(const Nullkiller * ai) const;
|
||||
TGoalVec missionKeymaster(const Nullkiller * ai) const;
|
||||
std::string questToString() const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ void Composition::accept(AIGateway * ai)
|
||||
}
|
||||
}
|
||||
|
||||
TGoalVec Composition::decompose() const
|
||||
TGoalVec Composition::decompose(const Nullkiller * ai) const
|
||||
{
|
||||
TGoalVec result;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Goals
|
||||
Composition & addNext(const AbstractGoal & goal);
|
||||
Composition & addNext(TSubgoal goal);
|
||||
Composition & addNextSequence(const TGoalVec & taskSequence);
|
||||
TGoalVec decompose() const override;
|
||||
TGoalVec decompose(const Nullkiller * ai) const override;
|
||||
bool isElementar() const override;
|
||||
int getHeroExchangeCount() const override;
|
||||
};
|
||||
|
||||
@@ -100,7 +100,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
||||
throw cannotFulfillGoalException("Path is nondeterministic.");
|
||||
}
|
||||
|
||||
node->specialAction->execute(hero);
|
||||
node->specialAction->execute(ai, hero);
|
||||
|
||||
if(!heroPtr.validAndSet())
|
||||
{
|
||||
@@ -156,7 +156,7 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(moveHeroToTile(hero, node->coord))
|
||||
if(moveHeroToTile(ai, hero, node->coord))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -224,9 +224,9 @@ std::string ExecuteHeroChain::toString() const
|
||||
return "ExecuteHeroChain " + targetName + " by " + chainPath.targetHero->getNameTranslated();
|
||||
}
|
||||
|
||||
bool ExecuteHeroChain::moveHeroToTile(const CGHeroInstance * hero, const int3 & tile)
|
||||
bool ExecuteHeroChain::moveHeroToTile(AIGateway * ai, const CGHeroInstance * hero, const int3 & tile)
|
||||
{
|
||||
if(tile == hero->visitablePos() && cb->getVisitableObjs(hero->visitablePos()).size() < 2)
|
||||
if(tile == hero->visitablePos() && ai->myCb->getVisitableObjs(hero->visitablePos()).size() < 2)
|
||||
{
|
||||
logAi->warn("Why do I want to move hero %s to tile %s? Already standing on that tile! ", hero->getNameTranslated(), tile.toString());
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ namespace Goals
|
||||
|
||||
ExecuteHeroChain(const AIPath & path, const CGObjectInstance * obj = nullptr);
|
||||
|
||||
|
||||
void accept(AIGateway * ai) override;
|
||||
std::string toString() const override;
|
||||
bool operator==(const ExecuteHeroChain & other) const override;
|
||||
@@ -36,7 +35,7 @@ namespace Goals
|
||||
int getHeroExchangeCount() const override { return chainPath.exchangeCount; }
|
||||
|
||||
private:
|
||||
bool moveHeroToTile(const CGHeroInstance * hero, const int3 & tile);
|
||||
bool moveHeroToTile(AIGateway * ai, const CGHeroInstance * hero, const int3 & tile);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Goals
|
||||
{
|
||||
priority = -1;
|
||||
}
|
||||
TGoalVec decompose() const override
|
||||
TGoalVec decompose(const Nullkiller * ai) const override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user