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:
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user