Jump to content

MiniMap & Atlas (client)


Recommended Posts

Hello everyone, i'm developing a section of ingame wiki which I think I'll release once finished, and I came across a (probably stupid) problem, yet I can't solve it. I'm creating a second MiniMap module called MiniMapWiki which is made of its relative cpp python module PythonMiniMapWikimodule.cpp, the derived class (CScreen & Singleton) MiniMapWiki.cpp & .h just as normal MiniMap and Python functions in uiMiniMapWiki.py. Client Binary part is a refactored copy of already existing function. Module Initialization (initMiniMapWiki()) is correctly added in StdAfx.h and UserInterface.cpp, and python part initialization is handled by interfacemodule.py when creating other windows in def __MakeWindows(self). The error i recive occurs after character selection and just before loading is done and it throws an Assertion Failed error of ms_singleton. I can't really get where the problem is but it might be a double initialization or a missing one.(Debug mode no syserr just assertion failed message) I'll paste my 3 c++ files here. Hope someone can help me find it out, however i'll keep searching on my own.

PythonMiniMapWiki.cpp

Spoiler

#include "StdAfx.h"
#include "../eterLib/StateManager.h"
#include "../eterLib/GrpSubImage.h"
#include "../eterlib/Camera.h"
#include "../EterPack/EterPackManager.h"

#include "PythonMiniMapWiki.h"
#include "PythonBackground.h"
#include "PythonCharacterManager.h"
#include "PythonGuild.h"

#include "AbstractPlayer.h"

#include "../eterPythonLib/PythonWindowManager.h"

void CPythonMiniMapWiki::AddObserver(DWORD dwVID, float fSrcX, float fSrcY)
{
    std::map<DWORD, SObserver>::iterator f = m_kMap_dwVID_kObserver.find(dwVID);
    if (m_kMap_dwVID_kObserver.end() == f)
    {
        SObserver kObserver;
        kObserver.dwSrcTime = ELTimer_GetMSec();
        kObserver.dwDstTime = kObserver.dwSrcTime + 1000;
        kObserver.fSrcX = fSrcX;
        kObserver.fSrcY = fSrcY;
        kObserver.fDstX = fSrcX;
        kObserver.fDstY = fSrcY;
        kObserver.fCurX = fSrcX;
        kObserver.fCurY = fSrcY;
        m_kMap_dwVID_kObserver.insert(std::map<DWORD, SObserver>::value_type(dwVID, kObserver));
    }
    else
    {
        SObserver& rkObserver = f->second;
        rkObserver.dwSrcTime = ELTimer_GetMSec();
        rkObserver.dwDstTime = rkObserver.dwSrcTime + 1000;
        rkObserver.fSrcX = fSrcX;
        rkObserver.fSrcY = fSrcY;
        rkObserver.fDstX = fSrcX;
        rkObserver.fDstY = fSrcY;
        rkObserver.fCurX = fSrcX;
        rkObserver.fCurY = fSrcY;
    }
}

void CPythonMiniMapWiki::MoveObserver(DWORD dwVID, float fDstX, float fDstY)
{
    std::map<DWORD, SObserver>::iterator f = m_kMap_dwVID_kObserver.find(dwVID);
    if (m_kMap_dwVID_kObserver.end() == f)
        return;

    SObserver& rkObserver = f->second;
    rkObserver.dwSrcTime = ELTimer_GetMSec();
    rkObserver.dwDstTime = rkObserver.dwSrcTime + 1000;
    rkObserver.fSrcX = rkObserver.fCurX;
    rkObserver.fSrcY = rkObserver.fCurY;
    rkObserver.fDstX = fDstX;
    rkObserver.fDstY = fDstY;
}

void CPythonMiniMapWiki::RemoveObserver(DWORD dwVID)
{
    m_kMap_dwVID_kObserver.erase(dwVID);
}

void CPythonMiniMapWiki::SetCenterPosition(float fCenterX, float fCenterY)
{
    m_fCenterX = fCenterX;
    m_fCenterY = fCenterY;

    CMapOutdoor& rkMap = CPythonBackground::Instance().GetMapOutdoorRef();
    for (BYTE byTerrainNum = 0; byTerrainNum < AROUND_AREA_NUM; ++byTerrainNum)
    {
        m_lpMiniMapTexture[byTerrainNum] = NULL;
        CTerrain * pTerrain;
        if (rkMap.GetTerrainPointer(byTerrainNum, &pTerrain))
            m_lpMiniMapTexture[byTerrainNum] = pTerrain->GetMiniMapTexture();
    }

    const TOutdoorMapCoordinate & rOutdoorMapCoord = rkMap.GetCurCoordinate();

    m_fCenterCellX = (m_fCenterX - (float)(rOutdoorMapCoord.m_sTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE)) / (float)(CTerrainImpl::CELLSCALE);
    m_fCenterCellY = (m_fCenterY - (float)(rOutdoorMapCoord.m_sTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE)) / (float)(CTerrainImpl::CELLSCALE);

    __SetPosition();
}

void CPythonMiniMapWiki::Update(float fCenterX, float fCenterY)
{
    CPythonBackground& rkBG = CPythonBackground::Instance();
    if (!rkBG.IsMapOutdoor())
        return;

    // ¹Ì´Ï¸Ê ±×¸² °»½Å
    if (m_fCenterX != fCenterX || m_fCenterY != fCenterY)
        SetCenterPosition(fCenterX, fCenterY);

    // ij¸¯ÅÍ ¸®½ºÆ® °»½Å
    m_OtherPCPositionVector.clear();
    m_PartyPCPositionVector.clear();
    m_NPCPositionVector.clear();
    m_MonsterPositionVector.clear();
    m_WarpPositionVector.clear();

    float fooCellScale = 1.0f / ((float)CTerrainImpl::CELLSCALE);

    CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();

    CInstanceBase* pkInstMain = rkChrMgr.GetMainInstancePtr();
    if (!pkInstMain)
        return;

    CPythonCharacterManager::CharacterIterator i;
    for (i = rkChrMgr.CharacterInstanceBegin(); i != rkChrMgr.CharacterInstanceEnd(); ++i)
    {
        CInstanceBase* pkInstEach = *i;

        TPixelPosition kInstancePosition;
        pkInstEach->NEW_GetPixelPosition(&kInstancePosition);
        float fDistanceFromCenterX = (kInstancePosition.x - m_fCenterX) * fooCellScale * m_fScale;
        float fDistanceFromCenterY = (kInstancePosition.y - m_fCenterY) * fooCellScale * m_fScale;
        if (fabs(fDistanceFromCenterX) >= m_fMiniMapRadius || fabs(fDistanceFromCenterY) >= m_fMiniMapRadius)
            continue;

        float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY);
        if (fDistanceFromCenter >= m_fMiniMapRadius)
            continue;

        TMarkPosition aMarkPosition;

        if (pkInstEach->IsPC() && !pkInstEach->IsInvisibility())
        {
            if (pkInstEach == CPythonCharacterManager::Instance().GetMainInstancePtr())
                continue;

            aMarkPosition.m_fX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
            aMarkPosition.m_fY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;
            aMarkPosition.m_eNameColor = pkInstEach->GetNameColorIndex();
            if (aMarkPosition.m_eNameColor == CInstanceBase::NAMECOLOR_PARTY)
                m_PartyPCPositionVector.push_back(aMarkPosition);
            else
                m_OtherPCPositionVector.push_back(aMarkPosition);
        }
#ifdef ENABLE_OFFLINE_SHOP
        else if (pkInstEach->GetRace() == 30000)
        {
            aMarkPosition.m_fX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
            aMarkPosition.m_fY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;
            aMarkPosition.m_eNameColor = pkInstEach->GetNameColorIndex();
            m_NPCPositionVector.push_back(aMarkPosition);
        }
#endif
        else if (pkInstEach->IsNPC())
        {
            aMarkPosition.m_fX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
            aMarkPosition.m_fY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;

            m_NPCPositionVector.push_back(aMarkPosition);
        }
        else if (pkInstEach->IsEnemy())
        {
            aMarkPosition.m_fX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
            aMarkPosition.m_fY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;

            m_MonsterPositionVector.push_back(aMarkPosition);
        }
        else if (pkInstEach->IsWarp())
        {
            aMarkPosition.m_fX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
            aMarkPosition.m_fY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;

            m_WarpPositionVector.push_back(aMarkPosition);
        }
    }

    {
        DWORD dwCurTime = ELTimer_GetMSec();

        std::map<DWORD, SObserver>::iterator i;
        for (i = m_kMap_dwVID_kObserver.begin(); i != m_kMap_dwVID_kObserver.end(); ++i)
        {
            SObserver& rkObserver = i->second;

            float fPos = float(dwCurTime - rkObserver.dwSrcTime) / float(rkObserver.dwDstTime - rkObserver.dwSrcTime);
            if (fPos<0.0f) fPos = 0.0f;
            else if (fPos>1.0f) fPos = 1.0f;

            rkObserver.fCurX = (rkObserver.fDstX - rkObserver.fSrcX)*fPos + rkObserver.fSrcX;
            rkObserver.fCurY = (rkObserver.fDstY - rkObserver.fSrcY)*fPos + rkObserver.fSrcY;

            TPixelPosition kInstancePosition;
            kInstancePosition.x = rkObserver.fCurX;
            kInstancePosition.y = rkObserver.fCurY;
            kInstancePosition.z = 0.0f;

            float fDistanceFromCenterX = (kInstancePosition.x - m_fCenterX) * fooCellScale * m_fScale;
            float fDistanceFromCenterY = (kInstancePosition.y - m_fCenterY) * fooCellScale * m_fScale;
            if (fabs(fDistanceFromCenterX) >= m_fMiniMapRadius || fabs(fDistanceFromCenterY) >= m_fMiniMapRadius)
                continue;

            float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY);
            if (fDistanceFromCenter >= m_fMiniMapRadius)
                continue;

            TMarkPosition aMarkPosition;
            aMarkPosition.m_fX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
            aMarkPosition.m_fY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;
            aMarkPosition.m_eNameColor = CInstanceBase::NAMECOLOR_PARTY;
            m_PartyPCPositionVector.push_back(aMarkPosition);
        }
    }

    {
        TAtlasMarkInfoVector::iterator itor = m_AtlasWayPointInfoVector.begin();
        for (; itor != m_AtlasWayPointInfoVector.end(); ++itor)
        {
            TAtlasMarkInfo & rAtlasMarkInfo = *itor;

            if (TYPE_TARGET != rAtlasMarkInfo.m_byType)
                continue;

            if (0 != rAtlasMarkInfo.m_dwChrVID)
            {
                CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(rAtlasMarkInfo.m_dwChrVID);
                if (pInstance)
                {
                    TPixelPosition kPixelPosition;
                    pInstance->NEW_GetPixelPosition(&kPixelPosition);
                    __UpdateWayPoint(&rAtlasMarkInfo, kPixelPosition.x, kPixelPosition.y);
                }
            }

            const float c_fMiniMapWindowRadius = 55.0f;

            float fDistanceFromCenterX = (rAtlasMarkInfo.m_fX - m_fCenterX) * fooCellScale * m_fScale;
            float fDistanceFromCenterY = (rAtlasMarkInfo.m_fY - m_fCenterY) * fooCellScale * m_fScale;
            float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY);

            if (fDistanceFromCenter >= c_fMiniMapWindowRadius)
            {
                float fRadianX = acosf(fDistanceFromCenterX / fDistanceFromCenter);
                float fRadianY = asinf(fDistanceFromCenterY / fDistanceFromCenter);
                fDistanceFromCenterX = 55.0f * cosf(fRadianX);
                fDistanceFromCenterY = 55.0f * sinf(fRadianY);
                rAtlasMarkInfo.m_fMiniMapX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX + 2.0f;
                rAtlasMarkInfo.m_fMiniMapY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY + 2.0f;
            }
            else
            {
                rAtlasMarkInfo.m_fMiniMapX = (m_fWidth - (float)m_WhiteMark.GetWidth()) / 2.0f + fDistanceFromCenterX + m_fScreenX;
                rAtlasMarkInfo.m_fMiniMapY = (m_fHeight - (float)m_WhiteMark.GetHeight()) / 2.0f + fDistanceFromCenterY + m_fScreenY;
            }
        }
    }
}

void CPythonMiniMapWiki::Render(float fScreenX, float fScreenY)
{
    CPythonBackground& rkBG = CPythonBackground::Instance();
    if (!rkBG.IsMapOutdoor())
        return;

    if (!m_bShow)
        return;

    if (!rkBG.IsMapReady())
        return;

    if (m_fScreenX != fScreenX || m_fScreenY != fScreenY)
    {
        m_fScreenX = fScreenX;
        m_fScreenY = fScreenY;
        __SetPosition();
    }

    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);

    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);

    STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);

    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

    STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

    STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFF000000);

    STATEMANAGER.SetTexture(1, m_MiniMapFilterGraphicImageInstance.GetTexturePointer()->GetD3DTexture());
    STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matMiniMapCover);

    STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
    STATEMANAGER.SetStreamSource(0, m_VertexBuffer.GetD3DVertexBuffer(), 20);
    STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0);
    STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld);

    for (BYTE byTerrainNum = 0; byTerrainNum < AROUND_AREA_NUM; ++byTerrainNum)
    {
        LPDIRECT3DTEXTURE8 pMiniMapTexture = m_lpMiniMapTexture[byTerrainNum];
        STATEMANAGER.SetTexture(0, pMiniMapTexture);
        if (pMiniMapTexture)
        {
            CStateManager& rkSttMgr = CStateManager::Instance();
            rkSttMgr.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, byTerrainNum * 4, 4, byTerrainNum * 6, 2);
        }
        else
        {
            STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
            STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, byTerrainNum * 4, 4, byTerrainNum * 6, 2);
            STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
        }
    }

    STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);

    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG2);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG2);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP);

    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);

    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
    STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);

    SetDiffuseOperation();
    STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matIdentity);

    STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);

    TInstancePositionVectorIterator aIterator;

    if (m_fScale >= 2.0f)
    {
        // Monster
        STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_MOB));//m_MarkTypeToColorMap[TYPE_MONSTER]);
        aIterator = m_MonsterPositionVector.begin();
        while (aIterator != m_MonsterPositionVector.end())
        {
            TMarkPosition & rPosition = *aIterator;
            m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY);
            m_WhiteMark.Render();
            ++aIterator;
        }

        // Other PC
        aIterator = m_OtherPCPositionVector.begin();
        while (aIterator != m_OtherPCPositionVector.end())
        {
            TMarkPosition & rPosition = *aIterator;
            STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(rPosition.m_eNameColor));
            m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY);
            m_WhiteMark.Render();
            ++aIterator;
        }

        // Party PC
        if (!m_PartyPCPositionVector.empty())
        {
            float v = (1 + sinf(CTimer::Instance().GetCurrentSecond() * 6)) / 5 + 0.6;
            D3DXCOLOR c(CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_PARTY));//(m_MarkTypeToColorMap[TYPE_PARTY]);
            D3DXCOLOR d(v, v, v, 1);
            D3DXColorModulate(&c, &c, &d);
            STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, (DWORD)c);
            aIterator = m_PartyPCPositionVector.begin();
            while (aIterator != m_PartyPCPositionVector.end())
            {
                TMarkPosition & rPosition = *aIterator;
                m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY);
                m_WhiteMark.Render();
                ++aIterator;
            }
        }
    }

    // NPC
    STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC));
    aIterator = m_NPCPositionVector.begin();
    while (aIterator != m_NPCPositionVector.end())
    {
        TMarkPosition & rPosition = *aIterator;
        m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY);
        m_WhiteMark.Render();
        ++aIterator;
    }

    // Warp
    STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP));
    aIterator = m_WarpPositionVector.begin();
    while (aIterator != m_WarpPositionVector.end())
    {
        TMarkPosition & rPosition = *aIterator;
        m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY);
        m_WhiteMark.Render();
        ++aIterator;
    }

    STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);

    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);

    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);

    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);

    // ij¸¯ÅÍ ¸¶Å©
    CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr();

    if (pkInst)
    {
        float fRotation;
        fRotation = (540.0f - pkInst->GetRotation());
        while (fRotation > 360.0f)
            fRotation -= 360.0f;
        while (fRotation < 0.0f)
            fRotation += 360.0f;

        m_PlayerMark.SetRotation(fRotation);
        m_PlayerMark.Render();
    }

    // Target
    {
        TAtlasMarkInfoVector::iterator itor = m_AtlasWayPointInfoVector.begin();
        for (; itor != m_AtlasWayPointInfoVector.end(); ++itor)
        {
            TAtlasMarkInfo & rAtlasMarkInfo = *itor;

            if (TYPE_TARGET != rAtlasMarkInfo.m_byType)
                continue;
            if (rAtlasMarkInfo.m_fMiniMapX <= 0.0f)
                continue;
            if (rAtlasMarkInfo.m_fMiniMapY <= 0.0f)
                continue;

            __RenderTargetMark(rAtlasMarkInfo.m_fMiniMapX, rAtlasMarkInfo.m_fMiniMapY);
        }
    }

    CCamera* pkCmrCur = CCameraManager::Instance().GetCurrentCamera();

    // Ä«¸Þ¶ó ¹æÇâ
    if (pkCmrCur)
    {
        m_MiniMapCameraraphicImageInstance.SetRotation(pkCmrCur->GetRoll());
        m_MiniMapCameraraphicImageInstance.Render();
    }
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
}

void CPythonMiniMapWiki::SetScale(float fScale)
{
    if (fScale >= 4.0f)
        fScale = 4.0f;
    if (fScale <= 0.5f)
        fScale = 0.5f;
    m_fScale = fScale;

    __SetPosition();
}

void CPythonMiniMapWiki::ScaleUp()
{
    m_fScale *= 2.0f;
    if (m_fScale >= 4.0f)
        m_fScale = 4.0f;
    __SetPosition();
}

void CPythonMiniMapWiki::ScaleDown()
{
    m_fScale *= 0.5f;
    if (m_fScale <= 0.5f)
        m_fScale = 0.5f;
    __SetPosition();
}

void CPythonMiniMapWiki::SetMiniMapSize(float fWidth, float fHeight)
{
    m_fWidth = fWidth;
    m_fHeight = fHeight;
}

#pragma pack(push)
#pragma pack(1)
typedef struct _MINIMAPVERTEX
{
    float x, y, z;          // position
    float u, v;       // normal
} MINIMAPVERTEX, *LPMINIMAPVERTEX;
#pragma pack(pop)

bool CPythonMiniMapWiki::Create()
{
    const std::string strImageRoot = "D:/ymir work/ui/";
    const std::string strImageFilter = strImageRoot + "minimap_image_filter.dds";
    const std::string strImageCamera = strImageRoot + "minimap_camera.dds";
    const std::string strPlayerMark = strImageRoot + "minimap/playermark.sub";
    const std::string strWhiteMark = strImageRoot + "minimap/whitemark.sub";

    // ¹Ì´Ï¸Ê Ä¿¹ö
    CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strImageFilter.c_str());
    m_MiniMapFilterGraphicImageInstance.SetImagePointer(pImage);
    pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strImageCamera.c_str());
    m_MiniMapCameraraphicImageInstance.SetImagePointer(pImage);

    m_matMiniMapCover._11 = 1.0f / ((float)m_MiniMapFilterGraphicImageInstance.GetWidth());
    m_matMiniMapCover._22 = 1.0f / ((float)m_MiniMapFilterGraphicImageInstance.GetHeight());
    m_matMiniMapCover._33 = 0.0f;

    // ij¸¯ÅÍ ¸¶Å©
    CGraphicSubImage * pSubImage = (CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(strPlayerMark.c_str());
    m_PlayerMark.SetImagePointer(pSubImage);

    pSubImage = (CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(strWhiteMark.c_str());
    m_WhiteMark.SetImagePointer(pSubImage);

    char buf[256];
    for (int i = 0; i < MINI_WAYPOINT_IMAGE_COUNT; ++i)
    {
        sprintf(buf, "%sminimap/mini_waypoint%02d.sub", strImageRoot.c_str(), i + 1);
        m_MiniWayPointGraphicImageInstances.SetImagePointer((CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(buf));
        m_MiniWayPointGraphicImageInstances.SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN);
    }
    for (int j = 0; j < WAYPOINT_IMAGE_COUNT; ++j)
    {
        sprintf(buf, "%sminimap/waypoint%02d.sub", strImageRoot.c_str(), j + 1);
        m_WayPointGraphicImageInstances[j].SetImagePointer((CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(buf));
        m_WayPointGraphicImageInstances[j].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN);
    }
    for (int k = 0; k < TARGET_MARK_IMAGE_COUNT; ++k)
    {
        sprintf(buf, "%sminimap/targetmark%02d.sub", strImageRoot.c_str(), k + 1);
        m_TargetMarkGraphicImageInstances[k].SetImagePointer((CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(buf));
        m_TargetMarkGraphicImageInstances[k].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN);
    }

    m_GuildAreaFlagImageInstance.SetImagePointer((CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/ui/minimap/GuildArea01.sub"));

    // ±×·ÁÁú Æú¸®°ï ¼¼ÆÃ
#pragma pack(push)
#pragma pack(1)
    LPMINIMAPVERTEX        lpMiniMapVertex;
    LPMINIMAPVERTEX        lpOrigMiniMapVertex;
#pragma pack(pop)

    if (!m_VertexBuffer.Create(36, D3DFVF_XYZ | D3DFVF_TEX1, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
    {
        return false;
    }

    if (m_VertexBuffer.Lock((void **)&lpOrigMiniMapVertex))
    {
        char * pchMiniMapVertex = (char *)lpOrigMiniMapVertex;
        memset(pchMiniMapVertex, 0, sizeof(char) * 720);
        lpMiniMapVertex = (LPMINIMAPVERTEX)pchMiniMapVertex;

        for (int iY = -3; iY <= 1; ++iY)
        {
            if (0 == iY % 2)
                continue;
            float fY = 0.5f * ((float)iY);
            for (int iX = -3; iX <= 1; ++iX)
            {
                if (0 == iX % 2)
                    continue;
                float fX = 0.5f * ((float)iX);
                lpMiniMapVertex = (LPMINIMAPVERTEX)pchMiniMapVertex;
                lpMiniMapVertex->x = fX;
                lpMiniMapVertex->y = fY;
                lpMiniMapVertex->z = 0.0f;
                lpMiniMapVertex->u = 0.0f;
                lpMiniMapVertex->v = 0.0f;
                pchMiniMapVertex += 20;
                lpMiniMapVertex = (LPMINIMAPVERTEX)pchMiniMapVertex;
                lpMiniMapVertex->x = fX;
                lpMiniMapVertex->y = fY + 1.0f;
                lpMiniMapVertex->z = 0.0f;
                lpMiniMapVertex->u = 0.0f;
                lpMiniMapVertex->v = 1.0f;
                pchMiniMapVertex += 20;
                lpMiniMapVertex = (LPMINIMAPVERTEX)pchMiniMapVertex;
                lpMiniMapVertex->x = fX + 1.0f;
                lpMiniMapVertex->y = fY;
                lpMiniMapVertex->z = 0.0f;
                lpMiniMapVertex->u = 1.0f;
                lpMiniMapVertex->v = 0.0f;
                pchMiniMapVertex += 20;
                lpMiniMapVertex = (LPMINIMAPVERTEX)pchMiniMapVertex;
                lpMiniMapVertex->x = fX + 1.0f;
                lpMiniMapVertex->y = fY + 1.0f;
                lpMiniMapVertex->z = 0.0f;
                lpMiniMapVertex->u = 1.0f;
                lpMiniMapVertex->v = 1.0f;
                pchMiniMapVertex += 20;
            }
        }

        m_VertexBuffer.Unlock();
    }

    if (!m_IndexBuffer.Create(54, D3DFMT_INDEX16))
    {
        return false;
    }

    WORD pwIndices[54] =
    {
        0, 1, 2, 2, 1, 3,
        4, 5, 6, 6, 5, 7,
        8, 9, 10, 10, 9, 11,

        12, 13, 14, 14, 13, 15,
        16, 17, 18, 18, 17, 19,
        20, 21, 22, 22, 21, 23,

        24, 25, 26, 26, 25, 27,
        28, 29, 30, 30, 29, 31,
        32, 33, 34, 34, 33, 35
    };

    void * pIndices;

    if (m_IndexBuffer.Lock(&pIndices))
    {
        memcpy(pIndices, pwIndices, 54 * sizeof(WORD));
        m_IndexBuffer.Unlock();
    }

    return true;
}

void CPythonMiniMapWiki::__SetPosition()
{
    m_fMiniMapRadius = fMIN(6400.0f / ((float)CTerrainImpl::CELLSCALE) * m_fScale, 64.0f);

    m_matWorld._11 = m_fWidth * m_fScale;
    m_matWorld._22 = m_fHeight * m_fScale;
    m_matWorld._41 = (1.0f + m_fScale) * m_fWidth * 0.5f - m_fCenterCellX * m_fScale + m_fScreenX;
    m_matWorld._42 = (1.0f + m_fScale) * m_fHeight * 0.5f - m_fCenterCellY * m_fScale + m_fScreenY;

    if (!m_MiniMapFilterGraphicImageInstance.IsEmpty())
    {
        m_matMiniMapCover._41 = -(m_fScreenX) / ((float)m_MiniMapFilterGraphicImageInstance.GetWidth());
        m_matMiniMapCover._42 = -(m_fScreenY) / ((float)m_MiniMapFilterGraphicImageInstance.GetHeight());
    }

    if (!m_PlayerMark.IsEmpty())
        m_PlayerMark.SetPosition((m_fWidth - (float)m_PlayerMark.GetWidth()) / 2.0f + m_fScreenX,
        (m_fHeight - (float)m_PlayerMark.GetHeight()) / 2.0f + m_fScreenY);

    if (!m_MiniMapCameraraphicImageInstance.IsEmpty())
        m_MiniMapCameraraphicImageInstance.SetPosition((m_fWidth - (float)m_MiniMapCameraraphicImageInstance.GetWidth()) / 2.0f + m_fScreenX,
        (m_fHeight - (float)m_MiniMapCameraraphicImageInstance.GetHeight()) / 2.0f + m_fScreenY);
}

//////////////////////////////////////////////////////////////////////////
// Atlas

void CPythonMiniMapWiki::ClearAtlasMarkInfo()
{
    m_AtlasNPCInfoVector.clear();
    m_AtlasWarpInfoVector.clear();
}

void CPythonMiniMapWiki::RegisterAtlasMark(BYTE byType, const char * c_szName, long lx, long ly)
{
    TAtlasMarkInfo aAtlasMarkInfo;

    aAtlasMarkInfo.m_fX = float(lx);
    aAtlasMarkInfo.m_fY = float(ly);
    aAtlasMarkInfo.m_strText = c_szName;

    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;

    switch (byType)
    {
    case CActorInstance::TYPE_NPC:
        aAtlasMarkInfo.m_byType = TYPE_NPC;
        m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo);
        break;
    case CActorInstance::TYPE_WARP:
        aAtlasMarkInfo.m_byType = TYPE_WARP;
        {
            int iPos = aAtlasMarkInfo.m_strText.find(" ");
            if (iPos >= 0)
                aAtlasMarkInfo.m_strText[iPos] = 0;

        }
        m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo);
        break;
    }
}

void CPythonMiniMapWiki::ClearGuildArea()
{
    m_GuildAreaInfoVector.clear();
}

void CPythonMiniMapWiki::RegisterGuildArea(DWORD dwID, DWORD dwGuildID, long x, long y, long width, long height)
{
    TGuildAreaInfo kGuildAreaInfo;
    kGuildAreaInfo.dwGuildID = dwGuildID;
    kGuildAreaInfo.lx = x;
    kGuildAreaInfo.ly = y;
    kGuildAreaInfo.lwidth = width;
    kGuildAreaInfo.lheight = height;
    m_GuildAreaInfoVector.push_back(kGuildAreaInfo);
}

DWORD CPythonMiniMapWiki::GetGuildAreaID(DWORD x, DWORD y)
{
    TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin();
    for (; itor != m_GuildAreaInfoVector.end(); ++itor)
    {
        TGuildAreaInfo & rAreaInfo = *itor;

        if (x >= rAreaInfo.lx)
            if (y >= rAreaInfo.ly)
                if (x <= rAreaInfo.lx + rAreaInfo.lwidth)
                    if (y <= rAreaInfo.ly + rAreaInfo.lheight)
                    {
                        return rAreaInfo.dwGuildID;
                    }
    }

    return 0xffffffff;
}

void CPythonMiniMapWiki::CreateTarget(int iID, const char * c_szName)
{
    AddWayPoint(TYPE_TARGET, iID, 0.0f, 0.0f, c_szName);
}

void CPythonMiniMapWiki::UpdateTarget(int iID, int ix, int iy)
{
    TAtlasMarkInfo * pkInfo;
    if (!__GetWayPoint(iID, &pkInfo))
        return;

    if (0 != pkInfo->m_dwChrVID)
    {
        if (CPythonCharacterManager::Instance().GetInstancePtr(pkInfo->m_dwChrVID))
            return;
    }

    if (ix < m_dwAtlasBaseX)
        return;
    if (iy < m_dwAtlasBaseY)
        return;
    if (ix > m_dwAtlasBaseX + DWORD(m_fAtlasMaxX))
        return;
    if (iy > m_dwAtlasBaseY + DWORD(m_fAtlasMaxY))
        return;

    __UpdateWayPoint(pkInfo, ix - int(m_dwAtlasBaseX), iy - int(m_dwAtlasBaseY));
}

void CPythonMiniMapWiki::CreateTarget(int iID, const char * c_szName, DWORD dwVID)
{
    AddWayPoint(TYPE_TARGET, iID, 0.0f, 0.0f, c_szName, dwVID);
}

void CPythonMiniMapWiki::DeleteTarget(int iID)
{
    RemoveWayPoint(iID);
}

void CPythonMiniMapWiki::__LoadAtlasMarkInfo()
{
    ClearAtlasMarkInfo();
    ClearGuildArea();

    CPythonBackground& rkBG = CPythonBackground::Instance();
    if (!rkBG.IsMapOutdoor())
        return;

    CMapOutdoor& rkMap = rkBG.GetMapOutdoorRef();

    // LOCALE
    char szAtlasMarkInfoFileName[64 + 1];
    _snprintf(szAtlasMarkInfoFileName, sizeof(szAtlasMarkInfoFileName), "%s/map/%s_point.txt", LocaleService_GetLocalePath(), rkMap.GetName().c_str());
    // END_OF_LOCALE

    CTokenVectorMap stTokenVectorMap;

    if (!LoadMultipleTextData(szAtlasMarkInfoFileName, stTokenVectorMap))
    {
        Tracef(" CPythonMiniMapWiki::__LoadAtlasMarkInfo File Load %s ERROR\n", szAtlasMarkInfoFileName);
        return;
    }

    const std::string strType[TYPE_COUNT] = { "OPC", "OPCPVP", "OPCPVPSELF", "NPC", "MONSTER", "WARP", "WAYPOINT" };

    for (DWORD i = 0; i < stTokenVectorMap.size(); ++i)
    {
        char szMarkInfoName[32 + 1];
        _snprintf(szMarkInfoName, sizeof(szMarkInfoName), "%d", i);

        if (stTokenVectorMap.end() == stTokenVectorMap.find(szMarkInfoName))
            continue;

        const CTokenVector & rVector = stTokenVectorMap[szMarkInfoName];

        const std::string & c_rstrType = rVector[0].c_str();
        const std::string & c_rstrPositionX = rVector[1].c_str();
        const std::string & c_rstrPositionY = rVector[2].c_str();
        const std::string & c_rstrText = rVector[3].c_str();

        TAtlasMarkInfo aAtlasMarkInfo;

        for (int i = 0; i < TYPE_COUNT; ++i)
        {
            if (0 == c_rstrType.compare(strType))
                aAtlasMarkInfo.m_byType = (BYTE)i;
        }
        aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str());
        aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str());
        aAtlasMarkInfo.m_strText = c_rstrText;

        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;

        switch (aAtlasMarkInfo.m_byType)
        {
        case TYPE_NPC:
            m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo);
            break;
        case TYPE_WARP:
            m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo);
            break;
        }
    }
}

bool CPythonMiniMapWiki::LoadAtlas(const char* filepath)
{
    CPythonBackground& rkBG = CPythonBackground::Instance();
    if (!rkBG.IsMapOutdoor())
        return false;

    CMapOutdoor& rkMap = rkBG.GetMapOutdoorRef();

    const char* playerMarkFileName = "d:/ymir work/ui/minimap/playermark.sub";

    char atlasFileName[1024 + 1];
    snprintf(atlasFileName, sizeof(atlasFileName), "%s/atlas.sub", filepath);
    if (!CEterPackManager::Instance().isExist(atlasFileName))
    {
        snprintf(atlasFileName, sizeof(atlasFileName), "d:/ymir work/ui/atlas/%s/atlas.sub", filepath);
    }

    m_AtlasImageInstance.Destroy();
    m_AtlasPlayerMark.Destroy();
    CGraphicImage* pkGrpImgAtlas = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(atlasFileName);
    if (pkGrpImgAtlas)
    {
        m_AtlasImageInstance.SetImagePointer(pkGrpImgAtlas);

        if (pkGrpImgAtlas->IsEmpty())
            m_bAtlas = false;
        else
            m_bAtlas = true;
    }
    else
    {
    }
    m_AtlasPlayerMark.SetImagePointer((CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(playerMarkFileName));

    short sTerrainCountX, sTerrainCountY;
    rkMap.GetBaseXY(&m_dwAtlasBaseX, &m_dwAtlasBaseY);
    rkMap.GetTerrainCount(&sTerrainCountX, &sTerrainCountY);
    m_fAtlasMaxX = (float)sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE;
    m_fAtlasMaxY = (float)sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE;

    m_fAtlasImageSizeX = (float)m_AtlasImageInstance.GetWidth();
    m_fAtlasImageSizeY = (float)m_AtlasImageInstance.GetHeight();

    __LoadAtlasMarkInfo();

    if (m_bShowAtlas)
        OpenAtlasWindow();

    return true;
}

void CPythonMiniMapWiki::__GlobalPositionToAtlasPosition(long lx, long ly, float * pfx, float * pfy)
{
    *pfx = lx / m_fAtlasMaxX * m_fAtlasImageSizeX;
    *pfy = ly / m_fAtlasMaxY * m_fAtlasImageSizeY;
}

void CPythonMiniMapWiki::UpdateAtlas()
{
    CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr();

    if (pkInst)
    {
        TPixelPosition kInstPos;
        pkInst->NEW_GetPixelPosition(&kInstPos);

        float fRotation;
        fRotation = (540.0f - pkInst->GetRotation());
        while (fRotation > 360.0f)
            fRotation -= 360.0f;
        while (fRotation < 0.0f)
            fRotation += 360.0f;

        m_AtlasPlayerMark.SetPosition(kInstPos.x / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_AtlasPlayerMark.GetWidth() / 2.0f,
            kInstPos.y / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_AtlasPlayerMark.GetHeight() / 2.0f);
        m_AtlasPlayerMark.SetRotation(fRotation);
    }

    {
        TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin();
        for (; itor != m_GuildAreaInfoVector.end(); ++itor)
        {
            TGuildAreaInfo & rInfo = *itor;
            __GlobalPositionToAtlasPosition(rInfo.lx, rInfo.ly, &rInfo.fsxRender, &rInfo.fsyRender);
            __GlobalPositionToAtlasPosition(rInfo.lx + rInfo.lwidth, rInfo.ly + rInfo.lheight, &rInfo.fexRender, &rInfo.feyRender);
        }
    }
}

void CPythonMiniMapWiki::RenderAtlas(float fScreenX, float fScreenY)
{
    if (!m_bShowAtlas)
        return;

    if (m_fAtlasScreenX != fScreenX || m_fAtlasScreenY != fScreenY)
    {
        m_matWorldAtlas._41 = fScreenX;
        m_matWorldAtlas._42 = fScreenY;
        m_fAtlasScreenX = fScreenX;
        m_fAtlasScreenY = fScreenY;
    }

    STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldAtlas);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
    m_AtlasImageInstance.Render();

    STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
    STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

    STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC));
    m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasNPCInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;
        m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY);
        m_WhiteMark.Render();
        ++m_AtlasMarkInfoVectorIterator;
    }

    STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP));
    m_AtlasMarkInfoVectorIterator = m_AtlasWarpInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasWarpInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;
        m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY);
        m_WhiteMark.Render();
        ++m_AtlasMarkInfoVectorIterator;
    }

    STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
    STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
    STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WAYPOINT));
    m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin();
    for (; m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end(); ++m_AtlasMarkInfoVectorIterator)
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;

        if (rAtlasMarkInfo.m_fScreenX <= 0.0f)
            continue;
        if (rAtlasMarkInfo.m_fScreenY <= 0.0f)
            continue;

        if (TYPE_TARGET == rAtlasMarkInfo.m_byType)
        {
            __RenderMiniWayPointMark(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY);
        }
        else
        {
            __RenderWayPointMark(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY);
        }
    }

    STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);

    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);

    if ((ELTimer_GetMSec() / 500) % 2)
        m_AtlasPlayerMark.Render();

    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
    STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
    STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matIdentity);

    {
        TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin();
        for (; itor != m_GuildAreaInfoVector.end(); ++itor)
        {
            TGuildAreaInfo & rInfo = *itor;

            m_GuildAreaFlagImageInstance.SetPosition(fScreenX + (rInfo.fsxRender + rInfo.fexRender) / 2.0f - m_GuildAreaFlagImageInstance.GetWidth() / 2,
                fScreenY + (rInfo.fsyRender + rInfo.feyRender) / 2.0f - m_GuildAreaFlagImageInstance.GetHeight() / 2);
            m_GuildAreaFlagImageInstance.Render();

            //            CScreen::RenderBar2d(fScreenX+rInfo.fsxRender,
            //                                 fScreenY+rInfo.fsyRender,
            //                                 fScreenX+rInfo.fexRender,
            //                                 fScreenY+rInfo.feyRender);
        }
    }
}

bool CPythonMiniMapWiki::GetPickedInstanceInfo(float fScreenX, float fScreenY, std::string & rReturnName, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor)
{
    float fDistanceFromMiniMapCenterX = fScreenX - m_fScreenX - m_fWidth * 0.5f;
    float fDistanceFromMiniMapCenterY = fScreenY - m_fScreenY - m_fHeight * 0.5f;

    if (sqrtf(fDistanceFromMiniMapCenterX * fDistanceFromMiniMapCenterX + fDistanceFromMiniMapCenterY * fDistanceFromMiniMapCenterY) > m_fMiniMapRadius)
        return false;

    float fRealX = m_fCenterX + fDistanceFromMiniMapCenterX / m_fScale * ((float)CTerrainImpl::CELLSCALE);
    float fRealY = m_fCenterY + fDistanceFromMiniMapCenterY / m_fScale * ((float)CTerrainImpl::CELLSCALE);

    CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr();

    if (pkInst)
    {
        TPixelPosition kInstPos;
        pkInst->NEW_GetPixelPosition(&kInstPos);

        if (fabs(kInstPos.x - fRealX) < ((float)CTerrainImpl::CELLSCALE) * 6.0f / m_fScale &&
            fabs(kInstPos.y - fRealY) < ((float)CTerrainImpl::CELLSCALE) * 6.0f / m_fScale)
        {
            rReturnName = pkInst->GetNameString();
            *pReturnPosX = kInstPos.x;
            *pReturnPosY = kInstPos.y;
            *pdwTextColor = pkInst->GetNameColor();
            return true;
        }
    }

    if (m_fScale < 1.0f)
        return false;

    CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
    CPythonCharacterManager::CharacterIterator i;
    for (i = rkChrMgr.CharacterInstanceBegin(); i != rkChrMgr.CharacterInstanceEnd(); ++i)
    {
        CInstanceBase* pkInstEach = *i;
        if (pkInstEach->IsInvisibility())
            continue;
        if (m_fScale < 2.0f && (pkInstEach->IsEnemy() || pkInstEach->IsPC()))
            continue;
        TPixelPosition kInstancePosition;
        pkInstEach->NEW_GetPixelPosition(&kInstancePosition);

        if (fabs(kInstancePosition.x - fRealX) < ((float)CTerrainImpl::CELLSCALE) * 3.0f / m_fScale &&
            fabs(kInstancePosition.y - fRealY) < ((float)CTerrainImpl::CELLSCALE) * 3.0f / m_fScale)
        {
            rReturnName = pkInstEach->GetNameString();
            *pReturnPosX = kInstancePosition.x;
            *pReturnPosY = kInstancePosition.y;
            *pdwTextColor = pkInstEach->GetNameColor();
            return true;
        }
    }
    return false;
}


bool CPythonMiniMapWiki::GetAtlasInfo(float fScreenX, float fScreenY, std::string & rReturnString, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor, DWORD * pdwGuildID)
{
    float fRealX = (fScreenX - m_fAtlasScreenX) * (m_fAtlasMaxX / m_fAtlasImageSizeX);
    float fRealY = (fScreenY - m_fAtlasScreenY) * (m_fAtlasMaxY / m_fAtlasImageSizeY);

    //((float) CTerrainImpl::CELLSCALE) * 10.0f
    float fCheckWidth = (m_fAtlasMaxX / m_fAtlasImageSizeX) * 5.0f;
    float fCheckHeight = (m_fAtlasMaxY / m_fAtlasImageSizeY) * 5.0f;

    CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr();

    if (pkInst)
    {
        TPixelPosition kInstPos;
        pkInst->NEW_GetPixelPosition(&kInstPos);

        if (kInstPos.x - fCheckWidth<fRealX && kInstPos.x + fCheckWidth>fRealX &&
            kInstPos.y - fCheckHeight<fRealY && kInstPos.y + fCheckHeight>fRealY)
        {
            rReturnString = pkInst->GetNameString();
            *pReturnPosX = kInstPos.x;
            *pReturnPosY = kInstPos.y;
            *pdwTextColor = pkInst->GetNameColor();
            return true;
        }
    }

    m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasNPCInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;

        if (rAtlasMarkInfo.m_fX - fCheckWidth / 2<fRealX && rAtlasMarkInfo.m_fX + fCheckWidth>fRealX &&
            rAtlasMarkInfo.m_fY - fCheckWidth / 2<fRealY && rAtlasMarkInfo.m_fY + fCheckHeight>fRealY)
        {
            rReturnString = rAtlasMarkInfo.m_strText;
            *pReturnPosX = rAtlasMarkInfo.m_fX;
            *pReturnPosY = rAtlasMarkInfo.m_fY;
            *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType];
            return true;
        }
        ++m_AtlasMarkInfoVectorIterator;
    }

    m_AtlasMarkInfoVectorIterator = m_AtlasWarpInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasWarpInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;
        if (rAtlasMarkInfo.m_fX - fCheckWidth / 2<fRealX && rAtlasMarkInfo.m_fX + fCheckWidth>fRealX &&
            rAtlasMarkInfo.m_fY - fCheckWidth / 2<fRealY && rAtlasMarkInfo.m_fY + fCheckHeight>fRealY)
        {
            rReturnString = rAtlasMarkInfo.m_strText;
            *pReturnPosX = rAtlasMarkInfo.m_fX;
            *pReturnPosY = rAtlasMarkInfo.m_fY;
            *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType];
            return true;
        }
        ++m_AtlasMarkInfoVectorIterator;
    }

    m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;
        if (rAtlasMarkInfo.m_fScreenX > 0.0f)
            if (rAtlasMarkInfo.m_fScreenY > 0.0f)
                if (rAtlasMarkInfo.m_fX - fCheckWidth / 2<fRealX && rAtlasMarkInfo.m_fX + fCheckWidth>fRealX &&
                    rAtlasMarkInfo.m_fY - fCheckWidth / 2<fRealY && rAtlasMarkInfo.m_fY + fCheckHeight>fRealY)
                {
                    rReturnString = rAtlasMarkInfo.m_strText;
                    *pReturnPosX = rAtlasMarkInfo.m_fX;
                    *pReturnPosY = rAtlasMarkInfo.m_fY;
                    *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WAYPOINT);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType];
                    return true;
                }
        ++m_AtlasMarkInfoVectorIterator;
    }

    TGuildAreaInfoVector::iterator itor = m_GuildAreaInfoVector.begin();
    for (; itor != m_GuildAreaInfoVector.end(); ++itor)
    {
        TGuildAreaInfo & rInfo = *itor;
        if (fScreenX - m_fAtlasScreenX >= rInfo.fsxRender)
            if (fScreenY - m_fAtlasScreenY >= rInfo.fsyRender)
                if (fScreenX - m_fAtlasScreenX <= rInfo.fexRender)
                    if (fScreenY - m_fAtlasScreenY <= rInfo.feyRender)
                    {
                        if (CPythonGuild::Instance().GetGuildName(rInfo.dwGuildID, &rReturnString))
                        {
                            *pdwGuildID = rInfo.dwGuildID;
                        }
                        else
                        {
                            rReturnString = "empty_guild_area";
                        }

                        *pReturnPosX = rInfo.lx + rInfo.lwidth / 2;
                        *pReturnPosY = rInfo.ly + rInfo.lheight / 2;
                        *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_PARTY);
                        return true;
                    }
    }

    return false;
}

bool CPythonMiniMapWiki::GetAtlasSize(float * pfSizeX, float * pfSizeY)
{
    CPythonBackground& rkBG = CPythonBackground::Instance();
    if (!rkBG.IsMapOutdoor())
        return false;

    *pfSizeX = m_fAtlasImageSizeX;
    *pfSizeY = m_fAtlasImageSizeY;

    return true;
}

// Atlas
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// WayPoint
void CPythonMiniMapWiki::AddWayPoint(BYTE byType, DWORD dwID, float fX, float fY, std::string strText, DWORD dwChrVID)
{
    m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;
        if (rAtlasMarkInfo.m_dwID == dwID)
            return;
        ++m_AtlasMarkInfoVectorIterator;
    }

    TAtlasMarkInfo aAtlasMarkInfo;
    aAtlasMarkInfo.m_byType = byType;
    aAtlasMarkInfo.m_dwID = dwID;
    aAtlasMarkInfo.m_fX = fX;
    aAtlasMarkInfo.m_fY = fY;
    aAtlasMarkInfo.m_fScreenX = 0.0f;
    aAtlasMarkInfo.m_fScreenY = 0.0f;
    aAtlasMarkInfo.m_fMiniMapX = 0.0f;
    aAtlasMarkInfo.m_fMiniMapY = 0.0f;
    aAtlasMarkInfo.m_strText = strText;
    aAtlasMarkInfo.m_dwChrVID = dwChrVID;
    __UpdateWayPoint(&aAtlasMarkInfo, fX, fY);
    m_AtlasWayPointInfoVector.push_back(aAtlasMarkInfo);

}

void CPythonMiniMapWiki::RemoveWayPoint(DWORD dwID)
{
    m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin();
    while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end())
    {
        TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator;
        if (rAtlasMarkInfo.m_dwID == dwID)
        {
            m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.erase(m_AtlasMarkInfoVectorIterator);
            return;
        }
        ++m_AtlasMarkInfoVectorIterator;
    }
}

bool CPythonMiniMapWiki::__GetWayPoint(DWORD dwID, TAtlasMarkInfo ** ppkInfo)
{
    TAtlasMarkInfoVectorIterator itor = m_AtlasWayPointInfoVector.begin();
    for (; itor != m_AtlasWayPointInfoVector.end(); ++itor)
    {
        TAtlasMarkInfo & rInfo = *itor;
        if (dwID == rInfo.m_dwID)
        {
            *ppkInfo = &rInfo;
            return true;
        }
    }

    return false;
}

void CPythonMiniMapWiki::__UpdateWayPoint(TAtlasMarkInfo * pkInfo, int ix, int iy)
{
    pkInfo->m_fX = float(ix);
    pkInfo->m_fY = float(iy);
    pkInfo->m_fScreenX = pkInfo->m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX;
    pkInfo->m_fScreenY = pkInfo->m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY;
}

// WayPoint
//////////////////////////////////////////////////////////////////////////

void CPythonMiniMapWiki::__RenderWayPointMark(int ixCenter, int iyCenter)
{
    int iNum = (ELTimer_GetMSec() / 67) % WAYPOINT_IMAGE_COUNT;

    CGraphicImageInstance & rInstance = m_WayPointGraphicImageInstances[iNum];
    rInstance.SetPosition(ixCenter - rInstance.GetWidth() / 2, iyCenter - rInstance.GetHeight() / 2);
    rInstance.Render();
}

void CPythonMiniMapWiki::__RenderMiniWayPointMark(int ixCenter, int iyCenter)
{
    int iNum = (ELTimer_GetMSec() / 67) % MINI_WAYPOINT_IMAGE_COUNT;

    CGraphicImageInstance & rInstance = m_MiniWayPointGraphicImageInstances[iNum];
    rInstance.SetPosition(ixCenter - rInstance.GetWidth() / 2, iyCenter - rInstance.GetHeight() / 2);
    rInstance.Render();
}

void CPythonMiniMapWiki::__RenderTargetMark(int ixCenter, int iyCenter)
{
    int iNum = (ELTimer_GetMSec() / 80) % TARGET_MARK_IMAGE_COUNT;

    CGraphicImageInstance & rInstance = m_TargetMarkGraphicImageInstances[iNum];
    rInstance.SetPosition(ixCenter - rInstance.GetWidth() / 2, iyCenter - rInstance.GetHeight() / 2);
    rInstance.Render();
}

void CPythonMiniMapWiki::AddSignalPoint(float fX, float fY)
{
    static unsigned int g_id = 255;

    TSignalPoint sp;
    sp.id = g_id;
    sp.v2Pos.x = fX;
    sp.v2Pos.y = fY;

    m_SignalPointVector.push_back(sp);

    AddWayPoint(TYPE_WAYPOINT, g_id, fX, fY, "");

    g_id++;
}

void CPythonMiniMapWiki::ClearAllSignalPoint()
{
    vector<TSignalPoint>::iterator it;
    for (it = m_SignalPointVector.begin(); it != m_SignalPointVector.end(); ++it)
    {
        RemoveWayPoint(it->id);
    }
    m_SignalPointVector.clear();
}

void CPythonMiniMapWiki::RegisterAtlasWindow(PyObject* poHandler)
{
    m_poHandler = poHandler;
}

void CPythonMiniMapWiki::UnregisterAtlasWindow()
{
    m_poHandler = 0;
}

void CPythonMiniMapWiki::OpenAtlasWindow()
{
    if (m_poHandler)
    {
        PyCallClassMemberFunc(m_poHandler, "Show", Py_BuildValue("()"));
    }
}

void CPythonMiniMapWiki::SetAtlasCenterPosition(int x, int y)
{
    if (m_poHandler)
    {
        //int sw = UI::CWindowManager::Instance().GetScreenWidth();
        //int sh = UI::CWindowManager::Instance().GetScreenHeight();
        //PyCallClassMemberFunc(m_poHandler,"SetPosition", Py_BuildValue("(ii)",sw/2+x,sh/2+y));
        PyCallClassMemberFunc(m_poHandler, "SetCenterPositionAdjust", Py_BuildValue("(ii)", x, y));
    }
}

bool CPythonMiniMapWiki::IsAtlas()
{
    return m_bAtlas;
}

void CPythonMiniMapWiki::ShowAtlas()
{
    m_bShowAtlas = true;
}

void CPythonMiniMapWiki::HideAtlas()
{
    m_bShowAtlas = false;
}

bool CPythonMiniMapWiki::CanShowAtlas()
{
    return m_bShowAtlas;
}

bool CPythonMiniMapWiki::CanShow()
{
    return m_bShow;
}

void CPythonMiniMapWiki::Show()
{
    m_bShow = true;
}

void CPythonMiniMapWiki::Hide()
{
    m_bShow = false;
}

void CPythonMiniMapWiki::__Initialize()
{
    m_poHandler = 0;

    SetMiniMapSize(128.0f, 128.0f);

    m_fScale = 2.0f;

    m_fCenterX = m_fWidth * 0.5f;
    m_fCenterY = m_fHeight * 0.5f;

    m_fScreenX = 0.0f;
    m_fScreenY = 0.0f;

    m_fAtlasScreenX = 0.0f;
    m_fAtlasScreenY = 0.0f;

    m_dwAtlasBaseX = 0;
    m_dwAtlasBaseY = 0;

    m_fAtlasMaxX = 0.0f;
    m_fAtlasMaxY = 0.0f;

    m_fAtlasImageSizeX = 0.0f;
    m_fAtlasImageSizeY = 0.0f;

    m_bAtlas = false;

    m_bShow = false;
    m_bShowAtlas = false;

    D3DXMatrixIdentity(&m_matIdentity);
    D3DXMatrixIdentity(&m_matWorld);
    D3DXMatrixIdentity(&m_matMiniMapCover);
    D3DXMatrixIdentity(&m_matWorldAtlas);
}

void CPythonMiniMapWiki::Destroy()
{
    ClearAllSignalPoint();
    m_poHandler = 0;

    m_VertexBuffer.Destroy();
    m_IndexBuffer.Destroy();

    m_PlayerMark.Destroy();

    m_MiniMapFilterGraphicImageInstance.Destroy();
    m_MiniMapCameraraphicImageInstance.Destroy();

    m_AtlasWayPointInfoVector.clear();
    m_AtlasImageInstance.Destroy();
    m_AtlasPlayerMark.Destroy();
    m_WhiteMark.Destroy();

    for (int i = 0; i < MINI_WAYPOINT_IMAGE_COUNT; ++i)
        m_MiniWayPointGraphicImageInstances.Destroy();
    for (int j = 0; j < WAYPOINT_IMAGE_COUNT; ++j)
        m_WayPointGraphicImageInstances[j].Destroy();
    for (int k = 0; k < TARGET_MARK_IMAGE_COUNT; ++k)
        m_TargetMarkGraphicImageInstances[k].Destroy();

    m_GuildAreaFlagImageInstance.Destroy();

    __Initialize();
}

CPythonMiniMapWiki::CPythonMiniMapWiki()
{
    __Initialize();
}

CPythonMiniMapWiki::~CPythonMiniMapWiki()
{
    Destroy();
}
 

PythonMiniMapWiki.h

Spoiler

#pragma once

#include "PythonBackground.h"

class CPythonMiniMapWiki : public CScreen, public CSingleton<CPythonMiniMapWiki>
{
public:
    enum
    {
        EMPIRE_NUM = 4,

        MINI_WAYPOINT_IMAGE_COUNT = 12,
        WAYPOINT_IMAGE_COUNT = 15,
        TARGET_MARK_IMAGE_COUNT = 2,
    };
    enum
    {
        TYPE_OPC,
        TYPE_OPCPVP,
        TYPE_OPCPVPSELF,
        TYPE_NPC,
        TYPE_MONSTER,
        TYPE_WARP,
        TYPE_WAYPOINT,
        TYPE_PARTY,
        TYPE_EMPIRE,
        TYPE_EMPIRE_END = TYPE_EMPIRE + EMPIRE_NUM,
        TYPE_TARGET,
        TYPE_COUNT,
    };

public:
    CPythonMiniMapWiki();
    virtual ~CPythonMiniMapWiki();

    void Destroy();
    bool Create();

    bool IsAtlas();
    bool CanShow();
    bool CanShowAtlas();

    void SetMiniMapSize(float fWidth, float fHeight);
    void SetScale(float fScale);
    void ScaleUp();
    void ScaleDown();

    void SetCenterPosition(float fCenterX, float fCenterY);

    void Update(float fCenterX, float fCenterY);
    void Render(float fScreenX, float fScreenY);

    void Show();
    void Hide();

    bool GetPickedInstanceInfo(float fScreenX, float fScreenY, std::string & rReturnName, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor);

    // Atlas
    bool LoadAtlas(const char* filepath);
    void UpdateAtlas();
    void RenderAtlas(float fScreenX, float fScreenY);
    void ShowAtlas();
    void HideAtlas();

    bool GetAtlasInfo(float fScreenX, float fScreenY, std::string & rReturnString, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor, DWORD * pdwGuildID);
    bool GetAtlasSize(float * pfSizeX, float * pfSizeY);

    void AddObserver(DWORD dwVID, float fSrcX, float fSrcY);
    void MoveObserver(DWORD dwVID, float fDstX, float fDstY);
    void RemoveObserver(DWORD dwVID);

    // WayPoint
    void AddWayPoint(BYTE byType, DWORD dwID, float fX, float fY, std::string strText, DWORD dwChrVID = 0);
    void RemoveWayPoint(DWORD dwID);

    // SignalPoint
    void AddSignalPoint(float fX, float fY);
    void ClearAllSignalPoint();

    void RegisterAtlasWindow(PyObject* poHandler);
    void UnregisterAtlasWindow();
    void OpenAtlasWindow();
    void SetAtlasCenterPosition(int x, int y);

    // NPC List
    void ClearAtlasMarkInfo();
    void RegisterAtlasMark(BYTE byType, const char * c_szName, long lx, long ly);

    // Guild
    void ClearGuildArea();
    void RegisterGuildArea(DWORD dwID, DWORD dwGuildID, long x, long y, long width, long height);
    DWORD GetGuildAreaID(DWORD x, DWORD y);

    // Target
    void CreateTarget(int iID, const char * c_szName);
    void CreateTarget(int iID, const char * c_szName, DWORD dwVID);
    void UpdateTarget(int iID, int ix, int iy);
    void DeleteTarget(int iID);

protected:
    void __Initialize();
    void __SetPosition();
    void __LoadAtlasMarkInfo();

    void __RenderWayPointMark(int ixCenter, int iyCenter);
    void __RenderMiniWayPointMark(int ixCenter, int iyCenter);
    void __RenderTargetMark(int ixCenter, int iyCenter);

    void __GlobalPositionToAtlasPosition(long lx, long ly, float * pfx, float * pfy);

protected:
    // Atlas
    typedef struct
    {
        BYTE m_byType;
        DWORD m_dwID; // For WayPoint
        float m_fX;
        float m_fY;
        float m_fScreenX;
        float m_fScreenY;
        float m_fMiniMapX;
        float m_fMiniMapY;
        DWORD m_dwChrVID;
        std::string m_strText;
    } TAtlasMarkInfo;

    // GuildArea
    typedef struct
    {
        DWORD dwGuildID;
        long lx, ly;
        long lwidth, lheight;

        float fsxRender, fsyRender;
        float fexRender, feyRender;
    } TGuildAreaInfo;

    struct SObserver
    {
        float fCurX;
        float fCurY;
        float fSrcX;
        float fSrcY;
        float fDstX;
        float fDstY;

        DWORD dwSrcTime;
        DWORD dwDstTime;
    };

    // ij¸¯ÅÍ ¸®½ºÆ®
    typedef struct
    {
        float    m_fX;
        float    m_fY;
        UINT    m_eNameColor;
    } TMarkPosition;

    typedef std::vector<TMarkPosition>                TInstanceMarkPositionVector;
    typedef TInstanceMarkPositionVector::iterator    TInstancePositionVectorIterator;

protected:
    bool __GetWayPoint(DWORD dwID, TAtlasMarkInfo ** ppkInfo);
    void __UpdateWayPoint(TAtlasMarkInfo * pkInfo, int ix, int iy);

protected:
    float                            m_fWidth;
    float                            m_fHeight;

    float                            m_fScale;

    float                            m_fCenterX;
    float                            m_fCenterY;

    float                            m_fCenterCellX;
    float                            m_fCenterCellY;

    float                            m_fScreenX;
    float                            m_fScreenY;

    float                            m_fMiniMapRadius;

    // ¸Ê ±×¸²...
    LPDIRECT3DTEXTURE8                m_lpMiniMapTexture[AROUND_AREA_NUM];

    // ¹Ì´Ï¸Ê Ä¿¹ö
    CGraphicImageInstance            m_MiniMapFilterGraphicImageInstance;
    CGraphicExpandedImageInstance    m_MiniMapCameraraphicImageInstance;

    // ij¸¯ÅÍ ¸¶Å©
    CGraphicExpandedImageInstance    m_PlayerMark;
    CGraphicImageInstance            m_WhiteMark;

    TInstanceMarkPositionVector        m_PartyPCPositionVector;
    TInstanceMarkPositionVector        m_OtherPCPositionVector;
    TInstanceMarkPositionVector        m_NPCPositionVector;
    TInstanceMarkPositionVector        m_MonsterPositionVector;
    TInstanceMarkPositionVector        m_WarpPositionVector;
    std::map<DWORD, SObserver>        m_kMap_dwVID_kObserver;

    bool                            m_bAtlas;
    bool                            m_bShow;

    CGraphicVertexBuffer            m_VertexBuffer;
    CGraphicIndexBuffer                m_IndexBuffer;

    D3DXMATRIX                        m_matIdentity;
    D3DXMATRIX                        m_matWorld;
    D3DXMATRIX                        m_matMiniMapCover;

    bool                            m_bShowAtlas;
    CGraphicImageInstance            m_AtlasImageInstance;
    D3DXMATRIX                        m_matWorldAtlas;
    CGraphicExpandedImageInstance    m_AtlasPlayerMark;

    float                            m_fAtlasScreenX;
    float                            m_fAtlasScreenY;

    DWORD                            m_dwAtlasBaseX;
    DWORD                            m_dwAtlasBaseY;

    float                            m_fAtlasMaxX;
    float                            m_fAtlasMaxY;

    float                            m_fAtlasImageSizeX;
    float                            m_fAtlasImageSizeY;

    typedef std::vector<TAtlasMarkInfo>        TAtlasMarkInfoVector;
    typedef TAtlasMarkInfoVector::iterator    TAtlasMarkInfoVectorIterator;
    typedef std::vector<TGuildAreaInfo>        TGuildAreaInfoVector;
    typedef TGuildAreaInfoVector::iterator    TGuildAreaInfoVectorIterator;
    TAtlasMarkInfoVectorIterator            m_AtlasMarkInfoVectorIterator;
    TAtlasMarkInfoVector                    m_AtlasNPCInfoVector;
    TAtlasMarkInfoVector                    m_AtlasWarpInfoVector;

    // WayPoint
    CGraphicExpandedImageInstance            m_MiniWayPointGraphicImageInstances[MINI_WAYPOINT_IMAGE_COUNT];
    CGraphicExpandedImageInstance            m_WayPointGraphicImageInstances[WAYPOINT_IMAGE_COUNT];
    CGraphicExpandedImageInstance            m_TargetMarkGraphicImageInstances[TARGET_MARK_IMAGE_COUNT];
    CGraphicImageInstance                    m_GuildAreaFlagImageInstance;
    TAtlasMarkInfoVector                    m_AtlasWayPointInfoVector;
    TGuildAreaInfoVector                    m_GuildAreaInfoVector;

    // SignalPoint
    struct TSignalPoint
    {
        D3DXVECTOR2 v2Pos;
        unsigned int id;
    };
    vector<TSignalPoint>                m_SignalPointVector;

    PyObject*                            m_poHandler;
};
 

PythonMiniMapWikiModule.cpp

Spoiler

#include "StdAfx.h"
#include "PythonMiniMapWiki.h"

PyObject * miniMapWikiSetScale(PyObject * poSelf, PyObject * poArgs)
{
    float fScale;
    if (!PyTuple_GetFloat(poArgs, 0, &fScale))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().SetScale(fScale);
    return Py_BuildNone();
}

PyObject * miniMapWikiSetCenterPosition(PyObject * poSelf, PyObject * poArgs)
{
    float fCenterX;
    if (!PyTuple_GetFloat(poArgs, 0, &fCenterX))
        return Py_BuildException();

    float fCenterY;
    if (!PyTuple_GetFloat(poArgs, 1, &fCenterY))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().SetCenterPosition(fCenterX, fCenterY);
    return Py_BuildNone();
}


PyObject * miniMapWikiSetMiniMapSize(PyObject * poSelf, PyObject * poArgs)
{
    float fWidth;
    if (!PyTuple_GetFloat(poArgs, 0, &fWidth))
        return Py_BuildException();

    float fHeight;
    if (!PyTuple_GetFloat(poArgs, 1, &fHeight))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().SetMiniMapSize(fWidth, fHeight);
    return Py_BuildNone();
}

PyObject * miniMapWikiDestroy(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().Destroy();
    return Py_BuildNone();
}

PyObject * miniMapWikiCreate(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().Create();
    return Py_BuildNone();
}

PyObject * miniMapWikiUpdate(PyObject * poSelf, PyObject * poArgs)
{
    float fCenterX;
    if (!PyTuple_GetFloat(poArgs, 0, &fCenterX))
        return Py_BuildException();

    float fCenterY;
    if (!PyTuple_GetFloat(poArgs, 1, &fCenterY))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().Update(fCenterX, fCenterY);
    return Py_BuildNone();
}

PyObject * miniMapWikiRender(PyObject * poSelf, PyObject * poArgs)
{
    float fScrrenX;
    if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX))
        return Py_BuildException();

    float fScrrenY;
    if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().Render(fScrrenX, fScrrenY);
    return Py_BuildNone();
}

PyObject * miniMapWikiShow(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().Show();
    return Py_BuildNone();
}

PyObject * miniMapWikiHide(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().Hide();
    return Py_BuildNone();
}

PyObject * miniMapWikiisShow(PyObject * poSelf, PyObject * poArgs)
{
    bool bShow = CPythonMiniMapWiki::Instance().CanShow();
    return Py_BuildValue("b", bShow);
}

PyObject * miniMapWikiScaleUp(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().ScaleUp();
    return Py_BuildNone();
}

PyObject * miniMapWikiScaleDown(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().ScaleDown();
    return Py_BuildNone();
}

PyObject * miniMapWikiGetInfo(PyObject * poSelf, PyObject * poArgs)
{
    float fScrrenX;
    if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX))
        return Py_BuildException();

    float fScrrenY;
    if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY))
        return Py_BuildException();

    std::string aString;
    float fPosX, fPosY;
    DWORD dwTextColor;
    bool bFind = CPythonMiniMapWiki::Instance().GetPickedInstanceInfo(fScrrenX, fScrrenY, aString, &fPosX, &fPosY, &dwTextColor);
    int iPosX, iPosY;
    PR_FLOAT_TO_INT(fPosX, iPosX);
    PR_FLOAT_TO_INT(fPosY, iPosY);
    iPosX /= 100;
    iPosY /= 100;
    return Py_BuildValue("isiil", (int)bFind, aString.c_str(), iPosX, iPosY, (signed)dwTextColor);
}

//////////////////////////////////////////////////////////////////////////
// Atlas
PyObject * miniMapWikiLoadAtlas(PyObject * poSelf, PyObject * poArgs)
{
    char* filepath;
    if (!PyTuple_GetString(poArgs, 0, &filepath)){
        TraceError("CPythonMiniMapWiki::Instance.LoadAtlas file name error");
    }
    if (!CPythonMiniMapWiki::Instance().LoadAtlas(filepath))
        TraceError("CPythonMiniMapWiki::Instance().LoadAtlas() Failed");
    return Py_BuildNone();
}

PyObject * miniMapWikiUpdateAtlas(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().UpdateAtlas();
    return Py_BuildNone();
}

PyObject * miniMapWikiRenderAtlas(PyObject * poSelf, PyObject * poArgs)
{
    float fScrrenX;
    if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX))
        return Py_BuildException();

    float fScrrenY;
    if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().RenderAtlas(fScrrenX, fScrrenY);
    return Py_BuildNone();
}

PyObject * miniMapWikiShowAtlas(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().ShowAtlas();
    return Py_BuildNone();
}

PyObject * miniMapWikiHideAtlas(PyObject * poSelf, PyObject * poArgs)
{
    CPythonMiniMapWiki::Instance().HideAtlas();
    return Py_BuildNone();
}

PyObject * miniMapWikiisShowAtlas(PyObject * poSelf, PyObject * poArgs)
{
    bool bShow = CPythonMiniMapWiki::Instance().CanShowAtlas();
    return Py_BuildValue("b", bShow);
}

PyObject * miniMapWikiIsAtlas(PyObject * poSelf, PyObject * poArgs)
{
    bool isData = CPythonMiniMapWiki::Instance().IsAtlas();
    return Py_BuildValue("b", isData);
}


PyObject * miniMapWikiGetAtlasInfo(PyObject * poSelf, PyObject * poArgs)
{
    float fScrrenX;
    if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX))
        return Py_BuildException();
    float fScrrenY;
    if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY))
        return Py_BuildException();

    std::string aString = "";
    float fPosX = 0.0f;
    float fPosY = 0.0f;
    DWORD dwTextColor = 0;
    DWORD dwGuildID = 0;
    bool bFind = CPythonMiniMapWiki::Instance().GetAtlasInfo(fScrrenX, fScrrenY, aString, &fPosX, &fPosY, &dwTextColor, &dwGuildID);
    int iPosX, iPosY;
    PR_FLOAT_TO_INT(fPosX, iPosX);
    PR_FLOAT_TO_INT(fPosY, iPosY);
    iPosX /= 100;
    iPosY /= 100;
    return Py_BuildValue("isiili", (int)bFind, aString.c_str(), iPosX, iPosY, (signed)dwTextColor, dwGuildID);
}

PyObject * miniMapWikiGetAtlasSize(PyObject * poSelf, PyObject * poArgs)
{
    float fSizeX, fSizeY;
    bool bGet = CPythonMiniMapWiki::Instance().GetAtlasSize(&fSizeX, &fSizeY);

    /*
    float fSizeXoo256 = fSizeX / 256.0f;
    float fSizeYoo256 = fSizeY / 256.0f;

    if (fSizeXoo256 >= fSizeYoo256)
    {
    fSizeX /= fSizeYoo256;
    fSizeY = 256.0f;
    }
    else
    {
    fSizeX = 256.0f;
    fSizeY /= fSizeXoo256;
    }
    */

    int iSizeX, iSizeY;
    PR_FLOAT_TO_INT(fSizeX, iSizeX);
    PR_FLOAT_TO_INT(fSizeY, iSizeY);

    return Py_BuildValue("bii", (int)bGet, iSizeX, iSizeY);
}

PyObject * miniMapWikiAddWayPoint(PyObject * poSelf, PyObject * poArgs)
{
    int iID;
    if (!PyTuple_GetInteger(poArgs, 0, &iID))
        return Py_BuildException();

    float fX;
    if (!PyTuple_GetFloat(poArgs, 1, &fX))
        return Py_BuildException();

    float fY;
    if (!PyTuple_GetFloat(poArgs, 2, &fY))
        return Py_BuildException();

    char * buf;
    if (!PyTuple_GetString(poArgs, 3, &buf))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().AddWayPoint(CPythonMiniMapWiki::TYPE_WAYPOINT, (DWORD)iID, fX, fY, buf);

    return Py_BuildNone();
}

PyObject * miniMapWikiRemoveWayPoint(PyObject * poSelf, PyObject * poArgs)
{
    int iID;
    if (!PyTuple_GetInteger(poArgs, 0, &iID))
        return Py_BuildException();

    CPythonMiniMapWiki::Instance().RemoveWayPoint((DWORD)iID);

    return Py_BuildNone();
}

PyObject* miniMapWikiRegisterAtlasWindow(PyObject* poSelf, PyObject* poArgs)
{
    PyObject * poHandler;
    if (!PyTuple_GetObject(poArgs, 0, &poHandler))
        return Py_BuildException();
    CPythonMiniMapWiki::Instance().RegisterAtlasWindow(poHandler);
    return Py_BuildNone();
}

PyObject* miniMapWikiUnregisterAtlasWindow(PyObject* poSelf, PyObject* poArgs)
{
    CPythonMiniMapWiki::Instance().UnregisterAtlasWindow();
    return Py_BuildNone();
}

PyObject* miniMapWikiGetGuildAreaID(PyObject* poSelf, PyObject* poArgs)
{
    float fx;
    if (!PyTuple_GetFloat(poArgs, 0, &fx))
        return Py_BuildException();
    float fy;
    if (!PyTuple_GetFloat(poArgs, 1, &fy))
        return Py_BuildException();

    DWORD dwGuildID = CPythonMiniMapWiki::Instance().GetGuildAreaID(fx, fy);
    return Py_BuildValue("i", dwGuildID);
}

void initMiniMapWiki()
{
    static PyMethodDef s_methods[] =
    {
    { "SetScale",                        miniMapWikiSetScale,                                METH_VARARGS },
    { "ScaleUp",                        miniMapWikiScaleUp,                                    METH_VARARGS },
    { "ScaleDown",                        miniMapWikiScaleDown,                                METH_VARARGS },
    { "SetMiniMapSize",                    miniMapWikiSetMiniMapSize,                            METH_VARARGS },

    { "SetCenterPosition",                miniMapWikiSetCenterPosition,                        METH_VARARGS },

    { "Destroy",                        miniMapWikiDestroy,                                    METH_VARARGS },
    { "Create",                            miniMapWikiCreate,                                    METH_VARARGS },
    { "Update",                            miniMapWikiUpdate,                                    METH_VARARGS },
    { "Render",                            miniMapWikiRender,                                    METH_VARARGS },

    { "Show",                            miniMapWikiShow,                                    METH_VARARGS },
    { "Hide",                            miniMapWikiHide,                                    METH_VARARGS },

    { "isShow",                            miniMapWikiisShow,                                    METH_VARARGS },

    { "GetInfo",                        miniMapWikiGetInfo,                                    METH_VARARGS },

    { "LoadAtlas",                        miniMapWikiLoadAtlas,                                METH_VARARGS },
    { "UpdateAtlas",                    miniMapWikiUpdateAtlas,                                METH_VARARGS },
    { "RenderAtlas",                    miniMapWikiRenderAtlas,                                METH_VARARGS },
    { "ShowAtlas",                        miniMapWikiShowAtlas,                                METH_VARARGS },
    { "HideAtlas",                        miniMapWikiHideAtlas,                                METH_VARARGS },
    { "isShowAtlas",                    miniMapWikiisShowAtlas,                                METH_VARARGS },
    { "IsAtlas",                        miniMapWikiIsAtlas,                                    METH_VARARGS },
    { "GetAtlasInfo",                    miniMapWikiGetAtlasInfo,                            METH_VARARGS },
    { "GetAtlasSize",                    miniMapWikiGetAtlasSize,                            METH_VARARGS },

    { "AddWayPoint",                    miniMapWikiAddWayPoint,                                METH_VARARGS },
    { "RemoveWayPoint",                    miniMapWikiRemoveWayPoint,                            METH_VARARGS },

    { "RegisterAtlasWindow",            miniMapWikiRegisterAtlasWindow,                        METH_VARARGS },
    { "UnregisterAtlasWindow",            miniMapWikiUnregisterAtlasWindow,                    METH_VARARGS },

    { "GetGuildAreaID",                    miniMapWikiGetGuildAreaID,                            METH_VARARGS },

    { NULL, NULL },
    };

    PyObject * poModule = Py_InitModule("miniMapWiki", s_methods);

    PyModule_AddIntConstant(poModule, "TYPE_OPC", CPythonMiniMapWiki::TYPE_OPC);
    PyModule_AddIntConstant(poModule, "TYPE_OPCPVP", CPythonMiniMapWiki::TYPE_OPCPVP);
    PyModule_AddIntConstant(poModule, "TYPE_OPCPVPSELF", CPythonMiniMapWiki::TYPE_OPCPVPSELF);
    PyModule_AddIntConstant(poModule, "TYPE_NPC", CPythonMiniMapWiki::TYPE_NPC);
    PyModule_AddIntConstant(poModule, "TYPE_MONSTER", CPythonMiniMapWiki::TYPE_MONSTER);
    PyModule_AddIntConstant(poModule, "TYPE_WARP", CPythonMiniMapWiki::TYPE_WARP);
    PyModule_AddIntConstant(poModule, "TYPE_WAYPOINT", CPythonMiniMapWiki::TYPE_WAYPOINT);
    PyModule_AddIntConstant(poModule, "TYPE_PARTY", CPythonMiniMapWiki::TYPE_PARTY);
    PyModule_AddIntConstant(poModule, "TYPE_EMPIRE", CPythonMiniMapWiki::TYPE_EMPIRE);
}

 Edit: I just noticed CPythonMiniMapWiki class declared but never initialized, just added CPythonMiniMapWiki m_pyMiniMapWIki; in PythonApplication.h and m_pyMiniMapWiki.Destroy() in PythonApplication.cpp in function CPythonApplication::Destroy(), I knew it was something dumb but it was a lot of code to check.

Edited by OtherChoice
  • Love 1
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.