1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-29 21:56:54 +02:00

Merge pull request #5185 from vcmi/fix_blocked_paths

Fix blocked paths
This commit is contained in:
Ivan Savenko 2025-01-02 21:48:06 +02:00 committed by GitHub
commit dc7e5283c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 17 deletions

View File

@ -24,7 +24,7 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
void replaceWithCurvedPath(rmg::Path & path, const Zone & zone, const int3 & src, bool onlyStraight) void replaceWithCurvedPath(rmg::Path & path, const Zone & zone, const int3 & src, bool onlyStraight /* = true */)
{ {
auto costFunction = rmg::Path::createCurvedCostFunction(zone.area()->getBorder()); auto costFunction = rmg::Path::createCurvedCostFunction(zone.area()->getBorder());
auto pathArea = zone.areaForRoads(); auto pathArea = zone.areaForRoads();

View File

@ -271,6 +271,11 @@ const int3 & Object::getPosition() const
int3 Object::getVisitablePosition() const int3 Object::getVisitablePosition() const
{ {
assert(!dInstances.empty()); assert(!dInstances.empty());
// FIXME: This doesn't take into account Hota monster offset
if (guarded)
return getGuardPos();
for(const auto & instance : dInstances) for(const auto & instance : dInstances)
if(!getArea().contains(instance.getVisitablePosition())) if(!getArea().contains(instance.getVisitablePosition()))
return instance.getVisitablePosition(); return instance.getVisitablePosition();

View File

@ -419,11 +419,13 @@ bool ObjectManager::createMonoliths()
return false; return false;
} }
// Once it can be created, replace with curved path // Object must be placed first so that curved path won't go through occupied tiles
placeObject(rmgObject, guarded, true, objInfo.createRoad);
// Once it can be created, replace with curved path.
replaceWithCurvedPath(path, zone, rmgObject.getVisitablePosition()); replaceWithCurvedPath(path, zone, rmgObject.getVisitablePosition());
zone.connectPath(path); zone.connectPath(path);
placeObject(rmgObject, guarded, true, objInfo.createRoad);
} }
vstd::erase_if(requiredObjects, [](const auto & objInfo) vstd::erase_if(requiredObjects, [](const auto & objInfo)
@ -452,6 +454,8 @@ bool ObjectManager::createRequiredObjects()
logGlobal->error("Failed to fill zone %d due to lack of space", zone.getId()); logGlobal->error("Failed to fill zone %d due to lack of space", zone.getId());
return false; return false;
} }
placeObject(rmgObject, guarded, true, objInfo.createRoad);
if (objInfo.createRoad) if (objInfo.createRoad)
{ {
// Once valid path can be created, replace with curved path // Once valid path can be created, replace with curved path
@ -459,7 +463,6 @@ bool ObjectManager::createRequiredObjects()
} }
zone.connectPath(path); zone.connectPath(path);
placeObject(rmgObject, guarded, true, objInfo.createRoad);
for(const auto & nearby : nearbyObjects) for(const auto & nearby : nearbyObjects)
{ {
@ -672,6 +675,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
if (object.isGuarded()) if (object.isGuarded())
{ {
// Do not route roads through guarded objects
rp->areaVisitable().add(instance->getVisitablePosition()); rp->areaVisitable().add(instance->getVisitablePosition());
} }
} }

View File

@ -76,12 +76,23 @@ bool RoadPlacer::createRoad(const int3 & destination)
auto simpleRoutig = [this, &border](const int3& src, const int3& dst) auto simpleRoutig = [this, &border](const int3& src, const int3& dst)
{ {
if(areaIsolated().contains(dst)) if(std::abs((src - dst).y) == 1)
{ {
return 1000.0f; //Do not route road behind objects that are not visitable from top, such as Monoliths //Do not allow connections straight up through object not visitable from top
if(areaIsolated().contains(dst) || areaIsolated().contains(src))
{
return 1e12f;
}
} }
else else
{ {
if(areaIsolated().contains(dst))
{
//Simply do not route road behind objects that are not visitable from top, such as Monoliths
return 1e6f;
}
}
float ret = dst.dist2d(src); float ret = dst.dist2d(src);
if (visitableTiles.contains(src) || visitableTiles.contains(dst)) if (visitableTiles.contains(src) || visitableTiles.contains(dst))
@ -94,7 +105,6 @@ bool RoadPlacer::createRoad(const int3 & destination)
ret /= dist; ret /= dist;
} }
return ret; return ret;
}
}; };
auto res = path.search(destination, true, simpleRoutig); auto res = path.search(destination, true, simpleRoutig);