mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-24 03:47:18 +02:00
Do not place object visible tiles over the top of the map.
This commit is contained in:
parent
9ea746a68c
commit
3c87b3934d
@ -133,6 +133,11 @@ int3 CGObjectInstance::getPosition() const
|
||||
return pos;
|
||||
}
|
||||
|
||||
int3 CGObjectInstance::getTopVisiblePos() const
|
||||
{
|
||||
return pos - appearance->getTopVisibleOffset();
|
||||
}
|
||||
|
||||
void CGObjectInstance::setOwner(const PlayerColor & ow)
|
||||
{
|
||||
tempOwner = ow;
|
||||
|
@ -159,6 +159,7 @@ public:
|
||||
bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
|
||||
int3 visitablePos() const override;
|
||||
int3 getPosition() const override;
|
||||
int3 getTopVisiblePos() const;
|
||||
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos)
|
||||
bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
||||
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
||||
|
@ -524,6 +524,22 @@ bool ObjectTemplate::isVisitableFrom(si8 X, si8 Y) const
|
||||
return dirMap[dy][dx] != 0;
|
||||
}
|
||||
|
||||
void ObjectTemplate::calculateTopVisibleOffset()
|
||||
{
|
||||
for(int y = static_cast<int>(getHeight()) - 1; y >= 0; y--) //Templates start from bottom-right corner
|
||||
{
|
||||
for(int x = 0; x < static_cast<int>(getWidth()); x++)
|
||||
{
|
||||
if (isVisibleAt(x, y))
|
||||
{
|
||||
topVisibleOffset = int3(x, y, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
topVisibleOffset = int3(0, 0, 0);
|
||||
}
|
||||
|
||||
void ObjectTemplate::calculateVisitableOffset()
|
||||
{
|
||||
for(int y = 0; y < static_cast<int>(getHeight()); y++)
|
||||
@ -559,6 +575,7 @@ void ObjectTemplate::recalculate()
|
||||
calculateBlockedOffsets();
|
||||
calculateBlockMapOffset();
|
||||
calculateVisitableOffset();
|
||||
calculateTopVisibleOffset();
|
||||
|
||||
if (visitable && visitDir == 0)
|
||||
logMod->warn("Template for %s is visitable but has no visitable directions!", animationFile);
|
||||
|
@ -87,7 +87,12 @@ public:
|
||||
inline int3 getBlockMapOffset() const
|
||||
{
|
||||
return blockMapOffset;
|
||||
};
|
||||
};
|
||||
|
||||
inline int3 getTopVisibleOffset() const
|
||||
{
|
||||
return topVisibleOffset;
|
||||
}
|
||||
|
||||
// Checks if object is visitable from certain direction. X and Y must be between -1..+1
|
||||
bool isVisitableFrom(si8 X, si8 Y) const;
|
||||
@ -137,6 +142,7 @@ private:
|
||||
std::set<int3> blockedOffsets;
|
||||
int3 blockMapOffset;
|
||||
int3 visitableOffset;
|
||||
int3 topVisibleOffset;
|
||||
|
||||
void recalculate();
|
||||
|
||||
@ -146,6 +152,7 @@ private:
|
||||
void calculateBlockedOffsets();
|
||||
void calculateBlockMapOffset();
|
||||
void calculateVisitableOffset();
|
||||
void calculateTopVisibleOffset();
|
||||
|
||||
public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
|
@ -112,6 +112,9 @@ int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object
|
||||
continue;
|
||||
|
||||
obj.setPosition(tile);
|
||||
|
||||
if (obj.getVisibleTop().y < 0)
|
||||
continue;
|
||||
|
||||
if(!searchArea.contains(obj.getArea()) || !searchArea.overlap(obj.getAccessibleArea()))
|
||||
continue;
|
||||
@ -131,6 +134,9 @@ int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object
|
||||
for(const auto & tile : searchArea.getTiles())
|
||||
{
|
||||
obj.setPosition(tile);
|
||||
|
||||
if (obj.getVisibleTop().y < 0)
|
||||
continue;
|
||||
|
||||
if(!searchArea.contains(obj.getArea()) || !searchArea.overlap(obj.getAccessibleArea()))
|
||||
continue;
|
||||
|
@ -45,6 +45,11 @@ const Area & Object::Instance::getBlockedArea() const
|
||||
return dBlockedAreaCache;
|
||||
}
|
||||
|
||||
int3 Object::Instance::getTopTile() const
|
||||
{
|
||||
return object().getTopVisiblePos();
|
||||
}
|
||||
|
||||
int3 Object::Instance::getPosition(bool isAbsolute) const
|
||||
{
|
||||
if(isAbsolute)
|
||||
@ -284,6 +289,19 @@ const Area & Object::getArea() const
|
||||
return dFullAreaCache;
|
||||
}
|
||||
|
||||
const int3 Object::getVisibleTop() const
|
||||
{
|
||||
int3 topTile(-1, 10000, -1); //Start at the bottom
|
||||
for (const auto& i : dInstances)
|
||||
{
|
||||
if (i.getTopTile().y < topTile.y)
|
||||
{
|
||||
topTile = i.getTopTile();
|
||||
}
|
||||
}
|
||||
return topTile;
|
||||
}
|
||||
|
||||
void Object::Instance::finalize(RmgMap & map)
|
||||
{
|
||||
if(!map.isOnMap(getPosition(true)))
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
void setTemplate(TerrainId terrain); //cache invalidation
|
||||
void setAnyTemplate(); //cache invalidation
|
||||
|
||||
int3 getTopTile() const;
|
||||
int3 getPosition(bool isAbsolute = false) const;
|
||||
void setPosition(const int3 & position); //cache invalidation
|
||||
void setPositionRaw(const int3 & position); //no cache invalidation
|
||||
@ -75,6 +76,7 @@ public:
|
||||
void setTemplate(const TerrainId & terrain);
|
||||
|
||||
const Area & getArea() const; //lazy cache invalidation
|
||||
const int3 getVisibleTop() const;
|
||||
|
||||
void finalize(RmgMap & map);
|
||||
void clear();
|
||||
|
Loading…
x
Reference in New Issue
Block a user