[Fix] GF __LoadAtlasMarkInfo WhiteMark pixel kayması çözümü

Kaptan Yosun

Co-Co Admin
Moderatör
Geliştirici
Yardımsever Üye
Usta Üye
Mesaj
1.520
Çözümler
55
Beğeni
2.711
Puan
1.839
Ticaret Puanı
0
:mmt-hakkinda:

Bu konudaki GF tabanlı atlas mark sistemi kullanılırken, görev bulunan NPC’lerin minimap üzerindeki 2×2 WhiteMark noktalarında bir 1 pixel kuzeybatı yönünde kayma gözüme çarptı. Bu kayma yalnızca görev işaretli NPC’lerde görülüyor, normal NPC noktaları ise ilk bakışta doğruymuş gibi duruyordu.

Normalde şöyle iken:
normal.webp


GF __LoadAtlasMarkInfo Fonksiyonuna geçtikten sonra şöyle oluyor:
broken.webp

Neden Daha Önce Fark Etmedik?​

Eski atlas verileri ve önceki yükleme fonksiyonlarında, atlas mark pozisyonları düşük çözünürlüklü / kaba koordinatlar ile işlendiği için bu hata pratikte gizli kalıyordu.
Yeni GF __LoadAtlasMarkInfo yapısında ise atlas koordinatları daha doğru ve doğrudan kullanıldığı için, daha önce fark edilmeyen bu hizalama problemi görünür hale geldi.

Örneğin bu eski Server\Binary\share\locale\xx\map\metin2_map_c1\npc.txt içinden bir örnek, koordinatlar kabaca yazılmış:
Kod:
Genişlet Daralt Kopyala
m    732    390    0    0    0    0    1m    100    1    9009

Bu da yeni Client\Binary\pack\locale\locale\xx\map\metin2_map_c1_point.txt içinden, koordinatlar x100 olacak şekilde tam yazılmış
Kod:
Genişlet Daralt Kopyala
#index    x    y    npc_vnum    enable_helper    icon
0    73200    39000    9009    0    0

Bu ise muhtemelen float precision hesaplarına bir kaynaya yol açıyordu.
Yani sorun yeni fonksiyonun eklediği bir bug değil, önceden var olan fakat maskelenmiş bir mantık hatasının açığa çıkması.


Sebep​

Atlas mark pozisyonları yükleme aşamasında:
  • sprite genişlik / yüksekliklerinin yarısı düşülerek erken merkezleme yapılıyordu
  • render aşamasında ise sprite zaten merkezlenmiş varsayılıyordu
Bu durum:
  • atlas mark pozisyonlarının iki kez merkezlenmesine
  • özellikle WhiteMark içindeki quest highlight pixel’inin 1px Kuzeybatıya kaymasına
    neden oluyordu.

Çözüm​

Mantık katmanları net şekilde ayrıldı:
  • Atlas mark pozisyonları merkez koordinat olarak saklanıyor
  • Sprite boyutuna bağlı yarım genişlik / yükseklik hesapları yalnızca render aşamasında uygulanıyor
Bu sayede:
  • NPC noktaları
  • quest highlight pixel’leri
  • waypoint ve target işaretleri
tamamen aynı referans noktasını kullanarak hizalanmış oldu.

Sonuç​

  • WhiteMark üzerindeki quest pixel kayması tamamen giderildi
  • Atlas ve minimap render mantığı daha tutarlı hale getirildi
  • İleride yapılacak refactor veya görsel değişikliklerde benzer hataların tekrar oluşması engellendi

// Arayın @@ void CPythonMiniMap::__LoadAtlasMarkInfo()
Client\Source\UserInterface\PythonMiniMap.cpp:
Genişlet Daralt Kopyala
        aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f;
        aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f;
// Değiştirin
Client\Source\UserInterface\PythonMiniMap.cpp:
Genişlet Daralt Kopyala
        /* - ATLAS_MARK_INFO [REFACTOR] ------------------------
         * [KaptanYosun Dev Note]
         * Atlas mark positions must be stored as CENTER coordinates.
         *
         * The previous implementation subtracted half of the mark size
         * here, effectively converting the position to top-left space
         * too early. This caused double-centering during rendering and
         * resulted in a 1px north-west offset in quest-highlight pixels.
         *
         * Centering (subtracting half width/height) is now applied ONLY
         * at render time, ensuring consistent alignment between:
         *  - NPC dots
         *  - Quest highlight pixels
         *  - Waypoints and target marks
         *
         * Rule: store logical positions as center, apply sprite offsets
         * only in the rendering layer.
         */
        aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX;
        aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY;
        /* ----------------------------------------------------- */

// Arayın @@ void CPythonMiniMap::RenderAtlas(float fScreenX, float fScreenY)
Client\Source\UserInterface\PythonMiniMap.cpp:
Genişlet Daralt Kopyala
    STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC));
    m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin();
// Altına ekleyin
Client\Source\UserInterface\PythonMiniMap.cpp:
Genişlet Daralt Kopyala
    /* - ATLAS_MARK_INFO [REFACTOR] ------------------------ */
    const float halfWidth = static_cast<float>(m_WhiteMark.GetWidth()) * 0.5f;
    const float halfHeight = static_cast<float>(m_WhiteMark.GetHeight()) * 0.5f;
    /* ----------------------------------------------------- */

// Arayın (2x) @@ void CPythonMiniMap::RenderAtlas(float fScreenX, float fScreenY)
Client\Source\UserInterface\PythonMiniMap.cpp:
Genişlet Daralt Kopyala
        m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY);
// Değiştirin (2x)
Client\Source\UserInterface\PythonMiniMap.cpp:
Genişlet Daralt Kopyala
        /* - ATLAS_MARK_INFO [REFACTOR] ------------------------ */
        m_WhiteMark.SetPosition(
            rAtlasMarkInfo.m_fScreenX - halfWidth,
            rAtlasMarkInfo.m_fScreenY - halfHeight
        );
        /* ----------------------------------------------------- */

Bu fix, GF Atlas Mark sistemini kullanan tüm client’lar için geçerlidir.
 
Geri
Üst