mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Merge pull request #1939 from vcmi/fix_top_of_map_objects
Merging after positive review.
This commit is contained in:
@@ -133,6 +133,11 @@ int3 CGObjectInstance::getPosition() const
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int3 CGObjectInstance::getTopVisiblePos() const
|
||||||
|
{
|
||||||
|
return pos - appearance->getTopVisibleOffset();
|
||||||
|
}
|
||||||
|
|
||||||
void CGObjectInstance::setOwner(const PlayerColor & ow)
|
void CGObjectInstance::setOwner(const PlayerColor & ow)
|
||||||
{
|
{
|
||||||
tempOwner = 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)
|
bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
|
||||||
int3 visitablePos() const override;
|
int3 visitablePos() const override;
|
||||||
int3 getPosition() 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 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)
|
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
|
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;
|
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()
|
void ObjectTemplate::calculateVisitableOffset()
|
||||||
{
|
{
|
||||||
for(int y = 0; y < static_cast<int>(getHeight()); y++)
|
for(int y = 0; y < static_cast<int>(getHeight()); y++)
|
||||||
@@ -559,6 +575,7 @@ void ObjectTemplate::recalculate()
|
|||||||
calculateBlockedOffsets();
|
calculateBlockedOffsets();
|
||||||
calculateBlockMapOffset();
|
calculateBlockMapOffset();
|
||||||
calculateVisitableOffset();
|
calculateVisitableOffset();
|
||||||
|
calculateTopVisibleOffset();
|
||||||
|
|
||||||
if (visitable && visitDir == 0)
|
if (visitable && visitDir == 0)
|
||||||
logMod->warn("Template for %s is visitable but has no visitable directions!", animationFile);
|
logMod->warn("Template for %s is visitable but has no visitable directions!", animationFile);
|
||||||
|
@@ -87,7 +87,12 @@ public:
|
|||||||
inline int3 getBlockMapOffset() const
|
inline int3 getBlockMapOffset() const
|
||||||
{
|
{
|
||||||
return blockMapOffset;
|
return blockMapOffset;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
inline int3 getTopVisibleOffset() const
|
||||||
|
{
|
||||||
|
return topVisibleOffset;
|
||||||
|
}
|
||||||
|
|
||||||
// Checks if object is visitable from certain direction. X and Y must be between -1..+1
|
// Checks if object is visitable from certain direction. X and Y must be between -1..+1
|
||||||
bool isVisitableFrom(si8 X, si8 Y) const;
|
bool isVisitableFrom(si8 X, si8 Y) const;
|
||||||
@@ -137,6 +142,7 @@ private:
|
|||||||
std::set<int3> blockedOffsets;
|
std::set<int3> blockedOffsets;
|
||||||
int3 blockMapOffset;
|
int3 blockMapOffset;
|
||||||
int3 visitableOffset;
|
int3 visitableOffset;
|
||||||
|
int3 topVisibleOffset;
|
||||||
|
|
||||||
void recalculate();
|
void recalculate();
|
||||||
|
|
||||||
@@ -146,6 +152,7 @@ private:
|
|||||||
void calculateBlockedOffsets();
|
void calculateBlockedOffsets();
|
||||||
void calculateBlockMapOffset();
|
void calculateBlockMapOffset();
|
||||||
void calculateVisitableOffset();
|
void calculateVisitableOffset();
|
||||||
|
void calculateTopVisibleOffset();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
@@ -112,6 +112,9 @@ int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
obj.setPosition(tile);
|
obj.setPosition(tile);
|
||||||
|
|
||||||
|
if (obj.getVisibleTop().y < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(!searchArea.contains(obj.getArea()) || !searchArea.overlap(obj.getAccessibleArea()))
|
if(!searchArea.contains(obj.getArea()) || !searchArea.overlap(obj.getAccessibleArea()))
|
||||||
continue;
|
continue;
|
||||||
@@ -131,6 +134,9 @@ int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object
|
|||||||
for(const auto & tile : searchArea.getTiles())
|
for(const auto & tile : searchArea.getTiles())
|
||||||
{
|
{
|
||||||
obj.setPosition(tile);
|
obj.setPosition(tile);
|
||||||
|
|
||||||
|
if (obj.getVisibleTop().y < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(!searchArea.contains(obj.getArea()) || !searchArea.overlap(obj.getAccessibleArea()))
|
if(!searchArea.contains(obj.getArea()) || !searchArea.overlap(obj.getAccessibleArea()))
|
||||||
continue;
|
continue;
|
||||||
|
@@ -45,6 +45,11 @@ const Area & Object::Instance::getBlockedArea() const
|
|||||||
return dBlockedAreaCache;
|
return dBlockedAreaCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int3 Object::Instance::getTopTile() const
|
||||||
|
{
|
||||||
|
return object().getTopVisiblePos();
|
||||||
|
}
|
||||||
|
|
||||||
int3 Object::Instance::getPosition(bool isAbsolute) const
|
int3 Object::Instance::getPosition(bool isAbsolute) const
|
||||||
{
|
{
|
||||||
if(isAbsolute)
|
if(isAbsolute)
|
||||||
@@ -284,6 +289,19 @@ const Area & Object::getArea() const
|
|||||||
return dFullAreaCache;
|
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)
|
void Object::Instance::finalize(RmgMap & map)
|
||||||
{
|
{
|
||||||
if(!map.isOnMap(getPosition(true)))
|
if(!map.isOnMap(getPosition(true)))
|
||||||
|
@@ -38,6 +38,7 @@ public:
|
|||||||
void setTemplate(TerrainId terrain); //cache invalidation
|
void setTemplate(TerrainId terrain); //cache invalidation
|
||||||
void setAnyTemplate(); //cache invalidation
|
void setAnyTemplate(); //cache invalidation
|
||||||
|
|
||||||
|
int3 getTopTile() const;
|
||||||
int3 getPosition(bool isAbsolute = false) const;
|
int3 getPosition(bool isAbsolute = false) const;
|
||||||
void setPosition(const int3 & position); //cache invalidation
|
void setPosition(const int3 & position); //cache invalidation
|
||||||
void setPositionRaw(const int3 & position); //no cache invalidation
|
void setPositionRaw(const int3 & position); //no cache invalidation
|
||||||
@@ -75,6 +76,7 @@ public:
|
|||||||
void setTemplate(const TerrainId & terrain);
|
void setTemplate(const TerrainId & terrain);
|
||||||
|
|
||||||
const Area & getArea() const; //lazy cache invalidation
|
const Area & getArea() const; //lazy cache invalidation
|
||||||
|
const int3 getVisibleTop() const;
|
||||||
|
|
||||||
void finalize(RmgMap & map);
|
void finalize(RmgMap & map);
|
||||||
void clear();
|
void clear();
|
||||||
|
Reference in New Issue
Block a user