1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-23 00:28:08 +02:00

NKAI: water paths in graph

This commit is contained in:
Andrii Danylchenko
2024-02-11 15:27:56 +02:00
parent b236384356
commit fb6fd63a58
5 changed files with 62 additions and 7 deletions

View File

@ -10,6 +10,7 @@
#include "StdInc.h"
#include "ObjectGraph.h"
#include "AIPathfinderConfig.h"
#include "../../../lib/CRandomGenerator.h"
#include "../../../CCallback.h"
#include "../../../lib/mapping/CMap.h"
#include "../Engine/Nullkiller.h"
@ -21,10 +22,10 @@ namespace NKAI
void ObjectGraph::updateGraph(const Nullkiller * ai)
{
auto cb = ai->cb;
auto mapSize = cb->getMapSize();
std::map<const CGHeroInstance *, HeroRole> actors;
std::map<const CGHeroInstance *, const CGObjectInstance *> actorObjectMap;
std::vector<CGBoat *> boats;
auto addObjectActor = [&](const CGObjectInstance * obj)
{
@ -37,8 +38,14 @@ void ObjectGraph::updateGraph(const Nullkiller * ai)
objectActor->pos = objectActor->convertFromVisitablePos(visitablePos);
objectActor->initObj(rng);
if(cb->getTile(visitablePos)->isWater())
{
boats.push_back(new CGBoat(objectActor->cb));
objectActor->boat = boats.back();
}
actorObjectMap[objectActor] = obj;
actors[objectActor] = obj->ID == Obj::TOWN ? HeroRole::MAIN : HeroRole::SCOUT;
actors[objectActor] = obj->ID == Obj::TOWN || obj->ID == Obj::SHIPYARD ? HeroRole::MAIN : HeroRole::SCOUT;
addObject(obj);
};
@ -85,6 +92,17 @@ void ObjectGraph::updateGraph(const Nullkiller * ai)
auto obj1 = actorObjectMap[path1.targetHero];
auto obj2 = actorObjectMap[path2.targetHero];
auto tile1 = cb->getTile(obj1->visitablePos());
auto tile2 = cb->getTile(obj2->visitablePos());
if(tile2->isWater() && !tile1->isWater())
{
auto linkTile = cb->getTile(pos);
if(!linkTile->isWater() || obj1->ID != Obj::BOAT || obj1->ID != Obj::SHIPYARD)
continue;
}
auto danger = ai->pathfinder->getStorage()->evaluateDanger(obj2->visitablePos(), path1.targetHero, true);
auto updated = nodes[obj1->visitablePos()].connections[obj2->visitablePos()].update(
@ -108,11 +126,16 @@ void ObjectGraph::updateGraph(const Nullkiller * ai)
}
});
for(auto h : actors)
for(auto h : actorObjectMap)
{
delete h.first;
}
for(auto boat : boats)
{
delete boat;
}
#if NKAI_GRAPH_TRACE_LEVEL >= 1
dumpToLog("graph");
#endif
@ -123,6 +146,21 @@ void ObjectGraph::addObject(const CGObjectInstance * obj)
nodes[obj->visitablePos()].init(obj);
}
void ObjectGraph::removeObject(const CGObjectInstance * obj)
{
nodes[obj->visitablePos()].objectExists = false;
if(obj->ID == Obj::BOAT)
{
vstd::erase_if(nodes[obj->visitablePos()].connections, [&](const std::pair<int3, ObjectLink> & link) -> bool
{
auto tile = cb->getTile(link.first, false);
return tile && tile->isWater();
});
}
}
void ObjectGraph::connectHeroes(const Nullkiller * ai)
{
for(auto obj : ai->memory->visitableObjs)
@ -170,7 +208,7 @@ void ObjectGraph::dumpToLog(std::string visualKey) const
node.second.danger);
#endif
logBuilder.addLine(node.first, tile.first);
logBuilder.addLine(tile.first, node.first);
}
}
});
@ -206,9 +244,7 @@ void GraphPaths::calculatePaths(const CGHeroInstance * targetHero, const Nullkil
graph.iterateConnections(pos.coord, [&](int3 target, ObjectLink o)
{
auto graphNode = graph.getNode(target);
auto targetNodeType = o.danger ? GrapthPathNodeType::BATTLE : pos.nodeType;
auto targetPointer = GraphPathNodePointer(target, targetNodeType);
auto & targetNode = getNode(targetPointer);