1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

Merge pull request #5149 from vcmi/fix_visitablePos_calls

Fix visitable pos calls
This commit is contained in:
Ivan Savenko 2024-12-25 13:45:51 +02:00 committed by GitHub
commit 4e5d44bc9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 54 additions and 23 deletions

View File

@ -58,6 +58,7 @@ public:
virtual void log(ELogLevel::ELogLevel level, const std::string & message) const = 0; virtual void log(ELogLevel::ELogLevel level, const std::string & message) const = 0;
virtual void log(ELogLevel::ELogLevel level, const boost::format & fmt) const = 0; virtual void log(ELogLevel::ELogLevel level, const boost::format & fmt) const = 0;
virtual ELogLevel::ELogLevel getEffectiveLevel() const = 0;
/// Returns true if a debug/trace log message will be logged, false if not. /// Returns true if a debug/trace log message will be logged, false if not.
/// Useful if performance is important and concatenating the log message is a expensive task. /// Useful if performance is important and concatenating the log message is a expensive task.
@ -67,16 +68,19 @@ public:
template<typename T, typename ... Args> template<typename T, typename ... Args>
void log(ELogLevel::ELogLevel level, const std::string & format, T t, Args ... args) const void log(ELogLevel::ELogLevel level, const std::string & format, T t, Args ... args) const
{ {
try if (getEffectiveLevel() <= level)
{ {
boost::format fmt(format); try
makeFormat(fmt, t, args...); {
log(level, fmt); boost::format fmt(format);
} makeFormat(fmt, t, args...);
catch(...) log(level, fmt);
{ }
log(ELogLevel::ERROR, "Log formatting failed, format was:"); catch(...)
log(ELogLevel::ERROR, format); {
log(ELogLevel::ERROR, "Log formatting failed, format was:");
log(ELogLevel::ERROR, format);
}
} }
} }

View File

@ -146,13 +146,16 @@ void CLogger::log(ELogLevel::ELogLevel level, const std::string & message) const
void CLogger::log(ELogLevel::ELogLevel level, const boost::format & fmt) const void CLogger::log(ELogLevel::ELogLevel level, const boost::format & fmt) const
{ {
try if (getEffectiveLevel() <= level)
{ {
log(level, fmt.str()); try
} {
catch(...) log(level, fmt.str());
{ }
log(ELogLevel::ERROR, "Invalid log format!"); catch (...)
{
log(ELogLevel::ERROR, "Invalid log format!");
}
} }
} }

View File

@ -46,7 +46,7 @@ private:
/// The logger is used to log messages to certain targets of a specific domain/name. /// The logger is used to log messages to certain targets of a specific domain/name.
/// It is thread-safe and can be used concurrently by several threads. /// It is thread-safe and can be used concurrently by several threads.
class DLL_LINKAGE CLogger: public vstd::CLoggerBase class DLL_LINKAGE CLogger final: public vstd::CLoggerBase
{ {
public: public:
ELogLevel::ELogLevel getLevel() const; ELogLevel::ELogLevel getLevel() const;
@ -70,7 +70,7 @@ public:
private: private:
explicit CLogger(const CLoggerDomain & domain); explicit CLogger(const CLoggerDomain & domain);
inline ELogLevel::ELogLevel getEffectiveLevel() const; /// Returns the log level applied on this logger whether directly or indirectly. inline ELogLevel::ELogLevel getEffectiveLevel() const override; /// Returns the log level applied on this logger whether directly or indirectly.
inline void callTargets(const LogRecord & record) const; inline void callTargets(const LogRecord & record) const;
CLoggerDomain domain; CLoggerDomain domain;

View File

@ -255,6 +255,14 @@ Object::Instance & Object::addInstance(CGObjectInstance & object, const int3 & p
return dInstances.back(); return dInstances.back();
} }
bool Object::isVisitable() const
{
return vstd::contains_if(dInstances, [](const Instance & instance)
{
return instance.object().isVisitable();
});
}
const int3 & Object::getPosition() const const int3 & Object::getPosition() const
{ {
return dPosition; return dPosition;
@ -464,6 +472,12 @@ uint32_t rmg::Object::getValue() const
rmg::Area Object::Instance::getBorderAbove() const rmg::Area Object::Instance::getBorderAbove() const
{ {
if (!object().isVisitable())
{
// TODO: Non-visitable objects don't need this, but theoretically could return valid area
return rmg::Area();
}
int3 visitablePos = getVisitablePosition(); int3 visitablePos = getVisitablePosition();
auto areaVisitable = rmg::Area({visitablePos}); auto areaVisitable = rmg::Area({visitablePos});
auto borderAbove = areaVisitable.getBorderOutside(); auto borderAbove = areaVisitable.getBorderOutside();

View File

@ -85,6 +85,7 @@ public:
const Area getEntrableArea() const; const Area getEntrableArea() const;
const Area & getBorderAbove() const; const Area & getBorderAbove() const;
bool isVisitable() const;
const int3 & getPosition() const; const int3 & getPosition() const;
void setPosition(const int3 & position); void setPosition(const int3 & position);
void setTemplate(const TerrainId & terrain, vstd::RNG &); void setTemplate(const TerrainId & terrain, vstd::RNG &);

View File

@ -587,17 +587,22 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
Zone::Lock lock(zone.areaMutex); Zone::Lock lock(zone.areaMutex);
zone.areaPossible()->subtract(object.getArea()); zone.areaPossible()->subtract(object.getArea());
bool keepVisitable = zone.freePaths()->contains(object.getVisitablePosition()); bool keepVisitable = object.isVisitable() && zone.freePaths()->contains(object.getVisitablePosition());
zone.freePaths()->subtract(object.getArea()); //just to avoid areas overlapping zone.freePaths()->subtract(object.getArea()); //just to avoid areas overlapping
if(keepVisitable)
zone.freePaths()->add(object.getVisitablePosition());
zone.areaUsed()->unite(object.getArea()); zone.areaUsed()->unite(object.getArea());
zone.areaUsed()->erase(object.getVisitablePosition()); if (keepVisitable)
{
zone.freePaths()->add(object.getVisitablePosition());
zone.areaUsed()->erase(object.getVisitablePosition());
}
if(guarded) //We assume the monster won't be guarded if(guarded) //We assume the monster won't be guarded
{ {
auto guardedArea = object.instances().back()->getAccessibleArea(); auto guardedArea = object.instances().back()->getAccessibleArea();
guardedArea.add(object.instances().back()->getVisitablePosition()); if (object.isVisitable())
{
guardedArea.add(object.instances().back()->getVisitablePosition());
}
auto areaToBlock = object.getAccessibleArea(true); auto areaToBlock = object.getAccessibleArea(true);
areaToBlock.subtract(guardedArea); areaToBlock.subtract(guardedArea);
zone.areaPossible()->subtract(areaToBlock); zone.areaPossible()->subtract(areaToBlock);
@ -641,7 +646,10 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
// TODO: Add multiple tiles in one operation to avoid multiple invalidation // TODO: Add multiple tiles in one operation to avoid multiple invalidation
for(auto * instance : object.instances()) for(auto * instance : object.instances())
{ {
objectsVisitableArea.add(instance->getVisitablePosition()); if (instance->object().isVisitable())
{
objectsVisitableArea.add(instance->getVisitablePosition());
}
objects.push_back(&instance->object()); objects.push_back(&instance->object());
if(auto * rp = zone.getModificator<RoadPlacer>()) if(auto * rp = zone.getModificator<RoadPlacer>())
{ {

View File

@ -39,5 +39,6 @@ public:
bool isDebugEnabled() const override {return true;} bool isDebugEnabled() const override {return true;}
bool isTraceEnabled() const override {return true;} bool isTraceEnabled() const override {return true;}
ELogLevel::ELogLevel getEffectiveLevel() const override {return ELogLevel::TRACE;}
}; };