From 3c87b3934dbcde406b711e7f446e5f3e3a780630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Mon, 10 Apr 2023 19:26:53 +0200 Subject: [PATCH 1/2] Do not place object visible tiles over the top of the map. --- lib/mapObjects/CObjectHandler.cpp | 5 +++++ lib/mapObjects/CObjectHandler.h | 1 + lib/mapObjects/ObjectTemplate.cpp | 17 +++++++++++++++++ lib/mapObjects/ObjectTemplate.h | 9 ++++++++- lib/rmg/ObjectManager.cpp | 6 ++++++ lib/rmg/RmgObject.cpp | 18 ++++++++++++++++++ lib/rmg/RmgObject.h | 2 ++ 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index f7658209e..a2169e341 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -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; diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index f79fb3d79..cdf7f6136 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -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 getBlockedPos() const; //returns set of positions blocked by this object diff --git a/lib/mapObjects/ObjectTemplate.cpp b/lib/mapObjects/ObjectTemplate.cpp index ad022cdb0..cf36e66a6 100644 --- a/lib/mapObjects/ObjectTemplate.cpp +++ b/lib/mapObjects/ObjectTemplate.cpp @@ -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(getHeight()) - 1; y >= 0; y--) //Templates start from bottom-right corner + { + for(int x = 0; x < static_cast(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(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); diff --git a/lib/mapObjects/ObjectTemplate.h b/lib/mapObjects/ObjectTemplate.h index 64e2e46ea..dcc9f7b90 100644 --- a/lib/mapObjects/ObjectTemplate.h +++ b/lib/mapObjects/ObjectTemplate.h @@ -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 blockedOffsets; int3 blockMapOffset; int3 visitableOffset; + int3 topVisibleOffset; void recalculate(); @@ -146,6 +152,7 @@ private: void calculateBlockedOffsets(); void calculateBlockMapOffset(); void calculateVisitableOffset(); + void calculateTopVisibleOffset(); public: template void serialize(Handler &h, const int version) diff --git a/lib/rmg/ObjectManager.cpp b/lib/rmg/ObjectManager.cpp index 5143706d4..4f2b293b6 100644 --- a/lib/rmg/ObjectManager.cpp +++ b/lib/rmg/ObjectManager.cpp @@ -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; diff --git a/lib/rmg/RmgObject.cpp b/lib/rmg/RmgObject.cpp index 3b76a00f1..a073e9614 100644 --- a/lib/rmg/RmgObject.cpp +++ b/lib/rmg/RmgObject.cpp @@ -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))) diff --git a/lib/rmg/RmgObject.h b/lib/rmg/RmgObject.h index 24a6f51b2..a164b9161 100644 --- a/lib/rmg/RmgObject.h +++ b/lib/rmg/RmgObject.h @@ -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(); From 4bd3cc16793e43272c8373c4c56ce5cd6765fa75 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Mon, 10 Apr 2023 20:45:41 +0200 Subject: [PATCH 2/2] Update lib/mapObjects/ObjectTemplate.h Co-authored-by: Nordsoft91 --- lib/mapObjects/ObjectTemplate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mapObjects/ObjectTemplate.h b/lib/mapObjects/ObjectTemplate.h index dcc9f7b90..ef48b0b57 100644 --- a/lib/mapObjects/ObjectTemplate.h +++ b/lib/mapObjects/ObjectTemplate.h @@ -87,7 +87,7 @@ public: inline int3 getBlockMapOffset() const { return blockMapOffset; - }; + } inline int3 getTopVisibleOffset() const {