| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 | 
							- /*
 
- * ObjectGraph.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 "ObjectGraph.h"
 
- #include "ObjectGraphCalculator.h"
 
- #include "AIPathfinderConfig.h"
 
- #include "../../../lib/CRandomGenerator.h"
 
- #include "../../../CCallback.h"
 
- #include "../../../lib/mapping/CMap.h"
 
- #include "../Engine/Nullkiller.h"
 
- #include "../../../lib/logging/VisualLogger.h"
 
- #include "Actions/QuestAction.h"
 
- #include "../pforeach.h"
 
- #include "Actions/BoatActions.h"
 
- namespace NKAI
 
- {
 
- bool ObjectGraph::tryAddConnection(
 
- 	const int3 & from,
 
- 	const int3 & to,
 
- 	float cost,
 
- 	uint64_t danger)
 
- {
 
- 	auto result =  nodes[from].connections[to].update(cost, danger);
 
- 	auto & connection = nodes[from].connections[to];
 
- 	if(result && isVirtualBoat(to) && !connection.specialAction)
 
- 	{
 
- 		connection.specialAction = std::make_shared<AIPathfinding::BuildBoatActionFactory>(virtualBoats[to]);
 
- 	}
 
- 	return result;
 
- }
 
- void ObjectGraph::removeConnection(const int3 & from, const int3 & to)
 
- {
 
- 	nodes[from].connections.erase(to);
 
- }
 
- void ObjectGraph::updateGraph(const Nullkiller * ai)
 
- {
 
- 	auto cb = ai->cb;
 
- 	ObjectGraphCalculator calculator(this, ai);
 
- 	calculator.setGraphObjects();
 
- 	calculator.calculateConnections();
 
- 	calculator.addMinimalDistanceJunctions();
 
- 	calculator.calculateConnections();
 
- 	if(NKAI_GRAPH_TRACE_LEVEL >= 1)
 
- 		dumpToLog("graph");
 
- }
 
- void ObjectGraph::addObject(const CGObjectInstance * obj)
 
- {
 
- 	if(!hasNodeAt(obj->visitablePos()))
 
- 		nodes[obj->visitablePos()].init(obj);
 
- }
 
- void ObjectGraph::addVirtualBoat(const int3 & pos, const CGObjectInstance * shipyard)
 
- {
 
- 	if(!isVirtualBoat(pos))
 
- 	{
 
- 		virtualBoats[pos] = shipyard->id;
 
- 	}
 
- }
 
- void ObjectGraph::registerJunction(const int3 & pos)
 
- {
 
- 	if(!hasNodeAt(pos))
 
- 		nodes[pos].initJunction();
 
- }
 
- void ObjectGraph::removeObject(const CGObjectInstance * obj)
 
- {
 
- 	nodes[obj->visitablePos()].objectExists = false;
 
- 	if(obj->ID == Obj::BOAT && !isVirtualBoat(obj->visitablePos()))
 
- 	{
 
- 		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)
 
- 	{
 
- 		if(obj && obj->ID == Obj::HERO)
 
- 		{
 
- 			addObject(obj);
 
- 		}
 
- 	}
 
- 	for(auto & node : nodes)
 
- 	{
 
- 		auto pos = node.first;
 
- 		auto paths = ai->pathfinder->getPathInfo(pos);
 
- 		for(AIPath & path : paths)
 
- 		{
 
- 			if(path.getFirstBlockedAction())
 
- 				continue;
 
- 			auto heroPos = path.targetHero->visitablePos();
 
- 			nodes[pos].connections[heroPos].update(
 
- 				std::max(0.0f, path.movementCost()),
 
- 				path.getPathDanger());
 
- 			nodes[heroPos].connections[pos].update(
 
- 				std::max(0.0f, path.movementCost()),
 
- 				path.getPathDanger());
 
- 		}
 
- 	}
 
- }
 
- void ObjectGraph::dumpToLog(std::string visualKey) const
 
- {
 
- 	logVisual->updateWithLock(visualKey, [&](IVisualLogBuilder & logBuilder)
 
- 		{
 
- 			for(auto & tile : nodes)
 
- 			{
 
- 				for(auto & node : tile.second.connections)
 
- 				{
 
- 					if(NKAI_GRAPH_TRACE_LEVEL >= 2)
 
- 					{
 
- 						logAi->trace(
 
- 							"%s -> %s: %f !%d",
 
- 							node.first.toString(),
 
- 							tile.first.toString(),
 
- 							node.second.cost,
 
- 							node.second.danger);
 
- 					}
 
- 					logBuilder.addLine(tile.first, node.first);
 
- 				}
 
- 			}
 
- 		});
 
- }
 
- }
 
 
  |