mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
NKAI: object graph fixes
This commit is contained in:
parent
3820f6f78b
commit
adfcb650e2
@ -50,7 +50,6 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
using namespace tbb;
|
||||
|
||||
using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
|
||||
|
||||
@ -246,48 +245,6 @@ uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock>
|
||||
// todo: move to obj manager
|
||||
bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObjectInstance * obj);
|
||||
|
||||
template<typename TFunc>
|
||||
void pforeachTilePos(const int3 & mapSize, TFunc fn)
|
||||
{
|
||||
for(int z = 0; z < mapSize.z; ++z)
|
||||
{
|
||||
parallel_for(blocked_range<size_t>(0, mapSize.x), [&](const blocked_range<size_t>& r)
|
||||
{
|
||||
int3 pos(0, 0, z);
|
||||
|
||||
for(pos.x = r.begin(); pos.x != r.end(); ++pos.x)
|
||||
{
|
||||
for(pos.y = 0; pos.y < mapSize.y; ++pos.y)
|
||||
{
|
||||
fn(pos);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TFunc>
|
||||
void pforeachTilePaths(const int3 & mapSize, const Nullkiller * ai, TFunc fn)
|
||||
{
|
||||
for(int z = 0; z < mapSize.z; ++z)
|
||||
{
|
||||
parallel_for(blocked_range<size_t>(0, mapSize.x), [&](const blocked_range<size_t> & r)
|
||||
{
|
||||
int3 pos(0, 0, z);
|
||||
std::vector<AIPath> paths;
|
||||
|
||||
for(pos.x = r.begin(); pos.x != r.end(); ++pos.x)
|
||||
{
|
||||
for(pos.y = 0; pos.y < mapSize.y; ++pos.y)
|
||||
{
|
||||
ai->pathfinder->calculatePathInfo(paths, pos);
|
||||
fn(pos, paths);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class CDistanceSorter
|
||||
{
|
||||
const CGHeroInstance * hero;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "DangerHitMapAnalyzer.h"
|
||||
|
||||
#include "../Engine/Nullkiller.h"
|
||||
#include "../pforeach.h"
|
||||
#include "../../../lib/CRandomGenerator.h"
|
||||
|
||||
namespace NKAI
|
||||
|
@ -235,9 +235,9 @@ void ObjectClusterizer::clusterize()
|
||||
ai->memory->visitableObjs.end());
|
||||
|
||||
#if NKAI_TRACE_LEVEL == 0
|
||||
parallel_for(blocked_range<size_t>(0, objs.size()), [&](const blocked_range<size_t> & r) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, objs.size()), [&](const tbb::blocked_range<size_t> & r) {
|
||||
#else
|
||||
blocked_range<size_t> r(0, objs.size());
|
||||
tbb::blocked_range<size_t> r(0, objs.size());
|
||||
#endif
|
||||
auto priorityEvaluator = ai->priorityEvaluators->acquire();
|
||||
auto heroes = ai->cb->getHeroesInfo();
|
||||
|
@ -69,7 +69,7 @@ Goals::TGoalVec GatherArmyBehavior::deliverArmyToHero(const CGHeroInstance * her
|
||||
logAi->trace("Checking ways to gaher army for hero %s, %s", hero->getObjectName(), pos.toString());
|
||||
#endif
|
||||
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos);
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos, ai->nullkiller->settings->isObjectGraphAllowed());
|
||||
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Gather army found %d paths", paths.size());
|
||||
@ -231,7 +231,7 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const CGTownInstance * upgrader)
|
||||
logAi->trace("Checking ways to upgrade army in town %s, %s", upgrader->getObjectName(), pos.toString());
|
||||
#endif
|
||||
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos);
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos, ai->nullkiller->settings->isObjectGraphAllowed());
|
||||
auto goals = CaptureObjectsBehavior::getVisitGoals(paths);
|
||||
|
||||
std::vector<std::shared_ptr<ExecuteHeroChain>> waysToVisitObj;
|
||||
|
@ -81,6 +81,7 @@ set(Nullkiller_HEADERS
|
||||
Pathfinding/Rules/AIPreviousNodeRule.h
|
||||
Pathfinding/ObjectGraph.h
|
||||
AIUtility.h
|
||||
pforeach.h
|
||||
Analyzers/ArmyManager.h
|
||||
Analyzers/HeroManager.h
|
||||
Engine/Settings.h
|
||||
|
@ -412,7 +412,6 @@ struct DelayedWork
|
||||
class HeroChainCalculationTask
|
||||
{
|
||||
private:
|
||||
AISharedStorage & nodes;
|
||||
AINodeStorage & storage;
|
||||
std::vector<AIPathNode *> existingChains;
|
||||
std::vector<ExchangeCandidate> newChains;
|
||||
@ -424,8 +423,8 @@ private:
|
||||
|
||||
public:
|
||||
HeroChainCalculationTask(
|
||||
AINodeStorage & storage, AISharedStorage & nodes, const std::vector<int3> & tiles, uint64_t chainMask, int heroChainTurn)
|
||||
:existingChains(), newChains(), delayedWork(), nodes(nodes), storage(storage), chainMask(chainMask), heroChainTurn(heroChainTurn), heroChain(), tiles(tiles)
|
||||
AINodeStorage & storage, const std::vector<int3> & tiles, uint64_t chainMask, int heroChainTurn)
|
||||
:existingChains(), newChains(), delayedWork(), storage(storage), chainMask(chainMask), heroChainTurn(heroChainTurn), heroChain(), tiles(tiles)
|
||||
{
|
||||
existingChains.reserve(AIPathfinding::NUM_CHAINS);
|
||||
newChains.reserve(AIPathfinding::NUM_CHAINS);
|
||||
@ -621,7 +620,6 @@ void HeroChainCalculationTask::cleanupInefectiveChains(std::vector<ExchangeCandi
|
||||
{
|
||||
vstd::erase_if(result, [&](const ExchangeCandidate & chainInfo) -> bool
|
||||
{
|
||||
auto pos = chainInfo.coord;
|
||||
auto isNotEffective = storage.hasBetterChain(chainInfo.carrierParent, chainInfo)
|
||||
|| storage.hasBetterChain(chainInfo.carrierParent, chainInfo, result);
|
||||
|
||||
|
@ -168,6 +168,37 @@ private:
|
||||
}
|
||||
});
|
||||
|
||||
auto obj = ai->cb->getTopObj(pos);
|
||||
|
||||
if(obj && obj->ID == Obj::BOAT)
|
||||
{
|
||||
ai->pathfinder->calculatePathInfo(pathCache, pos);
|
||||
|
||||
for(AIPath & path : pathCache)
|
||||
{
|
||||
auto from = path.targetHero->visitablePos();
|
||||
auto fromObj = actorObjectMap[path.targetHero];
|
||||
auto fromTile = cb->getTile(from);
|
||||
|
||||
auto danger = ai->pathfinder->getStorage()->evaluateDanger(pos, path.targetHero, true);
|
||||
auto updated = target->tryAddConnection(
|
||||
from,
|
||||
pos,
|
||||
path.movementCost(),
|
||||
danger);
|
||||
|
||||
if(NKAI_GRAPH_TRACE_LEVEL >= 2 && updated)
|
||||
{
|
||||
logAi->trace(
|
||||
"Connected %s[%s] -> %s[%s] through [%s], cost %2f",
|
||||
fromObj ? fromObj->getObjectName() : "J", from.toString(),
|
||||
"Boat", pos.toString(),
|
||||
pos.toString(),
|
||||
path.movementCost());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -199,7 +230,9 @@ private:
|
||||
if(!cb->getTile(pos)->isWater())
|
||||
continue;
|
||||
|
||||
if(obj1 && (obj1->ID != Obj::BOAT || obj1->ID != Obj::SHIPYARD))
|
||||
auto startingObjIsBoatOrShipyard = obj1 && (obj1->ID == Obj::BOAT || obj1->ID == Obj::SHIPYARD);
|
||||
|
||||
if(!startingObjIsBoatOrShipyard)
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -287,7 +320,7 @@ private:
|
||||
assert(objectActor->visitablePos() == visitablePos);
|
||||
|
||||
actorObjectMap[objectActor] = obj;
|
||||
actors[objectActor] = obj->ID == Obj::TOWN || obj->ID == Obj::SHIPYARD ? HeroRole::MAIN : HeroRole::SCOUT;
|
||||
actors[objectActor] = obj->ID == Obj::TOWN || obj->ID == Obj::SHIPYARD || obj->ID == Obj::BOAT ? HeroRole::MAIN : HeroRole::SCOUT;
|
||||
|
||||
target->addObject(obj);
|
||||
}
|
||||
@ -717,9 +750,6 @@ void GraphPaths::quickAddChainInfoWithBlocker(std::vector<AIPath> & paths, int3
|
||||
|
||||
auto currentNode = currentTile->second[current.nodeType];
|
||||
|
||||
if(!currentNode.previous.valid())
|
||||
break;
|
||||
|
||||
allowBattle = allowBattle || currentNode.nodeType == GrapthPathNodeType::BATTLE;
|
||||
vstd::amax(danger, currentNode.danger);
|
||||
vstd::amax(cost, currentNode.cost);
|
||||
@ -777,7 +807,7 @@ void GraphPaths::quickAddChainInfoWithBlocker(std::vector<AIPath> & paths, int3
|
||||
}
|
||||
|
||||
if(!path.nodes.empty())
|
||||
break;
|
||||
continue;
|
||||
|
||||
for(auto graphTile = tilesToPass.rbegin(); graphTile != tilesToPass.rend(); graphTile++)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user