Files
Leviathan/Client/Game/game/Interface/WorldMap/SUIWorldMapWnd.cpp
T
2026-06-01 12:46:52 +02:00

1203 lines
32 KiB
C++

#include "stdafx.h"
#include "KDeviceManager.h"
#include <kfile/KFileManager.h>
#include "KResourceDX.h"
#include "KUIControl3DStatic.h"
#include "KUIControlStatic.h"
#include "KUITabControl.h"
#include "KUITextureManager.h"
#include "SGameManager.h"
#include "SUIWorldMapWnd.h"
#include "SUIDisplayInfo.h"
#include "SUIDefine.h"
#include "SPlayerInfoMgr.h"
#include "SMessengerMgr.h"
//#include "SGameMessageUI.h"
#include "SGameMessage.h"
#include "SChatType.h"
#include <geometry/X2DBasicTypes.h>
#include "SStringDB.h"
#include <toolkit/XEnv.h>
#include "SNpcResourceDB.h"
#include "SUIWorldAllMapWnd.h"
#include "SUIWorldDetailMapWnd.h"
#include "MapDefine.h" /// 2011.07.21 - prodongi
#include "SGameWorld.h"
#include "SFieldPropResourceDB.h"
#include "TerrainSeamlessWorldInfoForClient.h"
#include "TerrainMapEngine.h"
#include "SUIWorldMapMonsterRegion.h"
#include "SQuestDB.h"
#include <time.h>
#ifdef _KUI_INVALIDATION
// { [sonador]
#include <toolkit/XStringUtil.h>
// }
#endif
void SUIWorldMapWnd::sNoTargetTitle::init(SUIWnd* parent)
{
if (!parent)
return ;
m_wnd = parent->GetChild("dungeon_target_title");
if (m_wnd)
{
m_wnd->SetShow(false);
parent->SetChildAsTop(parent->GetID());
}
m_updateTime = 0.0f;
}
void SUIWorldMapWnd::sNoTargetTitle::check(int questCode)
{
QuestBase* base = GetQuestDB().GetQuestData((QuestBase::QuestCode)questCode);
if (!base)
return ;
if (QuestBase::QUEST_HUNT_ALL_MOB_ITEM == base->nType || 1 == base->mark_hide)
{
setState(SHOW);
}
else
{
setState(END);
}
}
void SUIWorldMapWnd::sNoTargetTitle::update(DWORD elapsedtime)
{
if (!m_wnd || !m_wnd->IsShow())
return ;
float e = (float)elapsedtime/1000.0f;
m_updateTime += e;
if (m_totalTime <= m_updateTime)
{
switch (m_state)
{
case SHOW: setState(FADE_IN); break;
case FADE_IN: setState(END); break;
}
}
else
{
switch (m_state)
{
case FADE_IN: m_alpha = max(0.0f, 1.0f - (m_updateTime/m_totalTime));
m_wnd->ChangeAlpha(m_alpha);
break;
}
}
}
void SUIWorldMapWnd::sNoTargetTitle::setState(int state)
{
if (!m_wnd)
return ;
m_state = state;
m_updateTime = 0.0f;
switch (m_state)
{
case SHOW: m_totalTime = 1.0f;
m_alpha = 1.0f;
m_wnd->SetShow(true);
m_wnd->ChangeAlpha(m_alpha);
break;
case FADE_IN: m_totalTime = 2.0f;
break;
case END: m_wnd->SetShow(false);
break;
}
}
void SUIWorldMapWnd::sNoTargetTitle::setTop(SUIWnd* parent)
{
if (m_wnd)
parent->SetChildAsTop(m_wnd->GetID());
}
/// 2010.11.19 - prodongi
void SUIWorldMapWnd::convertUiToWorldPos(const KPoint &uiPos, KPoint &worldPos, const KRect &uiRect, const KPoint &worldSize, int emptyWidth, int emptyHeight)
{
/*
int _nPosX = uiPos.x;
int _nPosY = (m_playerRealPos.y - c_nEmptyHeight) * fHeight;
// ui -> world
int _wPosX = (int)((double)_nPosX * (double)((double)(c_nRealWidth_WithOut_Dungeon-c_nEmptyWidth)/(double)m_rtWorldWnd->GetRect().GetWidth()));
int _wPosY = (int)((double)_nPosY * (double)((double)(c_nRealHeight-c_nEmptyHeight)/(double)m_rtWorldWnd->GetRect().GetHeight()));
*/
int _nPosX = uiPos.x;
int _nPosY = uiRect.GetHeight() - uiPos.y;
worldPos.x = (int)((double)_nPosX * (double)((double)(worldSize.x-emptyWidth)/(double)uiRect.GetWidth()));
worldPos.y = (int)((double)_nPosY * (double)((double)(worldSize.y-emptyHeight)/(double)uiRect.GetHeight()));
worldPos.x += emptyWidth;
worldPos.y += emptyHeight;
}
/// 2010.11.19 - prodongi
void SUIWorldMapWnd::convertWorldToUiPos(const KPoint &worldPos, KPoint &uiPos, const KRect &uiRect, const KPoint &worldSize, int emptyWidth, int emptyHeight)
{
/*
float fHeight = ((double)m_rtWorldWnd->GetRect().GetHeight()/(c_nRealHeight-c_nEmptyHeight));
uiPos.x = (m_playerRealPos.x - c_nEmptyWidth ) * ((double)m_rtWorldWnd->GetRect().GetWidth()/(c_nRealWidth_WithOut_Dungeon-c_nEmptyWidth));
uiPos.y = (m_playerRealPos.y - c_nEmptyHeight) * fHeight;
uiPos.y = m_rtWorldWnd->GetRect().GetHeight() - uiPos.y;
*/
float fHeight = ((double)uiRect.GetHeight()/(worldSize.y-emptyHeight));
uiPos.x = (worldPos.x - emptyWidth ) * ((double)uiRect.GetWidth()/(worldSize.x-emptyWidth));
uiPos.y = (worldPos.y - emptyHeight) * fHeight;
uiPos.y = uiRect.GetHeight() - uiPos.y;
}
/// 2010.11.25 - prodongi
/*
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//지역 표시 정보 맵
void SUILocalSignWnd::SetLocalTitle( const char * pString, DWORD dwTime )
{
m_dwStartTime = dwTime;
SetAlphaClose( dwTime );
SetChildCaption( "static_area_title", pString );
if( pString != NULL && strlen(pString) > 0 )
{
//리사이즈
DWORD dwWidth = KTextPhrase::GetOneLineStringSize( pString );
KUIWnd * pBG = GetChild( "outframe" );
KUIWnd * pSign = GetChild( "static_area_title" );
if( pBG && pSign )
{
KRect bgRect = pBG->GetRect();
KRect signRect = pSign->GetRect();
int nHalfW = KUIWndManager::GetResolution().cx / 2;
if( dwWidth < 150 )
dwWidth = 150; //최소 사이즈 유지
signRect.left = nHalfW - (dwWidth / 2);
signRect.right = nHalfW + (dwWidth / 2);
dwWidth += c_nSignDecoX;
bgRect.left = nHalfW - (dwWidth / 2);
bgRect.right = nHalfW + (dwWidth / 2);
#ifdef _KUI_INVALIDATION
this->Resize( bgRect );
#endif
pBG->Resize( bgRect );
pSign->Resize( signRect );
pSign->MovePos( pBG->GetRect().left + (c_nSignDecoX/2), pSign->GetRect().top );
#ifdef _COUNTRY_ME_
pBG->ClipRect(bgRect);
// 중동한정으로 ClipRect 갱신 안해줘서 글자 짤리는 문제 해결하기 위함 by 정동섭
// 왜 한글버전엔 문제가 안 발생하지 -,-
signRect.left -= 50;
signRect.right += 0;
pSign->Resize( signRect );
pSign->ClipRect( signRect );
pSign->MovePos( pBG->GetRect().left + (c_nSignDecoX/2) - 25, pSign->GetRect().top );
#endif
#ifdef _KUI_INVALIDATION
this->MovePos( pBG->GetRect().left, pBG->GetRect().top );
#endif
pBG->SetShow( true );
pSign->SetShow( true );
}
}
else
{
SetChildShow( "outframe" , false );
SetChildShow( "static_area_title", false );
}
}
bool SUILocalSignWnd::InitControls( KPoint kPos )
{
#ifdef _KUI_INVALIDATION
KUIControl * pBG = (KUIControl*)GetChild( "outframe" );
KUIControl * pSign = (KUIControl*)GetChild( "static_area_title" );
if( pBG ) this->AddPopupControl( pBG );
if( pSign ) this->AddPopupControl( pSign );
#endif
return SUIWnd::InitControls(kPos);
}
bool SUILocalSignWnd::InitData( bool bReload )
{
if( !bReload )
{ //리로드 일 경우
}
m_dwTime = 0;
m_dwStartTime = 0;
// SetChildShow( "outframe" , false );
// SetChildShow( "static_area_title", false );
return SUIWnd::InitData(bReload);
}
void SUILocalSignWnd::Process(DWORD dwTime)
{
if( m_dwStartTime )
{
DWORD dwLocalNameTime = dwTime-m_dwStartTime;
if( dwLocalNameTime > VIEW_TIME )
{
SetShow( false );
m_dwStartTime = 0;
}
else
{
float fTmRate = dwLocalNameTime / (float)VIEW_TIME;
float fAlpha = 1.0f;
if( fTmRate < 0.2f )
{
fAlpha = fTmRate / 0.2f;
}
else if( fTmRate < 0.5f )
{
fAlpha = 1.0f;
}
else
{
fAlpha = 1.0f - ( fTmRate - 0.5f ) * 2.0f;
}
// fAlpha = 1.0f - (float)(m_dwTime - m_dwLocalNameStartTime) / m_dwLocalNameDisplayTime;
ChangeAlpha(fAlpha);
//ChangeAlpha( 1.f - (float)(dwTime-m_dwStartTime)/VIEW_TIME );
}
}
}
#ifdef _KUI_INVALIDATION
// { [sonador]
void SUILocalSignWnd::Render( KViewportObject* pViewport, bool isFront )
{
bool bSavetofile = false;
if( m_bValidation == false )
{
bSavetofile = true;
}
KUIGenWnd::Render( pViewport, isFront );
if( bSavetofile )
{
//static int count = 0;
//std::string filename;
//XStringUtil::Format( filename, "xxxx%d", count++ );
//m_spRenderTarget->SaveToFile( filename.c_str() );
}
}
// }
#endif
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
K3DRenderDeviceDX* SUIWorldMapWnd::s_pDevice = NULL;
SUIWorldMapWnd::SUIWorldMapWnd( SGameManager* pGameManager, SUIDisplayInfo* pDisplayInfo )
: SUIWnd( pGameManager )
, m_pDisplayInfo( pDisplayInfo )
{
m_allMapWnd = NULL;
m_detailMapWnd = NULL;
m_categoryWnd = NULL; /// 2011.03.02 - prodongi
m_readyOpenTownDetailMap = -1;
m_readyOpenFieldDetailMap = -1; /// 201.06.02 - prodongi
m_readyOpenVillageDetailMap = -1;
m_readyCloseDetailMap = false;
m_lastTime = 0;
m_playerAreaWnd = NULL;
m_monsterRegionInfo = NULL;
m_bPointSign = FALSE;
m_dwPlayerPointTime = 0;
}
SUIWorldMapWnd::~SUIWorldMapWnd()
{
/// 2010.11.19 - prodongi
m_npcList.clear();
m_removeWndList.clear();
/// 2010.11.19 없어서 추가함 - prodongi
m_vecNPCInfoList.clear();
m_dungeonGateInfoList.clear(); /// 2011.07.21 - prodongi
SAFE_DELETE(m_monsterRegionInfo);
}
void SUIWorldMapWnd::SetRenderDevice( class K3DRenderDeviceDX * pDevice )
{
s_pDevice = pDevice;
}
/// 2010.11.16 - prodongi
SUIWnd* SUIWorldMapWnd::CreateWnd( const char* szNUIFileName, KUIWndManager* pWndManager, KPoint kPos, int nWindowID )
{
SUIWnd::CreateWnd(szNUIFileName, pWndManager, kPos, nWindowID);
createSubWnd(pWndManager);
m_playerAreaWnd = GetChild("panel_player_area");
/// 2011.08.30 - prodongi
m_monsterRegionInfo = new sMonsterRegionInfo;
m_monsterRegionInfo->initialize(this);
m_noTargetTitle.init(this); /// 2011.09.30 - prodongi
return this;
}
void SUIWorldMapWnd::createSubWnd(KUIWndManager *pWndManager)
{
KUIWnd* posWnd;
/// detail map
posWnd = GetChild("world_map_all");
assert(!m_allMapWnd);
m_allMapWnd = new SUIWorldAllMapWnd(m_pGameManager);
m_allMapWnd->CreateWnd("window_world_map_all.nui", pWndManager, KPoint(posWnd->GetRect().left, posWnd->GetRect().top));
m_allMapWnd->SetParent(this);
m_allMapWnd->SetShow(true);
//m_allMapWnd->createNpc(m_npcList); /// 2012.03.15 전체 맵에 npc를 출력할 때만 쓰인다(기획팀의 요청으로 제작), 보통때는 주석처리 한다
AddChild(m_allMapWnd);
/// category wnd
posWnd = GetChild("worldmap_category_contol");
m_categoryWnd = new SUIWnd(m_pGameManager);
m_categoryWnd->CreateWnd("window_world_map_npc_category.nui", pWndManager, KPoint(posWnd->GetRect().left, posWnd->GetRect().top));
m_categoryWnd->SetParent(this);
m_categoryWnd->SetShow(false);
AddChild(m_categoryWnd);
}
bool SUIWorldMapWnd::InitControls( KPoint kPos )
{
SetCustomMovingRect( KRect( 0, 0, 578, 20 ) ); // 타이틀 바 선택 영역, 이동위해 클릭 Area
//m_rtMinWnd = KRect( GetRect().left, GetRect().top, GetRect().right-400, GetRect().bottom-400 );
//m_rtMaxWnd = GetRect();
//SetResizeUnit( 400, 400, KSize(m_rtMinWnd.GetWidth(), m_rtMinWnd.GetHeight()), KSize(m_rtMaxWnd.GetWidth(), m_rtMaxWnd.GetHeight()) );
//RECT rc; rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0;
//// 8개 생성해 놓는다
//for( int i = 0; i < 7; i++ )
// CopyControl( CStringUtil::StringFormat("worldmap_party%02d", i+1).c_str(), CStringUtil::StringFormat("worldmap_party%02d", i+2).c_str(), rc );
return SUIWnd::InitControls(kPos);
}
#define _WORLD_MAP_TEST
bool SUIWorldMapWnd::InitData( bool bReload )
{
LoadNPCInfoFile();
loadDungeonGateInfo(); /// 2011.07.22 - prodongi
m_needApplyMonterRegionInfo = false; /// 2011.10.28 - prodongi
m_needRefreshMonterRegionInfo = false;
return SUIWnd::InitData(bReload);
}
void SUIWorldMapWnd::zoomin()
{
}
void SUIWorldMapWnd::zoomout()
{
}
void SUIWorldMapWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
if (m_allMapWnd)
m_allMapWnd->ProcMsgAtStatic(pMsg);
if (m_detailMapWnd)
m_detailMapWnd->ProcMsgAtStatic(pMsg);
switch(pMsg->nType)
{
case IMSG_MOUSEMOVE:
{
if (m_allMapWnd)
{
SIMSG_MOUSEMOVE* pMouseMove = (SIMSG_MOUSEMOVE* )pMsg;
m_allMapWnd->setMousePos(((int)(short)LOWORD(pMouseMove->lParam)), ((int)(short)HIWORD(pMouseMove->lParam)));
}
}
break;
/// 2011.09.15 - prodongi
case IMSG_UI_SEND_DATA:
{
SIMSG_UI_SEND_DATA* msg = dynamicCast<SIMSG_UI_SEND_DATA*>(pMsg);
if (!msg)
return ;
if ("set_quest_code" == msg->m_strString)
{
setQuestCode((QuestBase::QuestCode)msg->m_nNumber.getAmount());
if ((int)msg->m_nNumber2.getAmount() == 1)
{
if (!IsShow())
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_WORLDMAP, true) );
}
}
}
else if ("quest_status_updated" == msg->m_strString)
{
setQuestCode((QuestBase::QuestCode)msg->m_nNumber.getAmount());
}
else if ("quest_list_updated" == msg->m_strString)
{
if (IsShow())
m_monsterRegionInfo->checkValidQuestCode(this);
}
else if ("hide_quest_region" == msg->m_strString)
{
m_monsterRegionInfo->setQuestCode(0, this); ///초기화
}
}
break;
case IMSG_UI_FOCUS:
{
m_pManager->SetFocus(this);
pMsg->bUse = true;
}
break;
}
}
void SUIWorldMapWnd::HidePartyIcon()
{
//for( int i = 0; i < 8; i++ )
// SetChildShow( CStringUtil::StringFormat("worldmap_party%02d", i+1).c_str(), false );
}
void SUIWorldMapWnd::RefreshPartyPlayerPos()
{
}
void SUIWorldMapWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch(nMessage)
{
case KUI_MESSAGE::KBUTTON_CLICK:
{
if( ::_stricmp( lpszControlID, "button_close" ) == 0 )
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_WORLDMAP, false) );
}
}
break;
case KUI_MESSAGE::KGENWND_MOVE: // 윈도우 이동
LimitMoveWnd(); // 게임 외부로 나가지 못하게 제한
break;
}
SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
std::string SUIWorldMapWnd::GetWorldMapName( int nX, int nY )
{
//int nRealY = m_nMapPosY - nY;
//nRealY *= (-1);
//nRealY = m_nMapPosY + nRealY;
return CStringUtil::StringFormat( "worldmap_%03d_%03d.dds", nX, nY );
}
K3DTexture * SUIWorldMapWnd::GetWorldMapTexture( const char * pTexName )
{
return NULL;
}
bool UDgreater ( int elem1, int elem2 )
{
return elem1 > elem2;
}
void SUIWorldMapWnd::RefreshZoomWorldMap()
{
}
void SUIWorldMapWnd::MovePlayer( int nX, int nY )
{
}
void SUIWorldMapWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd/* = true*/ )
{
if( bOpen )
{
m_pGameManager->StartSound( "ui_popup_window01.wav" );
m_readyCloseDetailMap = false;
/// 2011.10.31 monster region refresh는 process에서 하도록 해준다 - prodongi
closeDetailMap(false);
/// 2011.06.07 - prodongi
SetChildCaption("worldmap_help_text_01", CStringUtil::StringFormat("<font:font_01><size:9><#ff8225><left>%s", S(1149)).c_str());
/// 2011.09.15 퀘스트 리스트 창 왼쪽으로 - prodongi
KUIWnd *pWnd = m_pManager->FindWnd( "window_quest_list_main" );
if( pWnd )
{
MovePos( pWnd->GetRect().left - GetRect().GetWidth(), pWnd->GetRect().top);
LimitMoveWnd();
}
m_monsterRegionInfo->clearChild(this);
m_needRefreshMonterRegionInfo = true;
m_noTargetTitle.setState(sNoTargetTitle::END);
m_noTargetTitle.setTop(this);
SetChildAsTop("panel_player_area");
}
}
void SUIWorldMapWnd::LoadNPCInfoFile()
{
GetNpcResourceDB().EnumNPC( &m_vecNPCInfoList );
for( size_t i = 0; i < m_vecNPCInfoList.size(); i++ )
{
if (IsRenderNPC(m_vecNPCInfoList[i].nID))
{
/// 2012.03.15 안 쓰여서 주석 처리함 - prodongi
/*
// 컨트롤 생성한다
KUIWnd* pNewWnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "iconstatic", m_vecNPCInfoList[i].strName.c_str(), " ", KRect(-1,-1,-1, -1), 0, 0, this, "static_minimap_npc", "ui_frame.spr", m_pManager, 0, "", KANCHOR_LEFT | KANCHOR_TOP ) );
if( pNewWnd )
{
pNewWnd->SetShow(false);
(( KUIControlIconStatic*)pNewWnd)->SetTooltip( m_vecNPCInfoList[i].strName.c_str() );
}
m_vecNPCInfoList[i].is_render = true;
m_vecNPCInfoList[i].wnd = pNewWnd;
*/
m_vecNPCInfoList[i].is_render = true;
m_npcList.push_back(m_vecNPCInfoList[i]); /// prodongi
}
}
}
/// 2011.07.21 - prodongi
void SUIWorldMapWnd::loadDungeonGateInfo()
{
if (!m_dungeonGateInfoList.empty())
return ;
int segmentCountPerMap, tileCountPerSegment;
float tileLength;
if (!getSeamlessWorldInfo(segmentCountPerMap, tileCountPerSegment, tileLength))
return ;
for (int x = 0; x <= 13; ++x)
{
for (int y = 0; y <= 10; ++y)
{
getQuestPropDBId(x, y, segmentCountPerMap, tileCountPerSegment, tileLength);
}
}
}
bool SUIWorldMapWnd::getSeamlessWorldInfo(int& segmentCountPerMap, int& tileCountPerSegment, float& tileLength)
{
CTerrainSeamlessWorldInfoForClient seamlessWorldInfo;
if( !seamlessWorldInfo.Initialize("TerrainSeamlessWorld.cfg", false))
return false;
segmentCountPerMap = seamlessWorldInfo.GetSegmentCountPerMap();
tileCountPerSegment = seamlessWorldInfo.GetTileCountPerSegment();
tileLength = seamlessWorldInfo.GetTileLength();
return true;
}
void SUIWorldMapWnd::getQuestPropDBId(int x, int y, int segmentCountPerMap, int tileCountPerSegment, float tileLength)
{
char filename[MAX_PATH];
sprintf(filename, "m%03d_%03d.qpf", x, y);
KStream * stream = KFileManager::Instance().CreateStreamFromResource(filename);
if (!stream)
return ;
NFM_QUEST_PROP_HEADER_V1 header;
stream->Read(&header, sizeof (header));
std::string strSign = _T( header.szSign );
if( strSign != NFM_QUEST_FILE_SIGN || header.nPropCount <= 0 )
{
KFileManager::Instance().DeleteStream(stream);
return ;
}
int segmentSX = x * segmentCountPerMap;
int segmentSY = y * segmentCountPerMap;
K3DPoint segmentOrigin = K3DPoint((float)(segmentSX * tileCountPerSegment) * tileLength, (float)(segmentSY * tileCountPerSegment) * tileLength);
switch (header.dwVersion)
{
case c_dwNFMQuestPropVer: readQuestPropList<NFM_QUEST_PROPSTRUCT_V3>(stream, header.nPropCount, segmentOrigin); break;
case 2: readQuestPropList<NFM_QUEST_PROPSTRUCT_V2>(stream, header.nPropCount, segmentOrigin); break;
case 1: readQuestPropList<NFM_QUEST_PROPSTRUCT_V1>(stream, header.nPropCount, segmentOrigin); break;
}
KFileManager::Instance().DeleteStream(stream);
}
void SUIWorldMapWnd::addDungeonGateInfo(int propDBId, float x, float y)
{
if (0 > propDBId)
return ;
int type = GetFieldPropResourceDB().getDungeonGateType(propDBId);
if (0 != type)
m_dungeonGateInfoList.push_back(sDungeonGateInfo(propDBId, (int)x, (int)y));
}
void SUIWorldMapWnd::ConvertWorldY( const int nY, int & nOutY )
{
nOutY = 258048-nY; //16128*16
}
bool SUIWorldMapWnd::TranslatePosition( int * nPosX, int * nPosY )
{
return false;
}
bool SUIWorldMapWnd::GetZoomTypePos( int nX, int nY, int& nOutX, int& nOutY )
{
return true;
}
void SUIWorldMapWnd::RefreshPlayerPos()
{
}
void SUIWorldMapWnd::RefreshNPC()
{
}
bool SUIWorldMapWnd::IsRenderNPC( ENC_INT id )
{
//std::string strCountry;
//strCountry = ENV().GetString("country");
NpcResourceBase* pNpcRes(NULL);
pNpcRes = GetNpcResourceDB().GetNpcInfo( id );
if( !pNpcRes ) return false;
int nlocal_flag(pNpcRes->local_flag);
if ((GameRule::EXCLUDE_TEST_SERV & nlocal_flag) && (ENV().GetString("tserver") == "test"))
return false;
if ((GameRule::EXCLUDE_SERVICE_SERV & nlocal_flag ) && ( ENV().GetString("tserver") != "test"))
return false;
return true;
}
void SUIWorldMapWnd::OnDeviceLost()
{
if( m_vtLoadedMapTexture.empty() )
return;
std::vector< std::string > minimap_list;
//캐쉬에 있는지 확인.
for( unsigned int i(0); m_vtLoadedMapTexture.size()>i; i++ )
{
minimap_list.push_back( m_vtLoadedMapTexture[i]->GetName() );
}
m_vtLoadedMapTexture.clear();
for( unsigned int i(0); minimap_list.size()>i; i++ )
{
//캐쉬에 없다.
KStream *stream = KFileManager::Instance().CreateStreamFromResource( minimap_list[i].c_str() );
if( stream == NULL )
continue;
K3DTextureDX* pSrcTex = new K3DTextureDX( s_pDevice );
pSrcTex->SetName( minimap_list[i].c_str() );
pSrcTex->Initialize( *stream, 0, D3DPOOL_DEFAULT, K3DFMT_A8R8G8B8 );
//Load Time
pSrcTex->SetLoadedTime( GetSafeTickCount() );
//Device Lost
s_pDevice->AddLostTexture( pSrcTex );
m_vtLoadedMapTexture.push_back( K3DTextureSPtr( pSrcTex ) );
KFileManager::Instance().DeleteStream( stream );
}
minimap_list.clear();
RefreshZoomWorldMap();
}
// 2010.09.28 - prodongi
void SUIWorldMapWnd::showAreaText(bool show)
{
}
void SUIWorldMapWnd::setShowCategory(bool show, bool directHide)
{
if (!m_categoryWnd)
return ;
if (show)
{
m_isAlphaHideCategory = false;
m_categoryWnd->SetShow(show);
m_categoryWnd->ChangeAlpha(1.0f);
m_updateCategoryShow.begin(5.0f, false);
SetChildAsTop("window_world_map_npc_category");
SetChildCaption("worldmap_help_text_01", CStringUtil::StringFormat("<font:font_01><size:9><#ff8225><left>%s", S(1150)).c_str());
}
else
{
if (directHide)
{
m_categoryWnd->SetShow(show);
m_updateCategoryShow.end();
}
else
{
m_isAlphaHideCategory = true;
m_updateCategoryShow.begin(0.5f, false);
}
}
}
void SUIWorldMapWnd::updateShowCategory(DWORD elapsedtime)
{
if (!m_categoryWnd || !m_categoryWnd->IsShow())
return ;
float t = (float)elapsedtime/1000.0f;
if (!m_updateCategoryShow.update(t))
{
if (m_isAlphaHideCategory)
{
m_updateCategoryShow.end();
m_categoryWnd->SetShow(false);
}
else
{
setShowCategory(false);
}
}
else
{
if (m_isAlphaHideCategory)
{
m_categoryWnd->ChangeAlpha(1.0f - m_updateCategoryShow.getRate());
}
}
}
void SUIWorldMapWnd::Process(DWORD dwTime)
{
DWORD elapsedtime = dwTime - m_lastTime;
m_lastTime = dwTime;
if (m_allMapWnd)
{
m_allMapWnd->Process(dwTime, elapsedtime);
}
if (m_detailMapWnd)
{
m_detailMapWnd->Process(dwTime, elapsedtime);
}
if (m_readyCloseDetailMap)
{
if (m_detailMapWnd && m_detailMapWnd->isClosed())
{
closeDetailMap();
m_readyCloseDetailMap = false;
}
}
if (0 <= m_readyOpenTownDetailMap)
{
closeDetailMap();
KRect worldRect;
m_allMapWnd->getVillageWndWorldRect(SUIWorldDetailMapWnd::TOWN, m_readyOpenTownDetailMap, worldRect);
readyOpenDetailMap(SUIWorldDetailMapWnd::TOWN, m_readyOpenTownDetailMap, false, worldRect);
m_readyOpenTownDetailMap = -1;
}
/// 2011.06.02 - prodongi
if (0 <= m_readyOpenFieldDetailMap)
{
closeDetailMap();
KRect worldRect;
m_allMapWnd->getFieldWndWorldRect(m_readyOpenFieldDetailMap, worldRect);
readyOpenDetailMap(SUIWorldDetailMapWnd::FIELD, m_readyOpenFieldDetailMap, false, worldRect);
m_readyOpenFieldDetailMap = -1;
}
if (0 <= m_readyOpenVillageDetailMap)
{
closeDetailMap();
KRect worldRect;
m_allMapWnd->getVillageWndWorldRect(SUIWorldDetailMapWnd::VILLAGE, m_readyOpenVillageDetailMap, worldRect);
readyOpenDetailMap(SUIWorldDetailMapWnd::VILLAGE, m_readyOpenVillageDetailMap, false, worldRect);
m_readyOpenVillageDetailMap = -1;
}
/// 2011.03.03 - prodongi
if (m_openDetailMapInfo.m_is)
{
openDetailMap();
}
/// 2011.03.03 - prodongi
procRemoveWndList();
/// 2011.06.02 - prodongi
updateShowCategory(elapsedtime);
procMonsterRegion(dwTime); /// 2011.10.28 - prodongi
m_noTargetTitle.update(elapsedtime); /// 2011.09.30 - prodongi
if ( dwTime-m_dwPlayerPointTime > WORLDSIGNTIME )
{
m_playerAreaWnd->SetShow(m_bPointSign);
m_bPointSign = !m_bPointSign;
m_dwPlayerPointTime = dwTime;
}
}
void SUIWorldMapWnd::procMonsterRegion(DWORD dwTime)
{
if (m_needApplyMonterRegionInfo)
{
m_monsterRegionInfo->apply(this, m_detailMapWnd ? false : true);
m_needApplyMonterRegionInfo = false;
}
if (m_needRefreshMonterRegionInfo)
{
m_monsterRegionInfo->refresh(this, m_detailMapWnd ? false : true);
m_needRefreshMonterRegionInfo = false;
}
m_monsterRegionInfo->process(dwTime);
}
/// 2011.03.03 - prodongi
void SUIWorldMapWnd::readyOpenDetailMap(int type, int index, bool aniAlpha, KRect const& worldRect)
{
m_openDetailMapInfo.m_is = true;
m_openDetailMapInfo.m_type = type;
m_openDetailMapInfo.m_index = index;
m_openDetailMapInfo.m_aniAlpha = aniAlpha;
m_openDetailMapInfo.m_worldRect = worldRect;
m_monsterRegionInfo->clearChild(this);
}
void SUIWorldMapWnd::openDetailMap()
{
m_openDetailMapInfo.m_is = false;
int type = m_openDetailMapInfo.m_type;
int index = m_openDetailMapInfo.m_index;
bool aniAlpha = m_openDetailMapInfo.m_aniAlpha;
KRect worldRect(m_openDetailMapInfo.m_worldRect);
char nuiName[MAX_PATH];
switch (type)
{
case SUIWorldDetailMapWnd::FIELD: sprintf(nuiName, "window_world_map_detail_area%02d.nui", index+1); break;
case SUIWorldDetailMapWnd::VILLAGE: {
switch (index)
{
case 0: strcpy(nuiName, "window_world_map_detail_village_laksy.nui"); break;
case 2: strcpy(nuiName, "window_world_map_detail_village_horizon.nui"); break;
case 3: strcpy(nuiName, "window_world_map_detail_village_katan.nui"); break;
case 4: strcpy(nuiName, "window_world_map_detail_village_beginner.nui");break;
case 5: strcpy(nuiName, "window_world_map_detail_village_ruin.nui"); break;
default:nuiName[0] = 0x00;
}
}
break;
case SUIWorldDetailMapWnd::TOWN: sprintf(nuiName, "window_world_map_detail_village_rondo_%02d.nui", index+1);break;
default: nuiName[0] = 0x00; assert(0 && "invalid_type"); break;
}
if(!KFileManager::Instance().IsValidResource(nuiName))
return ;
if (m_detailMapWnd)
{
addRemoveWndList(m_detailMapWnd);
m_detailMapWnd = NULL;
}
m_detailMapWnd = new SUIWorldDetailMapWnd(m_pGameManager);
KUIWnd* posWnd = GetChild("world_detail");
KPoint pos(posWnd->GetRect().left, posWnd->GetRect().top);
m_detailMapWnd->CreateWnd(nuiName, m_pManager, pos);
m_detailMapWnd->SetParent(this);
m_detailMapWnd->SetShow(true);
m_detailMapWnd->setType(type);
m_detailMapWnd->setIndex(index); /// 2011.06.02- prodongi
m_detailMapWnd->setWorldRect(worldRect);
m_detailMapWnd->createDungeonGate(m_dungeonGateInfoList); /// 201.07.21 - prodongi
m_detailMapWnd->createNpc(m_npcList);
m_detailMapWnd->setPlayerRotation(m_allMapWnd->getPlayerRadian()); /// 2011.03.14 - prodongi
if (aniAlpha) m_detailMapWnd->beginAlpha();
AddChild(m_detailMapWnd);
m_monsterRegionInfo->refresh(this, false);
m_noTargetTitle.setTop(this);
/// 2011.06.02 - prodongi
if (SUIWorldDetailMapWnd::TOWN == type && 3 == index)
setShowCategory(false, true);
else
setShowCategory(true);
/// 2011.03.16 test 코드, 혹시 몰르니 남겨둔다 - prodongi
//_oprint("%s\n", nuiName);
}
void SUIWorldMapWnd::closeDetailMap(bool refreshMonsterRegion)
{
if (m_detailMapWnd)
{
addRemoveWndList(m_detailMapWnd);
m_detailMapWnd = NULL;
SetChildCaption("worldmap_help_text_01", CStringUtil::StringFormat("<font:font_01><size:9><#ff8225><left>%s", S(1149)).c_str());
}
if (refreshMonsterRegion)
m_monsterRegionInfo->refresh(this, true);
}
void SUIWorldMapWnd::readyCloseDetailMap()
{
m_readyCloseDetailMap = true;
if (m_detailMapWnd)
m_detailMapWnd->endAlpha();
/// 2011.06.02 - prodongi
setShowCategory(false);
m_monsterRegionInfo->clearChild(this);
}
/// 2011.03.15 test 코드, 혹시 몰르니 남겨둔다 - prodongi
/*
void SUIWorldMapWnd::refreshNpcPos(KRect const& offset)
{
if (m_detailMapWnd)
m_detailMapWnd->refreshNpcPos(offset);
}
*/
void SUIWorldMapWnd::addRemoveWndList(KUIWnd* wnd)
{
if (!wnd)
return ;
wnd->SetShow(false);
m_removeWndList.push_back(wnd);
}
/// 2011.03.03 - prodongi
void SUIWorldMapWnd::procRemoveWndList()
{
if (m_removeWndList.empty())
return ;
OffToolTipWnd();
std::vector<KUIWnd*>::iterator it = m_removeWndList.begin();
for (; it != m_removeWndList.end(); ++it)
{
/// 2011.03.15 ReleaseCapture()를 호출 하면 안된다, 왜냐면 현재 캡춰된 넘은 *it의 자식 컨트롤이기 때문에 ReleaseCapture를 쓰면 초기화가 안된다 - prodongi
m_pManager->SetCapture(NULL);
RemoveChild(*it);
}
m_removeWndList.clear();
}
/// 2011.03.17 - prodongi
bool SUIWorldMapWnd::checkVisibleIsInRegionPlayer(const KRect &rect) const
{
int hw = rect.GetWidth() >> 1;
int hh = rect.GetHeight() >> 1;
int x = rect.left + hw;
int y = rect.top + hh;
return m_playerAreaWnd->IsInRect(x, y);
}
bool SUIWorldMapWnd::convertInvalidMonsterRegion(KRect const& r, KRect& convertR)
{
m_playerAreaWnd->SetShow(true);
bool in_lt = m_playerAreaWnd->IsInRect(r.left, r.top);
bool in_rt = m_playerAreaWnd->IsInRect(r.right, r.top);
bool in_lb = m_playerAreaWnd->IsInRect(r.left, r.bottom);
bool in_rb = m_playerAreaWnd->IsInRect(r.right, r.bottom);
/// 한개라도 영역 안에 있으면 m_rcRegion을 벗어나지 않는 경계를 다시 설정해준다
if (in_lt || in_rt || in_lb || in_rb)
{
convertR.left = ::max(r.left, m_playerAreaWnd->GetRect().left);
convertR.right = ::min(r.right, m_playerAreaWnd->GetRect().right);
convertR.top = ::max(r.top, m_playerAreaWnd->GetRect().top);
convertR.bottom = ::min(r.bottom, m_playerAreaWnd->GetRect().bottom);
return true;
}
return false;
}
/// 2011.08.30 - prodongi
KUIWnd* SUIWorldMapWnd::createMonsterRegionControl(KRect const& r, float theta)
{
/*
bool in_lt = m_playerAreaWnd->IsInRect(r.left, r.top);
bool in_rt = m_playerAreaWnd->IsInRect(r.right, r.top);
bool in_lb = m_playerAreaWnd->IsInRect(r.left, r.bottom);
bool in_rb = m_playerAreaWnd->IsInRect(r.right, r.bottom);
KRect _r;
/// 한개라도 영역 안에 있으면 m_rcRegion을 벗어나지 않는 경계를 다시 설정해준다
if (in_lt || in_rt || in_lb || in_rb)
{
_r.left = ::max(r.left, m_playerAreaWnd->GetRect().left);
_r.right = ::min(r.right, m_playerAreaWnd->GetRect().right);
_r.top = ::max(r.top, m_playerAreaWnd->GetRect().top);
_r.bottom = ::min(r.bottom, m_playerAreaWnd->GetRect().bottom);
}
else
{
return NULL;
}
*/
KUIWnd* wnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "iconstatic", "monster_region", " ", r, 0, KFLAG_NO_GET_MESSAGE, this, "", "ui_frame.spr", m_pManager, 0, "", KANCHOR_LEFT | KANCHOR_TOP ) );
if( wnd )
{
KUIControlIconStatic* staticControl = dynamicCast<KUIControlIconStatic*>(wnd);
if (staticControl)
{
staticControl->SetAbleReSizeRes(false);
staticControl->SetIcon("ui_frame.spr", "game_panel_worldmap_quest_target");
staticControl->SetRotate(theta);
}
wnd->SetShow(true);
}
return wnd;
}
KUIWnd* SUIWorldMapWnd::createQuestMarkNpcControl(char const* id)
{
KUIWnd* wnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "iconstatic", id, " ", KRect(), 0, KFLAG_NO_GET_MESSAGE, this, "common_mark_titanium_quest_target", "ui_frame.spr", m_pManager, 0, "", KANCHOR_LEFT | KANCHOR_TOP ) );
return wnd;
}
/// 2011.08.30 - prodongi
void SUIWorldMapWnd::convertWorldToUiPos(KPoint const& worldPos, KPoint &uiPos)
{
/// 디테일 맵을 먼저 체크
if (m_detailMapWnd)
m_detailMapWnd->convertWorldToUiPos(worldPos, uiPos);
else if (m_allMapWnd)
m_allMapWnd->convertWorldToUiPos(worldPos, uiPos);
}
bool SUIWorldMapWnd::getQuestMarkNpcUIRect(int npcId, KRect &r)
{
KResSprite* sprite = _getSpriteSet()->GetSpriteRes("common_mark_titanium_quest_target", 0);
if (!sprite)
return false;
std::vector<NPC_INFO>::iterator it = m_npcList.begin();
for (; it != m_npcList.end(); ++it)
{
if (it->nID == npcId)
{
KPoint uiPos;
convertWorldToUiPos(KPoint(it->x, it->y), uiPos);
m_playerAreaWnd->SetShow(true);
if (!m_playerAreaWnd->IsInRect(uiPos.x, uiPos.y))
return false;
uiPos.y -= 3; /// 여유분
int w = (int)sprite->GetSizeX();
int h = (int)sprite->GetSizeY();
int hw = w >> 1;
/// 1은 npc 마크 아이콘의 중앙으로 맞추기 위한 옵셋 값이다
r.left = uiPos.x - hw + 1;
r.top = uiPos.y - h;
r.right = uiPos.x + hw + 1;
r.bottom = uiPos.y;
return true;
}
}
return false;
}
void SUIWorldMapWnd::changeNpcIconToFinish(const std::vector<int> &npcList)
{
if (m_detailMapWnd)
m_detailMapWnd->changeNpcIconToFinish(npcList);
}
void SUIWorldMapWnd::restoreNpcIconToOriginal(const std::vector<int> &npcList)
{
if (m_detailMapWnd)
m_detailMapWnd->restoreNpcIconToOriginal(npcList);
}
void SUIWorldMapWnd::setQuestCode(int questCode)
{
/// 2011.09.30 사냥<전체 몬스터> 인지 체크 - prodongi
if (IsShow())
{
m_noTargetTitle.check(questCode);
}
bool ret = m_monsterRegionInfo->setQuestCode(questCode, this);
if (IsShow() && ret)
{
m_needApplyMonterRegionInfo = true;
}
}