/* * DangerHitMapAnalyzer.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 "../Pathfinding/AINodeStorage.h" #include "../Engine/PriorityEvaluator.h" namespace NKAI { struct ClusterObjectInfo { float priority = 0.f; float movementCost = 0.f; uint64_t danger = 0; uint8_t turn = 0; }; struct ObjectInstanceIDHash { ObjectInstanceID::hash hash; bool equal(ObjectInstanceID o1, ObjectInstanceID o2) const { return o1 == o2; } }; using ClusterObjects = tbb::concurrent_hash_map; struct ObjectCluster { public: ClusterObjects objects; const CGObjectInstance * blocker; void reset() { objects.clear(); } void addObject(const CGObjectInstance * object, const AIPath & path, float priority); ObjectCluster(const CGObjectInstance * blocker): blocker(blocker) {} ObjectCluster() : ObjectCluster(nullptr) { } std::vector getObjects(const CPlayerSpecificInfoCallback * cb) const; const CGObjectInstance * calculateCenter(const CPlayerSpecificInfoCallback * cb) const; }; using ClusterMap = tbb::concurrent_hash_map, ObjectInstanceIDHash>; class ObjectClusterizer { private: static Obj IgnoredObjectTypes[]; ObjectCluster nearObjects; ObjectCluster farObjects; ClusterMap blockedObjects; const Nullkiller * ai; RewardEvaluator valueEvaluator; bool isUpToDate; std::vector invalidated; public: void clusterize(); std::vector getNearbyObjects() const; std::vector getFarObjects() const; std::vector> getLockedClusters() const; const CGObjectInstance * getBlocker(const AIPath & path) const; std::optional getBlocker(const AIPathNodeInfo & node) const; ObjectClusterizer(const Nullkiller * ai): ai(ai), valueEvaluator(ai), isUpToDate(false){} void validateObjects(); void onObjectRemoved(ObjectInstanceID id); void invalidate(ObjectInstanceID id); void reset() { isUpToDate = false; invalidated.clear(); } private: bool shouldVisitObject(const CGObjectInstance * obj) const; void clusterizeObject( const CGObjectInstance * obj, PriorityEvaluator * priorityEvaluator, std::vector & pathCache, std::vector & heroes); }; }