1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Extra cache for search area

This commit is contained in:
Tomasz Zieliński
2023-12-13 22:13:42 +01:00
parent bfea30e318
commit d31789e745
3 changed files with 53 additions and 9 deletions

View File

@@ -177,6 +177,38 @@ rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, const std::
return resultPath; 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<bool(const int3 &)> & areafilter) const rmg::Path Zone::searchPath(const int3 & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter) const
///connect current tile to any other free tile within zone ///connect current tile to any other free tile within zone
{ {

View File

@@ -66,6 +66,7 @@ public:
void connectPath(const rmg::Path & path); void connectPath(const rmg::Path & path);
rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter = AREA_NO_FILTER) const; rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter = AREA_NO_FILTER) const;
rmg::Path searchPath(const int3 & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter = AREA_NO_FILTER) const; rmg::Path searchPath(const int3 & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter = AREA_NO_FILTER) const;
rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const rmg::Area & searchArea) const;
TModificators getModificators(); TModificators getModificators();

View File

@@ -95,7 +95,7 @@ void ObjectManager::updateDistances(std::function<ui32(const int3 & tile)> dista
{ {
RecursiveLock lock(externalAccessMutex); RecursiveLock lock(externalAccessMutex);
tilesByDistance.clear(); 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); ui32 d = distanceFunction(tile);
map.setNearestObjectDistance(tile, std::min(static_cast<float>(d), map.getNearestObjectDistance(tile))); map.setNearestObjectDistance(tile, std::min(static_cast<float>(d), map.getNearestObjectDistance(tile)));
@@ -305,6 +305,7 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg
{ {
int3 pos; int3 pos;
auto possibleArea = searchArea; auto possibleArea = searchArea;
auto cachedArea = zone.areaPossible() + zone.freePaths();
while(true) while(true)
{ {
pos = findPlaceForObject(possibleArea, obj, weightFunction, optimizer); 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)); 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)) if(unguardedArea.contains(t) && !guardedArea.contains(t))
return false; return false;
//guard position is always target //guard position is always target
if(obj.instances().back()->getPosition(true) == t) if(obj.instances().back()->getPosition(true) == t)
return true; 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()) if(path.valid())
{ {
@@ -670,7 +681,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
return false; return false;
// Prefer non-blocking tiles, if any // Prefer non-blocking tiles, if any
auto entrableTiles = object.getEntrableArea().getTiles(); const auto & entrableTiles = object.getEntrableArea().getTiles();
int3 entrableTile(-1, -1, -1); int3 entrableTile(-1, -1, -1);
if (entrableTiles.empty()) if (entrableTiles.empty())
{ {