1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-16 10:19:47 +02:00
vcmi/AI/Nullkiller/Behaviors/ClusterBehavior.cpp

120 lines
2.8 KiB
C++
Raw Normal View History

2021-05-16 13:45:12 +02:00
/*
* RecruitHeroBehavior.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 "ClusterBehavior.h"
2021-05-16 14:39:38 +02:00
#include "../AIGateway.h"
2021-05-16 13:45:12 +02:00
#include "../Engine/Nullkiller.h"
#include "../AIUtility.h"
#include "../Markers/UnlockCluster.h"
2021-05-16 13:45:12 +02:00
#include "../Goals/Composition.h"
#include "../Behaviors/CaptureObjectsBehavior.h"
2022-09-26 20:01:07 +02:00
namespace NKAI
{
2021-05-16 13:45:12 +02:00
using namespace Goals;
std::string ClusterBehavior::toString() const
{
return "Unlock Clusters";
}
2024-03-31 17:39:00 +02:00
Goals::TGoalVec ClusterBehavior::decompose(const Nullkiller * ai) const
2021-05-16 13:45:12 +02:00
{
Goals::TGoalVec tasks;
2024-03-31 17:39:00 +02:00
auto clusters = ai->objectClusterizer->getLockedClusters();
2021-05-16 13:45:12 +02:00
for(auto cluster : clusters)
{
2024-03-31 17:39:00 +02:00
vstd::concatenate(tasks, decomposeCluster(ai, cluster));
2021-05-16 13:45:12 +02:00
}
return tasks;
}
2024-03-31 17:39:00 +02:00
Goals::TGoalVec ClusterBehavior::decomposeCluster(const Nullkiller * ai, std::shared_ptr<ObjectCluster> cluster) const
2021-05-16 13:45:12 +02:00
{
auto center = cluster->calculateCenter(ai->cb.get());
2024-05-19 09:04:45 +02:00
auto paths = ai->pathfinder->getPathInfo(center->visitablePos(), ai->isObjectGraphAllowed());
2021-05-16 13:45:12 +02:00
auto blockerPos = cluster->blocker->visitablePos();
std::vector<AIPath> blockerPaths;
blockerPaths.reserve(paths.size());
TGoalVec goals;
2022-09-26 20:01:07 +02:00
#if NKAI_TRACE_LEVEL >= 2
2021-05-16 13:45:12 +02:00
logAi->trace(
"Checking cluster %s %s, found %d paths",
2021-05-16 13:45:12 +02:00
cluster->blocker->getObjectName(),
cluster->blocker->visitablePos().toString(),
paths.size());
#endif
for(auto path = paths.begin(); path != paths.end();)
{
2022-09-26 20:01:07 +02:00
#if NKAI_TRACE_LEVEL >= 2
2021-05-16 13:45:12 +02:00
logAi->trace("Checking path %s", path->toString());
#endif
2024-03-31 17:39:00 +02:00
auto blocker = ai->objectClusterizer->getBlocker(*path);
2021-05-16 13:45:12 +02:00
if(blocker != cluster->blocker)
{
path = paths.erase(path);
continue;
}
blockerPaths.push_back(*path);
2021-05-16 14:39:38 +02:00
AIPath & clonedPath = blockerPaths.back();
clonedPath.nodes.clear();
2021-05-16 13:45:12 +02:00
for(auto node = path->nodes.rbegin(); node != path->nodes.rend(); node++)
{
2021-05-16 14:39:38 +02:00
clonedPath.nodes.insert(clonedPath.nodes.begin(), *node);
2021-05-16 13:45:12 +02:00
2024-03-31 17:39:00 +02:00
if(node->coord == blockerPos || ai->cb->getGuardingCreaturePosition(node->coord) == blockerPos)
2021-05-16 13:45:12 +02:00
break;
}
2021-05-16 14:39:38 +02:00
for(auto & node : clonedPath.nodes)
node.parentIndex -= path->nodes.size() - clonedPath.nodes.size();
2022-09-26 20:01:07 +02:00
#if NKAI_TRACE_LEVEL >= 2
2021-05-16 13:45:12 +02:00
logAi->trace("Unlock path found %s", blockerPaths.back().toString());
#endif
path++;
}
2022-09-26 20:01:07 +02:00
#if NKAI_TRACE_LEVEL >= 2
2021-05-16 13:45:12 +02:00
logAi->trace("Decompose unlock paths");
#endif
2024-04-27 09:57:30 +02:00
auto unlockTasks = CaptureObjectsBehavior::getVisitGoals(blockerPaths, ai, cluster->blocker);
2021-05-16 13:45:12 +02:00
for(int i = 0; i < paths.size(); i++)
{
if(unlockTasks[i]->invalid())
continue;
auto path = paths[i];
auto elementarUnlock = sptr(UnlockCluster(cluster, path));
goals.push_back(sptr(Composition().addNext(elementarUnlock).addNext(unlockTasks[i])));
}
return goals;
}
2022-09-26 20:01:07 +02:00
}