#include "stdafx.h" #include #include "SStringDB.h" #include "SItemDB.h" #include "SLog.h" #include "SGameMessage.h" #include "SGameManager.h" //#include "SGameMessageUI.h" #include "SInventoryMgr.h" #include "SPlayerInfoMgr.h" //#include "KUIControl.h" #include "KUIControlStatic.h" #include "KUIControlButton.h" #include "SUIDurabilityWnd.h" //#include "SUIUtil.h" #include "SSummonSlotMgr.h" //----------------------------------------------------------------------------------------------------------------- // 이름 공간 //----------------------------------------------------------------------------------------------------------------- namespace UIDurabilityWnd { const static short g_nGauge( 12 ); const char* g_arrGaugeAni[eDurabilityGauga_Max] = { "common_guage_titanium_line_lightgrey", // 내구도가 존재하지 않는 일반 아이템 "common_guage_titanium_line_red", // 1% ~ 32% "common_guage_titanium_line_cyan", // 33% ~ 65% "common_guage_titanium_line_yellowgreen", // 66% ~ 100% "common_guage_titanium_line_Grey" }; // 내구도가 0%라서 수리가 필요한 아이템 const static short g_nGaugeCreature( 7 ); // 추가된 크리처 한마리당 슬롯 개수 const static int c_nMaxCreatureItem( 7 ); // 크리처 최대 아이템 개수 const static short g_nGaugeTotal( g_nGauge + (g_nGaugeCreature * 2) ); } //----------------------------------------------------------------------------------------------------------------- // 생성자 //----------------------------------------------------------------------------------------------------------------- SUIDurabilityWnd::SUIDurabilityWnd( SGameManager * pGameManager ) : SUIWnd( pGameManager ) { } //----------------------------------------------------------------------------------------------------------------- // 파괴자 //----------------------------------------------------------------------------------------------------------------- SUIDurabilityWnd::~SUIDurabilityWnd() { Release(); } //----------------------------------------------------------------------------------------------------------------- // 해제 //----------------------------------------------------------------------------------------------------------------- void SUIDurabilityWnd::Release() { m_arrGeneralItem.clear(); // 장비가 내구도가없는 일반아이템의경우 출력될 X 아이콘. m_arrDrabilityGauge.clear(); // 내구도게이지. m_vecUIMatchingInfo_Character.clear(); #ifdef DEF_METIN_CREATURE m_arCreatureRepair0.clear(); m_arCreatureRepair1.clear(); #endif } //----------------------------------------------------------------------------------------------------------------- // 컨트롤 초기화 //----------------------------------------------------------------------------------------------------------------- bool SUIDurabilityWnd::InitControls( KPoint kPos ) { return SUIWnd::InitControls( kPos ); } //----------------------------------------------------------------------------------------------------------------- // 윈도우 생성 //----------------------------------------------------------------------------------------------------------------- SUIWnd* SUIDurabilityWnd::CreateWnd( const char* szFile, KUIWndManager* pWndManager, KPoint kPos, int nWindowID ) { SUIWnd::CreateWnd( szFile, pWndManager, kPos, nWindowID ); CreateUIMatchingInfo_Character(); m_arrGeneralItem.resize( g_nGaugeTotal ); m_arrDrabilityGauge.resize( g_nGaugeTotal ); for( int i=g_nGauge; iSetShow( false ); else { SDEBUGLOG( "[UIDurabilityWnd] Can't Get UI Control - Name[%s]", CStringUtil::StringFormat( "gauge_repair_line_yellowgreen_%02d", i+1 ).c_str() ); assert( m_arrDrabilityGauge[i] ); continue; } } if( false == m_vecUIMatchingInfo_Character.empty() && m_vecUIMatchingInfo_Character[0].m_pGaugeBarControl ) { m_fGaugeWidth = (float)m_vecUIMatchingInfo_Character[0].m_pGaugeBarControl->GetRect().GetWidth(); // 내구도 게이지 기본넓이. } #ifdef DEF_METIN_CREATURE InitCreatureRepairUI(); #endif return this; } //----------------------------------------------------------------------------------------------------------------- // 메시지 처리 //----------------------------------------------------------------------------------------------------------------- void SUIDurabilityWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam ) { switch( nMessage ) { case KUI_MESSAGE::KGENWND_MOVE: LimitMoveWnd(); break; } SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam ); } //----------------------------------------------------------------------------------------------------------------- // 윈도우 열릴 때 //----------------------------------------------------------------------------------------------------------------- void SUIDurabilityWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd) { if( bOpen ) { RefreshDurability(); } } //----------------------------------------------------------------------------------------------------------------- // 캐릭터 내구도 UI와 장비의 매칭 정보 생성 //----------------------------------------------------------------------------------------------------------------- void SUIDurabilityWnd::CreateUIMatchingInfo_Character() { m_vecUIMatchingInfo_Character.resize( g_nGauge ); for( WORD wDurabilityUIIndex = 0; wDurabilityUIIndex < g_nGauge; wDurabilityUIIndex++ ) { UIMATCHINGINFO& stUIMatchingInfo = m_vecUIMatchingInfo_Character[wDurabilityUIIndex]; stUIMatchingInfo.m_nUIIndex = wDurabilityUIIndex; stUIMatchingInfo.m_pGaugeBarControl = GetChild( CStringUtil::StringFormat( "gauge_repair_line_yellowgreen_%02d", wDurabilityUIIndex+1 ).c_str() ); if( NULL == stUIMatchingInfo.m_pGaugeBarControl ) { SDEBUGLOG( "[UIDurabilityWnd] Can't Get UI Control - Name[%s]", CStringUtil::StringFormat( "gauge_repair_line_yellowgreen_%02d", wDurabilityUIIndex+1 ).c_str() ); assert( stUIMatchingInfo.m_pGaugeBarControl ); } else stUIMatchingInfo.m_pGaugeBarControl->SetShow( false ); stUIMatchingInfo.m_pBrokenIconControl = GetChild( CStringUtil::StringFormat( "mark_none_ex%02d", wDurabilityUIIndex+1 ).c_str() ); if( NULL == stUIMatchingInfo.m_pBrokenIconControl ) { SDEBUGLOG( "[UIDurabilityWnd] Can't Get UI Control Pointer - Name[%s]", CStringUtil::StringFormat( "mark_none_ex%02d", wDurabilityUIIndex+1 ).c_str() ); assert( stUIMatchingInfo.m_pBrokenIconControl ); } else { stUIMatchingInfo.m_pBrokenIconControl->SetAniName( "common_mark_titanium_repair_none" ); stUIMatchingInfo.m_pBrokenIconControl->SetShow( false ); } stUIMatchingInfo.m_nWearType = GetWearTypeFromDurabilityUIIndex( wDurabilityUIIndex ); } } //----------------------------------------------------------------------------------------------------------------- // 내구도 UI Index로 부터 장비 타입 얻기 // 추가 설명 : 하드 코딩 하기로 협약 된 부분입니다. 이해하세요... //----------------------------------------------------------------------------------------------------------------- UINT SUIDurabilityWnd::GetWearTypeFromDurabilityUIIndex( WORD wDurabilityUIIndex ) { switch( wDurabilityUIIndex ) { case 0: return ItemBase::ItemWearType::WEAR_HELM; case 1: return ItemBase::ItemWearType::WEAR_ARMOR; case 2: return ItemBase::ItemWearType::WEAR_GLOVE; case 3: return ItemBase::ItemWearType::WEAR_BOOTS; case 4: return ItemBase::ItemWearType::WEAR_WEAPON; case 5: return ItemBase::ItemWearType::WEAR_SHIELD; case 6: return ItemBase::ItemWearType::WEAR_EAR; case 7: return ItemBase::ItemWearType::WEAR_SECOND_EAR; case 8: return ItemBase::ItemWearType::WEAR_RING; case 9: return ItemBase::ItemWearType::WEAR_SECOND_RING; case 10: return ItemBase::ItemWearType::WEAR_BELT; case 11: return ItemBase::ItemWearType::WEAR_ARMULET; default: { SDEBUGLOG( "[UIDurabilityWnd] Invalide UI Index Number - UI Index [%d]", wDurabilityUIIndex ); } return ItemBase::ItemWearType::WEAR_CANTWEAR; } return ItemBase::ItemWearType::WEAR_CANTWEAR; } void SUIDurabilityWnd::ProcMsgAtStatic(SGameMessage* pMsg) { switch (pMsg->nType) { case MSG_ITEM_WEAR_INFO: case MSG_ITEM_INVEN: RefreshDurability(); break; case IMSG_UI_MOVE: { pMsg->bUse = true; SIMSG_UI_MOVE* pMoveMsg = (SIMSG_UI_MOVE*)pMsg; if (pMoveMsg->m_nX != this->GetRect().left || pMoveMsg->m_nY != this->GetRect().top) MovePos(pMoveMsg->m_nX, pMoveMsg->m_nY); } break; case IMSG_UI_SEND_DATA: { SIMSG_UI_SEND_DATA* pData = (SIMSG_UI_SEND_DATA*)pMsg; if (pData->m_strString == "refresh_durability") { RefreshDurability(); } } break; } } //----------------------------------------------------------------------------------------------------------------- // 장비 타입으로 부터 매칭 정보 얻기 //----------------------------------------------------------------------------------------------------------------- PUIMATCHINGINFO SUIDurabilityWnd::FindUIMatchingInfoFromWearType( const int nWearType ) { if( m_vecUIMatchingInfo_Character.empty() ) return NULL; for( UINT nCount = 0; nCount < m_vecUIMatchingInfo_Character.size(); nCount++ ) { UIMATCHINGINFO stUIMatchingInfo = m_vecUIMatchingInfo_Character[nCount]; if( stUIMatchingInfo.m_nWearType == static_cast( nWearType ) ) return &m_vecUIMatchingInfo_Character[nCount]; } return NULL; } //----------------------------------------------------------------------------------------------------------------- // 장비 타입으로 부터 내구도 정보 얻기 //----------------------------------------------------------------------------------------------------------------- void SUIDurabilityWnd::GetDurabilityInfoFromWearType(const int nWearType, eWearItemStatus& eItemStatus, float& fDurabilityPercent) { SInventorySlot* pSlot( m_InventoryMgr.GetItemInfo( nWearType ) ); if( pSlot ) // 장비 있음 { const ItemBaseEx_info* pItemBase( GetItemDB().GetItemData( pSlot->GetItemCode() ) ); if( NULL == pItemBase ) { SDEBUGLOG( "[UIDurabilityWnd] Can't Get ItemInfo - ItemCode [ %n ]", pSlot->GetItemCode() ); assert( pItemBase ); eItemStatus = eWearItemStatus::eNone; fDurabilityPercent = 0.0f; } else { if( pSlot->getMaxEtherealDurability() > 0 ) // 상급 아이템 { float ethereal( pSlot->GetEtherealDurability() ); if( ethereal > 0.0f ) { eItemStatus = eWearItemStatus::eHighClass; fDurabilityPercent = (float)ethereal / (float)pSlot->getMaxEtherealDurability(); if( ( (float)pSlot->getMaxEtherealDurability() / 10000.0f ) - ( ethereal / 10000.0f ) < 1.0f ) fDurabilityPercent = 1.0f; } else { eItemStatus = eWearItemStatus::eBroken; fDurabilityPercent = 0.0f; } } else { eItemStatus = eWearItemStatus::eNormalClass; // 일반 아이템 fDurabilityPercent = 1.0f; } } } else // 장비 없음 { eItemStatus = eWearItemStatus::eNone; fDurabilityPercent = 0.0f; } return ; } //----------------------------------------------------------------------------------------------------------------- // 내구도 갱신 //----------------------------------------------------------------------------------------------------------------- void SUIDurabilityWnd::RefreshDurability() { for( UINT nCount = 0; nCount < m_vecUIMatchingInfo_Character.size(); nCount++ ) { UIMATCHINGINFO stUIMatchingInfo = m_vecUIMatchingInfo_Character[nCount]; if( stUIMatchingInfo.m_pGaugeBarControl ) stUIMatchingInfo.m_pGaugeBarControl->SetShow( false ); if( stUIMatchingInfo.m_pBrokenIconControl ) { stUIMatchingInfo.m_pBrokenIconControl->SetAniName( "common_mark_titanium_repair_none" ); stUIMatchingInfo.m_pBrokenIconControl->SetShow( false ); } } for( int nWearType = ItemBase::ItemWearType::WEAR_WEAPON; nWearType < ItemBase::ItemWearType::WEAR_FACE; ++nWearType ) { if( nWearType == ItemBase::ItemWearType::WEAR_MANTLE ) // 망토는 제외 continue; eDurabilityGaugaKind eGaugaKind( eDurabilityGauga_DontHave ); eWearItemStatus eItemStatus( eWearItemStatus::eNone ); float fDurabilityPercent( 0.0f ); // UI 매칭 정보 얻기 PUIMATCHINGINFO pUIMatchingInfo( FindUIMatchingInfoFromWearType( nWearType ) ); // 내구도 정도 얻기 GetDurabilityInfoFromWearType( nWearType, eItemStatus, fDurabilityPercent ); switch( eItemStatus ) { case eWearItemStatus::eNone: break; case eWearItemStatus::eNormalClass: { eGaugaKind = eDurabilityGauga_DontHave; if( pUIMatchingInfo && pUIMatchingInfo->m_pGaugeBarControl ) pUIMatchingInfo->m_pGaugeBarControl->SetShow( true ); } break; case eWearItemStatus::eHighClass: { if( fDurabilityPercent < 0.33f ) // red. eGaugaKind = eDurabilityGauga_Danger; else if( fDurabilityPercent < 0.66f ) // cyan. eGaugaKind = eDurabilityGauga_Warning; else // yellowgreen. eGaugaKind = eDurabilityGauga_Normal; if( pUIMatchingInfo && pUIMatchingInfo->m_pGaugeBarControl ) pUIMatchingInfo->m_pGaugeBarControl->SetShow( true ); } break; case eWearItemStatus::eBroken: { eGaugaKind = eDurabilityGauga_Broken; if( pUIMatchingInfo && pUIMatchingInfo->m_pBrokenIconControl ) { pUIMatchingInfo->m_pBrokenIconControl->SetAniName( "common_mark_titanium_repair_zero" ); pUIMatchingInfo->m_pBrokenIconControl->SetShow( true ); } if( pUIMatchingInfo && pUIMatchingInfo->m_pGaugeBarControl ) pUIMatchingInfo->m_pGaugeBarControl->SetShow( true ); } break; default: assert( NULL ); break; } if( pUIMatchingInfo && pUIMatchingInfo->m_pGaugeBarControl ) { KRect rt( pUIMatchingInfo->m_pGaugeBarControl->GetRect() ); pUIMatchingInfo->m_pGaugeBarControl->SetAniName( g_arrGaugeAni[ eGaugaKind ] ); rt.right = rt.left + m_fGaugeWidth * fDurabilityPercent; pUIMatchingInfo->m_pGaugeBarControl->Resize( rt ); } } for( int j = g_nGauge; j < g_nGaugeTotal; j++ ) { m_arrDrabilityGauge[ j ]->SetShow(false); } int nCount = m_CreatureSlotMgr.GetCreatureItemCount( m_CreatureSlotMgr.GetSelectedCreature() ); nCount = max( nCount, c_nMaxCreatureItem ); // 크리처관련 내구도 int nSummonCount = 0; int nStartID = g_nGauge; for( int k = 0; k < SCreatureSlotMgr::MAX_CREATURE_SLOT; k++ ) { if( nSummonCount >= SCreatureSlotMgr::MAX_SUMMON_SLOT ) break; AR_HANDLE hCreture = m_CreatureSlotMgr.GetCreatureHandleByCardHandle( m_CreatureSlotMgr.GetEquipedCreatureCard(k) ); if( m_CreatureSlotMgr.IsExistSummonedCreature( hCreture ) == false ) continue ; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( m_CreatureSlotMgr.GetEquipedCreatureCard(k) ); if( pSlot ) { refreshItemDurability( pSlot, m_arrDrabilityGauge[ nStartID ], m_fGaugeWidth ); } for( int i = 0; i < c_nMaxCreatureItem - 2; i++ ) { AR_HANDLE hItem = m_CreatureSlotMgr.GetCreatureItem( hCreture, i ); if( hItem == NULL ) continue; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( pSlot ) { // m_arrDrabilityGauge[ nStartID + i + 1 ] : 은 아이템 슬롯 전에 크리처 카드 슬롯이 있어서 인덱스 1 더해준다 refreshItemDurability( pSlot, m_arrDrabilityGauge[ nStartID + i + 1 ], m_fGaugeWidth ); } } nStartID += g_nGaugeCreature; nSummonCount++; } } #ifdef DEF_METIN_CREATURE // UI가 그룹으로 묶여져 있지를 않다. 그룹으로 묶고 싶다 ㅠㅠ void SUIDurabilityWnd::InitCreatureRepairUI() { for ( int i = c_nUICreatureRepair0; i < c_nUICreatureRepair0 + c_nRepairSlotSize; i++ ) { KUIWnd* pWnd = GetChild( CStringUtil::StringFormat( "guage_base_%02d", i ).c_str() ); m_arCreatureRepair0.push_back(pWnd); pWnd = GetChild( CStringUtil::StringFormat( "mark_%02d", i ).c_str() ); m_arCreatureRepair0.push_back(pWnd); } for ( int i = c_nUICreatureRepair1; i < c_nUICreatureRepair1 + c_nRepairSlotSize; i++ ) { KUIWnd* pWnd = GetChild( CStringUtil::StringFormat( "guage_base_%02d", i ).c_str() ); m_arCreatureRepair1.push_back(pWnd); pWnd = GetChild( CStringUtil::StringFormat( "mark_%02d", i ).c_str() ); m_arCreatureRepair1.push_back(pWnd); } } void SUIDurabilityWnd::SetShowCreatureRepairUI(int nCreatureUI, bool bShow) { vector< KUIWnd*> *pCreatureUI = NULL; switch(nCreatureUI) { case 0: pCreatureUI = &m_arCreatureRepair0; break; case 1: pCreatureUI = &m_arCreatureRepair1; break; default: return; } for ( int i = 0; i < pCreatureUI->size(); i++ ) { KUIWnd* pWnd = pCreatureUI->at(i); pWnd->SetShow(bShow); } } #endif