mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
NKAI: water paths in graph
This commit is contained in:
parent
b236384356
commit
fb6fd63a58
@ -373,6 +373,7 @@ void AIGateway::objectRemoved(const CGObjectInstance * obj, const PlayerColor &
|
||||
return;
|
||||
|
||||
nullkiller->memory->removeFromMemory(obj);
|
||||
nullkiller->baseGraph->removeObject(obj);
|
||||
|
||||
if(obj->ID == Obj::HERO && obj->tempOwner == playerID)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
void updateGraph(const Nullkiller * ai);
|
||||
void addObject(const CGObjectInstance * obj);
|
||||
void connectHeroes(const Nullkiller * ai);
|
||||
void removeObject(const CGObjectInstance * obj);
|
||||
void dumpToLog(std::string visualKey) const;
|
||||
|
||||
template<typename Func>
|
||||
|
14
Global.h
14
Global.h
@ -512,6 +512,20 @@ namespace vstd
|
||||
}
|
||||
}
|
||||
|
||||
//works for std::unordered_map, maybe something else
|
||||
template<typename Key, typename Val, typename Predicate>
|
||||
void erase_if(std::unordered_map<Key, Val> & container, Predicate pred)
|
||||
{
|
||||
auto itr = container.begin();
|
||||
auto endItr = container.end();
|
||||
while(itr != endItr)
|
||||
{
|
||||
auto tmpItr = itr++;
|
||||
if(pred(*tmpItr))
|
||||
container.erase(tmpItr);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InputRange, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_if(const InputRange &input, OutputIterator result, Predicate pred)
|
||||
{
|
||||
|
@ -80,9 +80,12 @@ public:
|
||||
auto pEnd = model->getTargetTileArea(end).topLeft();
|
||||
auto viewPort = target.getRenderArea();
|
||||
|
||||
pStart.x += 3;
|
||||
pEnd.x -= 3;
|
||||
|
||||
if(viewPort.isInside(pStart) && viewPort.isInside(pEnd))
|
||||
{
|
||||
target.drawLine(pStart, pEnd, ColorRGBA(255, 255, 0), ColorRGBA(255, 255, 0));
|
||||
target.drawLine(pStart, pEnd, ColorRGBA(255, 255, 0), ColorRGBA(255, 0, 0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user