From d31789e745a613dfedcbaa5588af565fc03fa7d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Wed, 13 Dec 2023 22:13:42 +0100 Subject: [PATCH] Extra cache for search area --- lib/rmg/Zone.cpp | 32 ++++++++++++++++++++++++++ lib/rmg/Zone.h | 1 + lib/rmg/modificators/ObjectManager.cpp | 29 +++++++++++++++-------- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/lib/rmg/Zone.cpp b/lib/rmg/Zone.cpp index 5f6e12d0c..262a80024 100644 --- a/lib/rmg/Zone.cpp +++ b/lib/rmg/Zone.cpp @@ -177,6 +177,38 @@ rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, const std:: return resultPath; } +rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, const rmg::Area & searchArea) const +///connect current tile to any other free tile within searchArea +{ + auto movementCost = [this](const int3 & s, const int3 & d) + { + if(map.isFree(d)) + return 1; + else if (map.isPossible(d)) + return 2; + return 3; + }; + + rmg::Path freePath(searchArea); + rmg::Path resultPath(searchArea); + freePath.connect(dAreaFree); + + //connect to all pieces + auto goals = connectedAreas(src, onlyStraight); + for(auto & goal : goals) + { + auto path = freePath.search(goal, onlyStraight, movementCost); + if(path.getPathArea().empty()) + return rmg::Path::invalid(); + + freePath.connect(path.getPathArea()); + resultPath.connect(path.getPathArea()); + } + + return resultPath; +} + + rmg::Path Zone::searchPath(const int3 & src, bool onlyStraight, const std::function & areafilter) const ///connect current tile to any other free tile within zone { diff --git a/lib/rmg/Zone.h b/lib/rmg/Zone.h index b6aa3b3ce..cce97f2e4 100644 --- a/lib/rmg/Zone.h +++ b/lib/rmg/Zone.h @@ -66,6 +66,7 @@ public: void connectPath(const rmg::Path & path); rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const std::function & areafilter = AREA_NO_FILTER) const; rmg::Path searchPath(const int3 & src, bool onlyStraight, const std::function & areafilter = AREA_NO_FILTER) const; + rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const rmg::Area & searchArea) const; TModificators getModificators(); diff --git a/lib/rmg/modificators/ObjectManager.cpp b/lib/rmg/modificators/ObjectManager.cpp index 111cec60c..d71d4e42a 100644 --- a/lib/rmg/modificators/ObjectManager.cpp +++ b/lib/rmg/modificators/ObjectManager.cpp @@ -95,7 +95,7 @@ void ObjectManager::updateDistances(std::function dista { RecursiveLock lock(externalAccessMutex); tilesByDistance.clear(); - for (auto tile : zone.areaPossible().getTiles()) //don't need to mark distance for not possible tiles + for (const auto & tile : zone.areaPossible().getTiles()) //don't need to mark distance for not possible tiles { ui32 d = distanceFunction(tile); map.setNearestObjectDistance(tile, std::min(static_cast(d), map.getNearestObjectDistance(tile))); @@ -305,6 +305,7 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg { int3 pos; auto possibleArea = searchArea; + auto cachedArea = zone.areaPossible() + zone.freePaths(); while(true) { pos = findPlaceForObject(possibleArea, obj, weightFunction, optimizer); @@ -322,21 +323,31 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg accessibleArea.add(obj.instances().back()->getPosition(true)); } - auto path = zone.searchPath(accessibleArea, onlyStraight, [&obj, isGuarded](const int3 & t) + rmg::Area subArea; + if (isGuarded) { - if(isGuarded) + const auto & guardedArea = obj.instances().back()->getAccessibleArea(); + const auto & unguardedArea = obj.getAccessibleArea(isGuarded); + subArea = cachedArea.getSubarea([guardedArea, unguardedArea, obj](const int3 & t) { - const auto & guardedArea = obj.instances().back()->getAccessibleArea(); - const auto & unguardedArea = obj.getAccessibleArea(isGuarded); if(unguardedArea.contains(t) && !guardedArea.contains(t)) return false; //guard position is always target if(obj.instances().back()->getPosition(true) == t) return true; - } - return !obj.getArea().contains(t); - }); + + return !obj.getArea().contains(t); + }); + } + else + { + subArea = cachedArea.getSubarea([obj](const int3 & t) + { + return !obj.getArea().contains(t); + }); + } + auto path = zone.searchPath(accessibleArea, onlyStraight, cachedArea); if(path.valid()) { @@ -670,7 +681,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard return false; // Prefer non-blocking tiles, if any - auto entrableTiles = object.getEntrableArea().getTiles(); + const auto & entrableTiles = object.getEntrableArea().getTiles(); int3 entrableTile(-1, -1, -1); if (entrableTiles.empty()) {