1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Some refactoring, commiting current state after tests

This commit is contained in:
Tomasz Zieliński 2023-12-06 09:49:41 +01:00
parent 47c1d3dcba
commit 03fa75c51e
3 changed files with 48 additions and 23 deletions

View File

@ -40,7 +40,9 @@ const Area & Object::Instance::getBlockedArea() const
{ {
dBlockedAreaCache.assign(dObject.getBlockedPos()); dBlockedAreaCache.assign(dObject.getBlockedPos());
if(dObject.isVisitable() || dBlockedAreaCache.empty()) 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; return dBlockedAreaCache;
} }
@ -85,9 +87,7 @@ void Object::Instance::setPosition(const int3 & position)
dBlockedAreaCache.clear(); dBlockedAreaCache.clear();
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
dParent.dAccessibleAreaCache.clear(); dParent.clearCachedArea();
dParent.dAccessibleAreaFullCache.clear();
dParent.dFullAreaCache.clear();
} }
void Object::Instance::setPositionRaw(const int3 & position) void Object::Instance::setPositionRaw(const int3 & position)
@ -97,9 +97,7 @@ void Object::Instance::setPositionRaw(const int3 & position)
dObject.pos = dPosition + dParent.getPosition(); dObject.pos = dPosition + dParent.getPosition();
dBlockedAreaCache.clear(); dBlockedAreaCache.clear();
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
dParent.dAccessibleAreaCache.clear(); dParent.clearCachedArea();
dParent.dAccessibleAreaFullCache.clear();
dParent.dFullAreaCache.clear();
} }
auto shift = position + dParent.getPosition() - dObject.pos; auto shift = position + dParent.getPosition() - dObject.pos;
@ -141,9 +139,7 @@ void Object::Instance::clear()
delete &dObject; delete &dObject;
dBlockedAreaCache.clear(); dBlockedAreaCache.clear();
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
dParent.dAccessibleAreaCache.clear(); dParent.clearCachedArea();
dParent.dAccessibleAreaFullCache.clear();
dParent.dFullAreaCache.clear();
} }
bool Object::Instance::isVisitableFrom(const int3 & position) const bool Object::Instance::isVisitableFrom(const int3 & position) const
@ -152,6 +148,11 @@ bool Object::Instance::isVisitableFrom(const int3 & position) const
return dObject.appearance->isVisitableFrom(relPosition.x, relPosition.y); return dObject.appearance->isVisitableFrom(relPosition.x, relPosition.y);
} }
bool Object::Instance::isBlockedVisitable() const
{
return dObject.isBlockedVisitable();
}
CGObjectInstance & Object::Instance::object() CGObjectInstance & Object::Instance::object()
{ {
return dObject; return dObject;
@ -205,9 +206,7 @@ void Object::addInstance(Instance & object)
setGuardedIfMonster(object); setGuardedIfMonster(object);
dInstances.push_back(object); dInstances.push_back(object);
dFullAreaCache.clear(); clearCachedArea();
dAccessibleAreaCache.clear();
dAccessibleAreaFullCache.clear();
} }
Object::Instance & Object::addInstance(CGObjectInstance & object) Object::Instance & Object::addInstance(CGObjectInstance & object)
@ -215,9 +214,7 @@ Object::Instance & Object::addInstance(CGObjectInstance & object)
dInstances.emplace_back(*this, object); dInstances.emplace_back(*this, object);
setGuardedIfMonster(dInstances.back()); setGuardedIfMonster(dInstances.back());
dFullAreaCache.clear(); clearCachedArea();
dAccessibleAreaCache.clear();
dAccessibleAreaFullCache.clear();
return dInstances.back(); return dInstances.back();
} }
@ -226,9 +223,7 @@ Object::Instance & Object::addInstance(CGObjectInstance & object, const int3 & p
dInstances.emplace_back(*this, object, position); dInstances.emplace_back(*this, object, position);
setGuardedIfMonster(dInstances.back()); setGuardedIfMonster(dInstances.back());
dFullAreaCache.clear(); clearCachedArea();
dAccessibleAreaCache.clear();
dAccessibleAreaFullCache.clear();
return dInstances.back(); return dInstances.back();
} }
@ -270,10 +265,25 @@ const rmg::Area & Object::getAccessibleArea(bool exceptLast) const
return dAccessibleAreaFullCache; return dAccessibleAreaFullCache;
} }
const rmg::Area & Object::getBlockVisitableArea() const
{
if(dInstances.empty())
return dBlockVisitableCache;
for(auto i = dInstances.begin(); i != std::prev(dInstances.end()); ++i)
{
// FIXME: Account for blockvis objects with multiple visitable tiles
if (i->isBlockedVisitable())
dAccessibleAreaCache.add(i->getVisitablePosition());
}
return dBlockVisitableCache;
}
void Object::setPosition(const int3 & position) void Object::setPosition(const int3 & position)
{ {
dAccessibleAreaCache.translate(position - dPosition); dAccessibleAreaCache.translate(position - dPosition);
dAccessibleAreaFullCache.translate(position - dPosition); dAccessibleAreaFullCache.translate(position - dPosition);
dBlockVisitableCache.translate(position - dPosition);
dFullAreaCache.translate(position - dPosition); dFullAreaCache.translate(position - dPosition);
dPosition = position; dPosition = position;
@ -374,14 +384,21 @@ void Object::finalize(RmgMap & map, CRandomGenerator & rng)
} }
} }
void Object::clearCachedArea() const
{
dFullAreaCache.clear();
dAccessibleAreaCache.clear();
dAccessibleAreaFullCache.clear();
dBlockVisitableCache.clear();
}
void Object::clear() void Object::clear()
{ {
for(auto & instance : dInstances) for(auto & instance : dInstances)
instance.clear(); instance.clear();
dInstances.clear(); dInstances.clear();
dFullAreaCache.clear();
dAccessibleAreaCache.clear(); clearCachedArea();
dAccessibleAreaFullCache.clear();
} }

View File

@ -35,6 +35,7 @@ public:
int3 getVisitablePosition() const; int3 getVisitablePosition() const;
bool isVisitableFrom(const int3 & tile) const; bool isVisitableFrom(const int3 & tile) const;
bool isBlockedVisitable() const;
const Area & getAccessibleArea() const; const Area & getAccessibleArea() 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
@ -71,6 +72,7 @@ public:
int3 getVisitablePosition() const; int3 getVisitablePosition() const;
const Area & getAccessibleArea(bool exceptLast = false) const; const Area & getAccessibleArea(bool exceptLast = false) const;
const Area & getBlockVisitableArea() const;
const int3 & getPosition() const; const int3 & getPosition() const;
void setPosition(const int3 & position); void setPosition(const int3 & position);
@ -83,12 +85,14 @@ public:
void setGuardedIfMonster(const Instance & object); void setGuardedIfMonster(const Instance & object);
void finalize(RmgMap & map, CRandomGenerator &); void finalize(RmgMap & map, CRandomGenerator &);
void clearCachedArea() const;
void clear(); void clear();
private: private:
std::list<Instance> dInstances; std::list<Instance> dInstances;
mutable Area dFullAreaCache; mutable Area dFullAreaCache;
mutable Area dAccessibleAreaCache, dAccessibleAreaFullCache; mutable Area dAccessibleAreaCache, dAccessibleAreaFullCache;
mutable Area dBlockVisitableCache;
int3 dPosition; int3 dPosition;
ui32 dStrength; ui32 dStrength;
bool guarded; bool guarded;

View File

@ -676,7 +676,8 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
auto instanceAccessibleArea = instance.getAccessibleArea(); auto instanceAccessibleArea = instance.getAccessibleArea();
if(instance.getBlockedArea().getTilesVector().size() == 1) if(instance.getBlockedArea().getTilesVector().size() == 1)
{ {
if(instance.object().appearance->isVisitableFromTop() && instance.object().ID != Obj::CORPSE) //TOOD: Move hardcoded option to template
if(instance.object().appearance->isVisitableFromTop() && !instance.object().isBlockedVisitable())
instanceAccessibleArea.add(instance.getVisitablePosition()); instanceAccessibleArea.add(instance.getVisitablePosition());
} }
@ -684,6 +685,9 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
if(rmgObject.instances().size() == 1) if(rmgObject.instances().size() == 1)
break; break;
// TODO: Do not place blockvis objects so that they block access to existing accessible area
// Either object must be removable, or both must be accessible independently
//condition for good position //condition for good position
if(!blockedArea.overlap(instance.getBlockedArea()) && accessibleArea.overlap(instanceAccessibleArea)) if(!blockedArea.overlap(instance.getBlockedArea()) && accessibleArea.overlap(instanceAccessibleArea))
break; break;