|
@@ -40,7 +40,9 @@ const Area & Object::Instance::getBlockedArea() const
|
|
|
{
|
|
|
dBlockedAreaCache.assign(dObject.getBlockedPos());
|
|
|
if(dObject.isVisitable() || dBlockedAreaCache.empty())
|
|
|
- dBlockedAreaCache.add(dObject.visitablePos());
|
|
|
+ if (!dObject.isBlockedVisitable())
|
|
|
+ // Do no assume blocked tile is accessible
|
|
|
+ dBlockedAreaCache.add(dObject.visitablePos());
|
|
|
}
|
|
|
return dBlockedAreaCache;
|
|
|
}
|
|
@@ -85,9 +87,7 @@ void Object::Instance::setPosition(const int3 & position)
|
|
|
|
|
|
dBlockedAreaCache.clear();
|
|
|
dAccessibleAreaCache.clear();
|
|
|
- dParent.dAccessibleAreaCache.clear();
|
|
|
- dParent.dAccessibleAreaFullCache.clear();
|
|
|
- dParent.dFullAreaCache.clear();
|
|
|
+ dParent.clearCachedArea();
|
|
|
}
|
|
|
|
|
|
void Object::Instance::setPositionRaw(const int3 & position)
|
|
@@ -97,9 +97,7 @@ void Object::Instance::setPositionRaw(const int3 & position)
|
|
|
dObject.pos = dPosition + dParent.getPosition();
|
|
|
dBlockedAreaCache.clear();
|
|
|
dAccessibleAreaCache.clear();
|
|
|
- dParent.dAccessibleAreaCache.clear();
|
|
|
- dParent.dAccessibleAreaFullCache.clear();
|
|
|
- dParent.dFullAreaCache.clear();
|
|
|
+ dParent.clearCachedArea();
|
|
|
}
|
|
|
|
|
|
auto shift = position + dParent.getPosition() - dObject.pos;
|
|
@@ -141,9 +139,7 @@ void Object::Instance::clear()
|
|
|
delete &dObject;
|
|
|
dBlockedAreaCache.clear();
|
|
|
dAccessibleAreaCache.clear();
|
|
|
- dParent.dAccessibleAreaCache.clear();
|
|
|
- dParent.dAccessibleAreaFullCache.clear();
|
|
|
- dParent.dFullAreaCache.clear();
|
|
|
+ dParent.clearCachedArea();
|
|
|
}
|
|
|
|
|
|
bool Object::Instance::isVisitableFrom(const int3 & position) const
|
|
@@ -152,6 +148,16 @@ bool Object::Instance::isVisitableFrom(const int3 & position) const
|
|
|
return dObject.appearance->isVisitableFrom(relPosition.x, relPosition.y);
|
|
|
}
|
|
|
|
|
|
+bool Object::Instance::isBlockedVisitable() const
|
|
|
+{
|
|
|
+ return dObject.isBlockedVisitable();
|
|
|
+}
|
|
|
+
|
|
|
+bool Object::Instance::isRemovable() const
|
|
|
+{
|
|
|
+ return dObject.isRemovable();
|
|
|
+}
|
|
|
+
|
|
|
CGObjectInstance & Object::Instance::object()
|
|
|
{
|
|
|
return dObject;
|
|
@@ -205,9 +211,7 @@ void Object::addInstance(Instance & object)
|
|
|
setGuardedIfMonster(object);
|
|
|
dInstances.push_back(object);
|
|
|
|
|
|
- dFullAreaCache.clear();
|
|
|
- dAccessibleAreaCache.clear();
|
|
|
- dAccessibleAreaFullCache.clear();
|
|
|
+ clearCachedArea();
|
|
|
}
|
|
|
|
|
|
Object::Instance & Object::addInstance(CGObjectInstance & object)
|
|
@@ -215,9 +219,7 @@ Object::Instance & Object::addInstance(CGObjectInstance & object)
|
|
|
dInstances.emplace_back(*this, object);
|
|
|
setGuardedIfMonster(dInstances.back());
|
|
|
|
|
|
- dFullAreaCache.clear();
|
|
|
- dAccessibleAreaCache.clear();
|
|
|
- dAccessibleAreaFullCache.clear();
|
|
|
+ clearCachedArea();
|
|
|
return dInstances.back();
|
|
|
}
|
|
|
|
|
@@ -226,9 +228,7 @@ Object::Instance & Object::addInstance(CGObjectInstance & object, const int3 & p
|
|
|
dInstances.emplace_back(*this, object, position);
|
|
|
setGuardedIfMonster(dInstances.back());
|
|
|
|
|
|
- dFullAreaCache.clear();
|
|
|
- dAccessibleAreaCache.clear();
|
|
|
- dAccessibleAreaFullCache.clear();
|
|
|
+ clearCachedArea();
|
|
|
return dInstances.back();
|
|
|
}
|
|
|
|
|
@@ -270,10 +270,56 @@ const rmg::Area & Object::getAccessibleArea(bool exceptLast) const
|
|
|
return dAccessibleAreaFullCache;
|
|
|
}
|
|
|
|
|
|
+const rmg::Area & Object::getBlockVisitableArea() const
|
|
|
+{
|
|
|
+ if(dInstances.empty())
|
|
|
+ return dBlockVisitableCache;
|
|
|
+
|
|
|
+ for(const auto & i : dInstances)
|
|
|
+ {
|
|
|
+ // FIXME: Account for blockvis objects with multiple visitable tiles
|
|
|
+ if (i.isBlockedVisitable())
|
|
|
+ dBlockVisitableCache.add(i.getVisitablePosition());
|
|
|
+ }
|
|
|
+
|
|
|
+ return dBlockVisitableCache;
|
|
|
+}
|
|
|
+
|
|
|
+const rmg::Area & Object::getRemovableArea() const
|
|
|
+{
|
|
|
+ if(dInstances.empty())
|
|
|
+ return dRemovableAreaCache;
|
|
|
+
|
|
|
+ for(const auto & i : dInstances)
|
|
|
+ {
|
|
|
+ if (i.isRemovable())
|
|
|
+ dRemovableAreaCache.unite(i.getBlockedArea());
|
|
|
+ }
|
|
|
+
|
|
|
+ return dRemovableAreaCache;
|
|
|
+}
|
|
|
+
|
|
|
+const rmg::Area Object::getEntrableArea() const
|
|
|
+{
|
|
|
+ // Calculate Area that hero can freely pass
|
|
|
+
|
|
|
+ // Do not use blockVisitTiles, unless they belong to removable objects (resources etc.)
|
|
|
+ // area = accessibleArea - (blockVisitableArea - removableArea)
|
|
|
+
|
|
|
+ rmg::Area entrableArea = getAccessibleArea();
|
|
|
+ rmg::Area blockVisitableArea = getBlockVisitableArea();
|
|
|
+ blockVisitableArea.subtract(getRemovableArea());
|
|
|
+ entrableArea.subtract(blockVisitableArea);
|
|
|
+
|
|
|
+ return entrableArea;
|
|
|
+}
|
|
|
+
|
|
|
void Object::setPosition(const int3 & position)
|
|
|
{
|
|
|
dAccessibleAreaCache.translate(position - dPosition);
|
|
|
dAccessibleAreaFullCache.translate(position - dPosition);
|
|
|
+ dBlockVisitableCache.translate(position - dPosition);
|
|
|
+ dRemovableAreaCache.translate(position - dPosition);
|
|
|
dFullAreaCache.translate(position - dPosition);
|
|
|
|
|
|
dPosition = position;
|
|
@@ -374,14 +420,22 @@ void Object::finalize(RmgMap & map, CRandomGenerator & rng)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void Object::clearCachedArea() const
|
|
|
+{
|
|
|
+ dFullAreaCache.clear();
|
|
|
+ dAccessibleAreaCache.clear();
|
|
|
+ dAccessibleAreaFullCache.clear();
|
|
|
+ dBlockVisitableCache.clear();
|
|
|
+ dRemovableAreaCache.clear();
|
|
|
+}
|
|
|
+
|
|
|
void Object::clear()
|
|
|
{
|
|
|
for(auto & instance : dInstances)
|
|
|
instance.clear();
|
|
|
dInstances.clear();
|
|
|
- dFullAreaCache.clear();
|
|
|
- dAccessibleAreaCache.clear();
|
|
|
- dAccessibleAreaFullCache.clear();
|
|
|
+
|
|
|
+ clearCachedArea();
|
|
|
}
|
|
|
|
|
|
|