mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
First attempt to enforce curved paths
This commit is contained in:
@ -190,4 +190,24 @@ const Area & Path::getPathArea() const
|
|||||||
return dPath;
|
return dPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path::MoveCostFunction Path::createCurvedCostFunction(const Area & border)
|
||||||
|
{
|
||||||
|
// Capture by value to ensure the Area object persists
|
||||||
|
return [border = border](const int3& src, const int3& dst) -> float
|
||||||
|
{
|
||||||
|
// Route main roads far from border
|
||||||
|
//float ret = dst.dist2d(src);
|
||||||
|
float ret = dst.dist2d(src);
|
||||||
|
|
||||||
|
float dist = border.distanceSqr(dst);
|
||||||
|
//int3 closestTile = border.nearest(dst);
|
||||||
|
//float dist = dst.chebdist2d(closestTile);
|
||||||
|
if(dist > 1.0f)
|
||||||
|
{
|
||||||
|
ret /= dist * dist;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -21,7 +21,8 @@ namespace rmg
|
|||||||
class Path
|
class Path
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const static std::function<float(const int3 &, const int3 &)> DEFAULT_MOVEMENT_FUNCTION;
|
typedef std::function<float(const int3 &, const int3 &)> MoveCostFunction;
|
||||||
|
const static MoveCostFunction DEFAULT_MOVEMENT_FUNCTION;
|
||||||
|
|
||||||
Path(const Area & area);
|
Path(const Area & area);
|
||||||
Path(const Area & area, const int3 & src);
|
Path(const Area & area, const int3 & src);
|
||||||
@ -42,6 +43,7 @@ public:
|
|||||||
const Area & getPathArea() const;
|
const Area & getPathArea() const;
|
||||||
|
|
||||||
static Path invalid();
|
static Path invalid();
|
||||||
|
static MoveCostFunction createCurvedCostFunction(const Area & border);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -278,24 +278,23 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
|
|||||||
assert(zone.getModificator<ObjectManager>());
|
assert(zone.getModificator<ObjectManager>());
|
||||||
auto & manager = *zone.getModificator<ObjectManager>();
|
auto & manager = *zone.getModificator<ObjectManager>();
|
||||||
auto * monsterType = manager.chooseGuard(connection.getGuardStrength(), true);
|
auto * monsterType = manager.chooseGuard(connection.getGuardStrength(), true);
|
||||||
|
|
||||||
rmg::Area border(zone.area()->getBorder());
|
rmg::Area border(zone.area()->getBorder());
|
||||||
border.unite(otherZone->area()->getBorder());
|
border.unite(otherZone->area()->getBorder());
|
||||||
|
|
||||||
auto costFunction = [&border](const int3 & s, const int3 & d)
|
auto localCostFunction = rmg::Path::createCurvedCostFunction(zone.area()->getBorder());
|
||||||
{
|
auto otherCostFunction = rmg::Path::createCurvedCostFunction(otherZone->area()->getBorder());
|
||||||
return 1.f / (1.f + border.distanceSqr(d));
|
|
||||||
};
|
// TODO: helper function for this sum?
|
||||||
|
|
||||||
auto ourArea = zone.areaPossible() + zone.freePaths();
|
auto ourArea = zone.areaPossible() + zone.freePaths();
|
||||||
auto theirArea = otherZone->areaPossible() + otherZone->freePaths();
|
auto theirArea = otherZone->areaPossible() + otherZone->freePaths();
|
||||||
theirArea.add(guardPos);
|
theirArea.add(guardPos);
|
||||||
rmg::Path ourPath(ourArea);
|
rmg::Path ourPath(ourArea);
|
||||||
rmg::Path theirPath(theirArea);
|
rmg::Path theirPath(theirArea);
|
||||||
ourPath.connect(zone.freePaths().get());
|
ourPath.connect(zone.freePaths().get());
|
||||||
ourPath = ourPath.search(guardPos, true, costFunction);
|
ourPath = ourPath.search(guardPos, true, localCostFunction);
|
||||||
theirPath.connect(otherZone->freePaths().get());
|
theirPath.connect(otherZone->freePaths().get());
|
||||||
theirPath = theirPath.search(guardPos, true, costFunction);
|
theirPath = theirPath.search(guardPos, true, otherCostFunction);
|
||||||
|
|
||||||
if(ourPath.valid() && theirPath.valid())
|
if(ourPath.valid() && theirPath.valid())
|
||||||
{
|
{
|
||||||
|
@ -419,6 +419,11 @@ bool ObjectManager::createMonoliths()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Once it can be created, replace with curved path
|
||||||
|
auto costFunction = rmg::Path::createCurvedCostFunction(zone.area()->getBorder());
|
||||||
|
rmg::Path curvedPath(zone.areaPossible() + zone.freePaths());
|
||||||
|
path = curvedPath.search(rmgObject.getVisitablePosition(), true, costFunction);
|
||||||
|
|
||||||
zone.connectPath(path);
|
zone.connectPath(path);
|
||||||
placeObject(rmgObject, guarded, true, objInfo.createRoad);
|
placeObject(rmgObject, guarded, true, objInfo.createRoad);
|
||||||
}
|
}
|
||||||
@ -449,6 +454,24 @@ 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;
|
||||||
}
|
}
|
||||||
|
if (objInfo.createRoad)
|
||||||
|
{
|
||||||
|
// Once valid path can be created, replace with curved path
|
||||||
|
|
||||||
|
auto costFunction = rmg::Path::createCurvedCostFunction(zone.area()->getBorder());
|
||||||
|
auto pathArea = zone.areaPossible() + zone.freePaths();
|
||||||
|
rmg::Path curvedPath(pathArea);
|
||||||
|
curvedPath.connect(zone.freePaths().get());
|
||||||
|
curvedPath = curvedPath.search(rmgObject.getVisitablePosition(), false, costFunction);
|
||||||
|
if (curvedPath.valid())
|
||||||
|
{
|
||||||
|
path = curvedPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logGlobal->warn("Failed to create curved path for required object at %s", rmgObject.getPosition().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
zone.connectPath(path);
|
zone.connectPath(path);
|
||||||
placeObject(rmgObject, guarded, true, objInfo.createRoad);
|
placeObject(rmgObject, guarded, true, objInfo.createRoad);
|
||||||
|
@ -91,7 +91,7 @@ bool RoadPlacer::createRoad(const int3 & destination)
|
|||||||
float dist = border.distanceSqr(dst);
|
float dist = border.distanceSqr(dst);
|
||||||
if(dist > 1.0f)
|
if(dist > 1.0f)
|
||||||
{
|
{
|
||||||
ret /= dist;
|
ret /= dist * dist;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user