diff --git a/modules/gamelib/ui/uiminimap.lua b/modules/gamelib/ui/uiminimap.lua index e8a50dc1..f98afcda 100644 --- a/modules/gamelib/ui/uiminimap.lua +++ b/modules/gamelib/ui/uiminimap.lua @@ -129,11 +129,11 @@ function UIMinimap:removeFlag(pos, icon, description) end function UIMinimap:updateFlag(flag) - local topLeft, bottomRight = self:getArea() - if self:isFlagVisible(flag, topLeft, bottomRight) then + local point = self:getPoint(flag.pos) + if self:containsPoint(point) and self:getZoom() > 0 then flag:setVisible(true) - flag:setMarginLeft(-5.5 + (self:getWidth() / (bottomRight.x - topLeft.x)) * (flag.pos.x - topLeft.x)) - flag:setMarginTop(-5.5 + (self:getHeight() / (bottomRight.y - topLeft.y)) * (flag.pos.y - topLeft.y)) + flag:setMarginLeft(point.x - self:getX() - flag:getWidth()/2) + flag:setMarginTop(point.y - self:getY() - flag:getHeight()/2) else flag:setVisible(false) end @@ -317,6 +317,4 @@ function UIMinimap:getArea() return topLeft, bottomRight end -function UIMinimap:isFlagVisible(flag, topLeft, bottomRight) - return flag.pos.x >= topLeft.x and flag.pos.x <= bottomRight.x and flag.pos.y >= topLeft.y and flag.pos.y <= bottomRight.y and flag.pos.z == topLeft.z -end + diff --git a/src/client/luafunctions.cpp b/src/client/luafunctions.cpp index 7d57d380..fc3d2896 100644 --- a/src/client/luafunctions.cpp +++ b/src/client/luafunctions.cpp @@ -593,6 +593,7 @@ void Client::registerLuaFunctions() g_lua.bindClassMemberFunction("setCameraPosition", &UIMinimap::setCameraPosition); g_lua.bindClassMemberFunction("setCross", &UIMinimap::setCross); g_lua.bindClassMemberFunction("followCreature", &UIMinimap::followCreature); + g_lua.bindClassMemberFunction("getPoint", &UIMinimap::getPoint); g_lua.bindClassMemberFunction("getPosition", &UIMinimap::getPosition); g_lua.bindClassMemberFunction("getCameraPosition", &UIMinimap::getCameraPosition); g_lua.bindClassMemberFunction("getFollowingCreature", &UIMinimap::getFollowingCreature); diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index 0980cb8f..34e073f2 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -97,18 +97,10 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal { if(screenRect.isEmpty()) return; - if(MMBLOCK_SIZE*scale <= 1) return; - Size mapSize = screenRect.size() / scale; - while(mapSize.width() > 8192 || mapSize.height() > 8192) { - scale *= 2; - mapSize = screenRect.size() / scale; - } - Rect mapRect(0, 0, mapSize); - mapRect.moveCenter(Point(mapCenter.x, mapCenter.y)); - + Rect mapRect = calcMapRect(screenRect, mapCenter, scale); g_painter->saveState(); g_painter->setColor(Color::black); g_painter->drawFilledRect(screenRect); @@ -119,14 +111,15 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal Point p = getBlockOffset(mapRect.topLeft() - Point(1,1)); g_painter->translate(-(mapRect.topLeft() - p)*scale); - if(scale > 1.0f) - g_painter->translate(Point(1,1) * scale * 0.5f); + Size wantedSize = mapRect.size() * scale; + Point off = Point(wantedSize.toPoint() - screenRect.size().toPoint())/2; + g_painter->translate(-off); - for(int y = p.y, ys = 0;y<=mapRect.bottom();y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) { + for(int y = p.y, ys = 0;y<=mapRect.bottom()+1;y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) { if(y < 0 || y >= 65536 - MMBLOCK_SIZE) continue; - for(int x = p.x, xs = 0;x<=mapRect.right();x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) { + for(int x = p.x, xs = 0;x<=mapRect.right()+1;x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) { if(x < 0 || x >= 65536 - MMBLOCK_SIZE) continue; @@ -151,32 +144,50 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal g_painter->restoreSavedState(); } +Point Minimap::getPoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale) +{ + if(screenRect.isEmpty()) + return Point(-1,-1); + if(MMBLOCK_SIZE*scale <= 1) + return Point(-1,-1); + + Rect mapRect = calcMapRect(screenRect, mapCenter, scale); + Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2; + Point posoff = (Point(pos.x,pos.y) - mapRect.topLeft())*scale; + return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2; +} + Position Minimap::getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale) { if(screenRect.isEmpty()) return Position(); - if(MMBLOCK_SIZE*scale <= 1) return Position(); - Position pos(mapCenter); + Rect mapRect = calcMapRect(screenRect, mapCenter, scale); + Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2; + Point pos2d = (point - screenRect.topLeft() + off)/scale + mapRect.topLeft(); + return Position(pos2d.x, pos2d.y, mapCenter.z); +} - Size mapSize = screenRect.size() / scale; - while(mapSize.width() > 8192 || mapSize.height() > 8192) { +Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale) +{ + int w, h; + do { + w = std::ceil(screenRect.width() / scale); + h = std::ceil(screenRect.height() / scale); + if(w % 2 == 0) + w++; + if(h % 2 == 0) + h++; scale *= 2; - mapSize = screenRect.size() / scale; - } - Rect mapRect(0, 0, mapSize); + } while(w > 8192 || h > 8192); + Rect mapRect(0,0,h,w); mapRect.moveCenter(Point(mapCenter.x, mapCenter.y)); - - Point p = (point - screenRect.topLeft() - Point(1,1) * scale * 0.5f)/scale + mapRect.topLeft(); - - pos.x = p.x; - pos.y = p.y; - - return pos; + return mapRect; } + void Minimap::updateTile(const Position& pos, const TilePtr& tile) { MinimapTile minimapTile; diff --git a/src/client/minimap.h b/src/client/minimap.h index a11210e0..73e574b6 100644 --- a/src/client/minimap.h +++ b/src/client/minimap.h @@ -82,6 +82,7 @@ public: void clean(); void draw(const Rect& screenRect, const Position& mapCenter, float scale); + Point getPoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale); Position getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale); void updateTile(const Position& pos, const TilePtr& tile); @@ -91,6 +92,7 @@ public: void saveOtmm(const std::string& fileName); private: + Rect calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale); bool hasBlock(const Position& pos) { return m_tileBlocks[pos.z].find(getBlockIndex(pos)) != m_tileBlocks[pos.z].end(); } MinimapBlock& getBlock(const Position& pos) { return m_tileBlocks[pos.z][getBlockIndex(pos)]; } Point getBlockOffset(const Point& pos) { return Point(pos.x - pos.x % MMBLOCK_SIZE, diff --git a/src/client/uiminimap.cpp b/src/client/uiminimap.cpp index 37a91758..98942ce6 100644 --- a/src/client/uiminimap.cpp +++ b/src/client/uiminimap.cpp @@ -80,6 +80,11 @@ void UIMinimap::setCameraPosition(const Position& pos) m_cameraPosition = pos; } +Point UIMinimap::getPoint(const Position& pos) +{ + return g_minimap.getPoint(pos, getPaddingRect(), getCameraPosition(), m_scale); +} + Position UIMinimap::getPosition(const Point& mousePos) { return g_minimap.getPosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale); diff --git a/src/client/uiminimap.h b/src/client/uiminimap.h index dcf72ae4..7e713d90 100644 --- a/src/client/uiminimap.h +++ b/src/client/uiminimap.h @@ -43,6 +43,7 @@ public: void setCross(bool enable) { m_crossEnabled = enable; } void followCreature(const CreaturePtr& creature); + Point getPoint(const Position& pos); Position getPosition(const Point& mousePos); Position getCameraPosition(); CreaturePtr getFollowingCreature() { return m_followingCreature; }