1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
/*
* ObjectGraph.h, 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
*
*/
#pragma once
#include "AINodeStorage.h"
#include "../AIUtility.h"
namespace NKAI
{
class Nullkiller;
struct ObjectLink
{
float cost = 100000; // some big number
uint64_t danger = 0;
std::shared_ptr<ISpecialActionFactory> specialAction;
bool update(float newCost, uint64_t newDanger)
{
if(cost > newCost)
{
cost = newCost;
danger = newDanger;
return true;
}
return false;
}
};
struct ObjectNode
{
ObjectInstanceID objID;
MapObjectID objTypeID;
bool objectExists;
std::unordered_map<int3, ObjectLink> connections;
void init(const CGObjectInstance * obj)
{
objectExists = true;
objID = obj->id;
objTypeID = obj->ID;
}
void initJunction()
{
objectExists = false;
objID = ObjectInstanceID();
objTypeID = Obj();
}
};
class ObjectGraph
{
std::unordered_map<int3, ObjectNode> nodes;
std::unordered_map<int3, ObjectInstanceID> virtualBoats;
public:
ObjectGraph()
:nodes(), virtualBoats()
{
}
void updateGraph(const Nullkiller * ai);
void addObject(const CGObjectInstance * obj);
void registerJunction(const int3 & pos);
void addVirtualBoat(const int3 & pos, const CGObjectInstance * shipyard);
void connectHeroes(const Nullkiller * ai);
void removeObject(const CGObjectInstance * obj);
bool tryAddConnection(const int3 & from, const int3 & to, float cost, uint64_t danger);
void removeConnection(const int3 & from, const int3 & to);
void dumpToLog(std::string visualKey) const;
bool isVirtualBoat(const int3 & tile) const
{
return vstd::contains(virtualBoats, tile);
}
void copyFrom(const ObjectGraph & other)
{
nodes = other.nodes;
virtualBoats = other.virtualBoats;
}
template<typename Func>
void iterateConnections(const int3 & pos, Func fn)
{
for(auto & connection : nodes.at(pos).connections)
{
fn(connection.first, connection.second);
}
}
const ObjectNode & getNode(int3 tile) const
{
return nodes.at(tile);
}
bool hasNodeAt(const int3 & tile) const
{
return vstd::contains(nodes, tile);
}
};
}
|