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:
parent
d078808c9f
commit
8f1638f78a
@ -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())
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user