1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-26 08:41:13 +02:00

Try to not route roads through passable objects

This commit is contained in:
Tomasz Zieliński 2024-03-01 17:48:07 +01:00
parent d078808c9f
commit 8f1638f78a
3 changed files with 30 additions and 7 deletions

View File

@ -597,7 +597,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
{
objectsVisitableArea.add(instance->getVisitablePosition());
objects.push_back(&instance->object());
if(auto * m = zone.getModificator<RoadPlacer>())
if(auto * rp = zone.getModificator<RoadPlacer>())
{
if (instance->object().blockVisit && !instance->object().removable)
{
@ -607,7 +607,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
else if(instance->object().appearance->isVisitableFromTop())
{
//Passable objects
m->areaForRoads().add(instance->getVisitablePosition());
rp->areaForRoads().add(instance->getVisitablePosition());
}
else if(!instance->object().appearance->isVisitableFromTop())
{
@ -621,8 +621,10 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
(!instance->object().blockingAt(tile + int3(0, 1, 0)) &&
instance->object().blockingAt(tile));
});
m->areaIsolated().unite(borderAbove);
rp->areaIsolated().unite(borderAbove);
}
rp->areaVisitable().add(instance->getVisitablePosition());
}
switch (instance->object().ID.toEnum())

View File

@ -52,6 +52,11 @@ rmg::Area & RoadPlacer::areaIsolated()
return isolated;
}
rmg::Area & RoadPlacer::areaVisitable()
{
return visitableTiles;
}
const rmg::Area & RoadPlacer::getRoads() const
{
return roads;
@ -64,7 +69,9 @@ bool RoadPlacer::createRoad(const int3 & dst)
rmg::Path path(searchArea);
path.connect(roads);
auto simpleRoutig = [this](const int3& src, const int3& dst)
const float VISITABLE_PENALTY = 1.33f;
auto simpleRoutig = [this, VISITABLE_PENALTY](const int3& src, const int3& dst)
{
if(areaIsolated().contains(dst))
{
@ -72,14 +79,19 @@ bool RoadPlacer::createRoad(const int3 & dst)
}
else
{
return 1.0f;
auto ret = 1.0f;
if (visitableTiles.contains(src) || visitableTiles.contains(dst))
{
ret *= VISITABLE_PENALTY;
}
return ret;
}
};
auto res = path.search(dst, true, simpleRoutig);
if(!res.valid())
{
auto desperateRoutig = [this](const int3& src, const int3& dst) -> float
auto desperateRoutig = [this, VISITABLE_PENALTY](const int3& src, const int3& dst) -> float
{
//Do not allow connections straight up through object not visitable from top
if(std::abs((src - dst).y) == 1)
@ -98,7 +110,13 @@ bool RoadPlacer::createRoad(const int3 & dst)
}
float weight = dst.dist2dSQ(src);
return weight * weight;
auto ret = weight * weight;
if (visitableTiles.contains(src) || visitableTiles.contains(dst))
{
ret *= VISITABLE_PENALTY;
}
return ret;
};
res = path.search(dst, false, desperateRoutig);

View File

@ -25,8 +25,10 @@ public:
void addRoadNode(const int3 & node);
void connectRoads(); //fills "roads" according to "roadNodes"
// TODO: Use setters?
rmg::Area & areaForRoads();
rmg::Area & areaIsolated();
rmg::Area & areaVisitable();
const rmg::Area & getRoads() const;
protected:
@ -38,6 +40,7 @@ protected:
rmg::Area roads; //all tiles with roads
rmg::Area areaRoads;
rmg::Area isolated;
rmg::Area visitableTiles; // Tiles occupied by removable or passable objects
};
VCMI_LIB_NAMESPACE_END