mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Do not hide roads behind objects
This commit is contained in:
@@ -359,6 +359,7 @@ void Object::setPosition(const int3 & position)
|
|||||||
dVisitableCache.translate(shift);
|
dVisitableCache.translate(shift);
|
||||||
dRemovableAreaCache.translate(shift);
|
dRemovableAreaCache.translate(shift);
|
||||||
dFullAreaCache.translate(shift);
|
dFullAreaCache.translate(shift);
|
||||||
|
dBorderAboveCache.translate(shift);
|
||||||
|
|
||||||
dPosition = position;
|
dPosition = position;
|
||||||
for(auto& i : dInstances)
|
for(auto& i : dInstances)
|
||||||
@@ -386,6 +387,16 @@ const Area & Object::getArea() const
|
|||||||
return dFullAreaCache;
|
return dFullAreaCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Area & Object::getBorderAbove() const
|
||||||
|
{
|
||||||
|
if(dBorderAboveCache.empty())
|
||||||
|
{
|
||||||
|
for(const auto & instance : dInstances)
|
||||||
|
dBorderAboveCache.unite(instance.getBorderAbove());
|
||||||
|
}
|
||||||
|
return dBorderAboveCache;
|
||||||
|
}
|
||||||
|
|
||||||
const int3 Object::getVisibleTop() const
|
const int3 Object::getVisibleTop() const
|
||||||
{
|
{
|
||||||
if (visibleTopOffset)
|
if (visibleTopOffset)
|
||||||
@@ -445,6 +456,20 @@ uint32_t rmg::Object::getValue() const
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rmg::Area Object::Instance::getBorderAbove() const
|
||||||
|
{
|
||||||
|
int3 visitablePos = getVisitablePosition();
|
||||||
|
auto areaVisitable = rmg::Area({visitablePos});
|
||||||
|
auto borderAbove = areaVisitable.getBorderOutside();
|
||||||
|
vstd::erase_if(borderAbove, [&](const int3 & tile)
|
||||||
|
{
|
||||||
|
return tile.y >= visitablePos.y ||
|
||||||
|
(!object().blockingAt(tile + int3(0, 1, 0)) &&
|
||||||
|
object().blockingAt(tile));
|
||||||
|
});
|
||||||
|
return borderAbove;
|
||||||
|
}
|
||||||
|
|
||||||
void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
|
void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
|
||||||
{
|
{
|
||||||
if(!map.isOnMap(getPosition(true)))
|
if(!map.isOnMap(getPosition(true)))
|
||||||
@@ -501,6 +526,7 @@ void Object::clearCachedArea() const
|
|||||||
dBlockVisitableCache.clear();
|
dBlockVisitableCache.clear();
|
||||||
dVisitableCache.clear();
|
dVisitableCache.clear();
|
||||||
dRemovableAreaCache.clear();
|
dRemovableAreaCache.clear();
|
||||||
|
dBorderAboveCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::clear()
|
void Object::clear()
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public:
|
|||||||
bool isBlockedVisitable() const;
|
bool isBlockedVisitable() const;
|
||||||
bool isRemovable() const;
|
bool isRemovable() const;
|
||||||
const Area & getAccessibleArea() const;
|
const Area & getAccessibleArea() const;
|
||||||
|
Area getBorderAbove() const;
|
||||||
void setTemplate(TerrainId terrain, CRandomGenerator &); //cache invalidation
|
void setTemplate(TerrainId terrain, CRandomGenerator &); //cache invalidation
|
||||||
void setAnyTemplate(CRandomGenerator &); //cache invalidation
|
void setAnyTemplate(CRandomGenerator &); //cache invalidation
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ public:
|
|||||||
const Area & getVisitableArea() const;
|
const Area & getVisitableArea() const;
|
||||||
const Area & getRemovableArea() const;
|
const Area & getRemovableArea() const;
|
||||||
const Area getEntrableArea() const;
|
const Area getEntrableArea() const;
|
||||||
|
const Area & getBorderAbove() const;
|
||||||
|
|
||||||
const int3 & getPosition() const;
|
const int3 & getPosition() const;
|
||||||
void setPosition(const int3 & position);
|
void setPosition(const int3 & position);
|
||||||
@@ -104,6 +106,7 @@ private:
|
|||||||
mutable Area dBlockVisitableCache;
|
mutable Area dBlockVisitableCache;
|
||||||
mutable Area dVisitableCache;
|
mutable Area dVisitableCache;
|
||||||
mutable Area dRemovableAreaCache;
|
mutable Area dRemovableAreaCache;
|
||||||
|
mutable Area dBorderAboveCache;
|
||||||
int3 dPosition;
|
int3 dPosition;
|
||||||
mutable std::optional<int3> visibleTopOffset;
|
mutable std::optional<int3> visibleTopOffset;
|
||||||
mutable std::list<Object::Instance*> cachedInstanceList;
|
mutable std::list<Object::Instance*> cachedInstanceList;
|
||||||
|
|||||||
@@ -648,15 +648,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
|
|||||||
else if(!instance->object().appearance->isVisitableFromTop())
|
else if(!instance->object().appearance->isVisitableFromTop())
|
||||||
{
|
{
|
||||||
// Do not route road behind visitable tile
|
// Do not route road behind visitable tile
|
||||||
int3 visitablePos = instance->getVisitablePosition();
|
auto borderAbove = instance->getBorderAbove();
|
||||||
auto areaVisitable = rmg::Area({visitablePos});
|
|
||||||
auto borderAbove = areaVisitable.getBorderOutside();
|
|
||||||
vstd::erase_if(borderAbove, [&](const int3 & tile)
|
|
||||||
{
|
|
||||||
return tile.y >= visitablePos.y ||
|
|
||||||
(!instance->object().blockingAt(tile + int3(0, 1, 0)) &&
|
|
||||||
instance->object().blockingAt(tile));
|
|
||||||
});
|
|
||||||
rp->areaIsolated().unite(borderAbove);
|
rp->areaIsolated().unite(borderAbove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,11 +77,13 @@ bool RoadPlacer::createRoad(const int3 & dst)
|
|||||||
{
|
{
|
||||||
if(areaIsolated().contains(dst))
|
if(areaIsolated().contains(dst))
|
||||||
{
|
{
|
||||||
return 1000.0f; //Do not route road behind objects that are not visitable from top
|
return 1000.0f; //Do not route road behind objects that are not visitable from top, such as Monoliths
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto ret = 1.0f;
|
float weight = dst.dist2dSQ(src);
|
||||||
|
auto ret = weight * weight;
|
||||||
|
|
||||||
if (visitableTiles.contains(src) || visitableTiles.contains(dst))
|
if (visitableTiles.contains(src) || visitableTiles.contains(dst))
|
||||||
{
|
{
|
||||||
ret *= VISITABLE_PENALTY;
|
ret *= VISITABLE_PENALTY;
|
||||||
|
|||||||
@@ -966,6 +966,10 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
|
|||||||
if (zone.freePaths()->overlap(areaToBlock) || roads.overlap(areaToBlock) || manager.getVisitableArea().overlap(areaToBlock))
|
if (zone.freePaths()->overlap(areaToBlock) || roads.overlap(areaToBlock) || manager.getVisitableArea().overlap(areaToBlock))
|
||||||
return -1.f;
|
return -1.f;
|
||||||
|
|
||||||
|
// Add huge penalty for objects hiding roads
|
||||||
|
if (rmgObject.getBorderAbove().overlap(roads))
|
||||||
|
bestDistance /= 10.0f;
|
||||||
|
|
||||||
return bestDistance;
|
return bestDistance;
|
||||||
}, guarded, false, ObjectManager::OptimizeType::BOTH);
|
}, guarded, false, ObjectManager::OptimizeType::BOTH);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user