#include "stdafx.h" #include "KUITabControl.h" #include "KUIControlButton.h" #include "KUIControlStatic.h" #include "KUIControlScroll.h" #include "SGameManager.h" //#include "SGameMessageUI.h" #include "SUICreatureSkillWnd.h" #include "SUIDisplayInfo.h" #include "SUILazyTooltip.h" #include "SSkillDB.h" #include "SStringDB.h" #include "SCreatureDB.h" #include "SSummonSlotMgr.h" #include "SSkillSlot.h" #include "ErrorCode/ErrorCode.h" #include "SUISysMsgDefine.h" #include "SInventoryMgr.h" #include "SLog.h" namespace nsUICreatureSkillFundWnd { const int c_nDelta( 38 ); // 늘어나는 단위 const int c_nIconSelectDelta( 4 ); // 아이콘 선택 static 표시 위치 delta const int c_nMAXLine( 7 ); const char* c_szTAB( "creature_skillfund_tab" ); const KColor g_enabledSkillIconColor( 0xffffffff ); const KColor g_disabledSkillIconColor( 0xff404040 ); enum { // 탭 타입 TAB_ACTIVE = 0, TAB_PASSIVE, }; }; using namespace rp; using namespace nsUICreatureSkillFundWnd; //----------------------------------------------------------------------------------------------------------------- // 생성자 //----------------------------------------------------------------------------------------------------------------- SUICreatureSkillFundWnd::SUICreatureSkillFundWnd( SGameManager* pGameManager, SUIDisplayInfo* pDisplayInfo ) : SUIWnd( pGameManager ) , m_pDisplayInfo( pDisplayInfo ) , m_nTabType( NULL ) , m_nGrade( NULL ) , m_nMaxLine( c_nMAXLine ) , m_nScrollPos( NULL ) { } //----------------------------------------------------------------------------------------------------------------- // 파괴자 //----------------------------------------------------------------------------------------------------------------- SUICreatureSkillFundWnd::~SUICreatureSkillFundWnd() { ClearSkillList(); } //----------------------------------------------------------------------------------------------------------------- // 컨트롤 초기화 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::InitControls( KPoint kPos ) { // 탭 만들기 KUISimpleTabControl* pTabControl = dynamicCast(GetChild(c_szTAB)); if( pTabControl ) { pTabControl->SetTabProperty( 0, false, 2 ); pTabControl->AddTabItem( S(6236)/*"액티브"*/, S(6305)/*"액티브 스킬"*/ ); pTabControl->AddTabItem( S(6256)/*"패시브"*/, S(6306)/*"패시브 스킬"*/ ); } CreateControls(); return SUIWnd::InitControls(kPos); } //----------------------------------------------------------------------------------------------------------------- // 데이터 초기화 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::InitData( bool bReload ) { if( bReload ) ClearSkillList(); m_nScrollPos = 0; m_nTabType = 0; m_nMaxLine = c_nMAXLine; DisableAllSlot(); HideSelectBar(); return SUIWnd::InitData(bReload); } //----------------------------------------------------------------------------------------------------------------- // 메시지 처리 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam ) { switch(nMessage) { case KUI_MESSAGE::KBUTTON_CLICK: { m_pGameManager->StartSound( "ui_click_jlv01.wav" ); string str; for( int i = 0; i < m_nMaxLine; i++ ) { str = CStringUtil::StringFormat( "creature_skillfund_up%02d", i ); if( ::_stricmp( lpszControlID, str.c_str() ) == 0 ) { ShowSelectBar(i, m_nGrade); SkillUP(i, m_nGrade); break; } } } break; case KUI_MESSAGE::KICON_CLICK: { m_pGameManager->StartSound( "ui_button_click.wav" ); string str; for( int i = 0; i < m_nMaxLine; i++ ) { str = CStringUtil::StringFormat( "creature_skillfund_icon%02d", i ); if( ::_stricmp( lpszControlID, str.c_str() ) == 0 ) // 선택처리 { ShowSelectBar(i, m_nGrade); break; } } } break; case KUI_MESSAGE::KSCROLL_SELECT: // 스크롤 선택 { int nPos = (int)lparam; nPos = max( nPos, 0 ); m_nScrollPos = nPos; RefreshSkillSlot(m_nGrade, nPos); } break; case KUI_MESSAGE::KTAB_SELECT: // 탭 변경 { SelectTab(); InitScrollPosition(); m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CREATURE_FUND_TAB_UPDATE( m_nTabType, m_nGrade ) ); } break; } SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam ); } //----------------------------------------------------------------------------------------------------------------- // 정적 메시지 처리 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::ProcMsgAtStatic( SGameMessage* pMsg ) { switch(pMsg->nType) { case IMSG_UI_MOVE: { SIMSG_UI_MOVE* pMoveMsg = ( SIMSG_UI_MOVE* )pMsg; MovePos( pMoveMsg->m_nX, pMoveMsg->m_nY-GetRect().GetHeight() ); pMsg->bUse = true; } break; case IMSG_UI_SEND_DATA: { SIMSG_UI_SEND_DATA* msg = (SIMSG_UI_SEND_DATA*)pMsg; if (msg->m_strString == "refresh") { if (IsShow()) UpdateSkillList(m_nTabType, m_nGrade); } pMsg->bUse = true; } break; case IMSG_UI_CREATURE_FUND_TAB_UPDATE: { if( IsShow() ) { SIMSG_UI_CREATURE_FUND_TAB_UPDATE* pSkillMsg = ( SIMSG_UI_CREATURE_FUND_TAB_UPDATE* )pMsg; UpdateSkillList( pSkillMsg->m_nTabType, pSkillMsg->m_nGradeTab ); #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } pMsg->bUse = true; } break; case MSG_ADDED_SKILL_LIST: case MSG_SKILL_LIST: case MSG_LEVEL_UPDATE: { RefreshSkillInfo(); RefreshScrollbar( m_nGrade ); RefreshSkillSlot( m_nGrade, m_nScrollPos ); pMsg->bUse = true; #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } break; case MSG_EXP_UPDATE: { RefreshSkillSlot( m_nGrade, m_nScrollPos ); pMsg->bUse = true; #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } break; case MSG_PROPERTY: { SMSG_PROPERTY* pPropertyMsg = (SMSG_PROPERTY*)pMsg; switch( pPropertyMsg->nPropertyType ) { case SMSG_PROPERTY::PROPERTY_LEVEL: case SMSG_PROPERTY::PROPERTY_EXP: case SMSG_PROPERTY::PROPERTY_JP: { RefreshSkillInfo(); RefreshScrollbar( m_nGrade ); RefreshSkillSlot( m_nGrade, m_nScrollPos ); #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } break; } pMsg->bUse = true; } break; case MSG_RESULT: { SMSG_RESULT* pMsgResult = (SMSG_RESULT*)pMsg; switch(pMsgResult->request_msg_id) { case TM_CS_JOB_LEVEL_UP: { if( pMsgResult->result == RESULT_SUCCESS ) { RefreshSkillInfo(); RefreshScrollbar( m_nGrade ); RefreshSkillSlot( m_nGrade, m_nScrollPos ); #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } } break; } pMsg->bUse = true; } break; } } //----------------------------------------------------------------------------------------------------------------- // 스킬투자윈도우 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::CreateControls() { RECT rc; rc.left = 0; rc.top = c_nDelta; rc.right = 0; rc.bottom = c_nDelta; KUIWnd* pIconCtr(NULL); pIconCtr = GetChild( "creature_skillfund_icon00" ); if( pIconCtr ) pIconCtr->SetCorrectionRect( KRect( 0, 0, 130, 0 ) ); for( int i = 0; i < m_nMaxLine-1; i++ ) { pIconCtr = CopyControl( CStringUtil::StringFormat( "creature_skillfund_icon%02d" , i ).c_str(), CStringUtil::StringFormat( "creature_skillfund_icon%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "creature_skillfund_up%02d" , i ).c_str(), CStringUtil::StringFormat( "creature_skillfund_up%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "creature_skillfund_01info%02d" , i ).c_str(), CStringUtil::StringFormat( "creature_skillfund_01info%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "creature_skillfund_01info%02d_value", i ).c_str(), CStringUtil::StringFormat( "creature_skillfund_01info%02d_value", i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "creature_skillfund_02info%02d" , i ).c_str(), CStringUtil::StringFormat( "creature_skillfund_02info%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "static_use_jp%02d" , i ).c_str(), CStringUtil::StringFormat( "static_use_jp%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "creature_skillfund_jp%02d" , i ).c_str(), CStringUtil::StringFormat( "creature_skillfund_jp%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "static_use_mp%02d" , i ).c_str(), CStringUtil::StringFormat( "static_use_mp%02d" , i+1 ).c_str(), rc ); CopyControl( CStringUtil::StringFormat( "static_use_mp_value%02d" , i ).c_str(), CStringUtil::StringFormat( "static_use_mp_value%02d" , i+1 ).c_str(), rc ); if( pIconCtr ) pIconCtr->SetCorrectionRect( KRect( 0, 0, 130, 0 ) ); } for( int i = 0; i < m_nMaxLine; i++ ) { SetChildCaption( CStringUtil::StringFormat( "creature_skillfund_up%02d", i ).c_str(), GetStringDB().GetString( STRING_UP ) ); } SetChildAsTop( "icon_select_over" ); } //----------------------------------------------------------------------------------------------------------------- // 스킬 리스트 얻기 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::GetSkillList( int nGrade, bool bPassive, vector*& pSkillTreeList ) { switch( nGrade ) { case 0: !bPassive ? pSkillTreeList = &m_vActiveSkillTreeList_1 : pSkillTreeList = &m_vPassiveSkillTreeList_1; break; case 1: !bPassive ? pSkillTreeList = &m_vActiveSkillTreeList_2 : pSkillTreeList = &m_vPassiveSkillTreeList_2; break; case 2: !bPassive ? pSkillTreeList = &m_vActiveSkillTreeList_3 : pSkillTreeList = &m_vPassiveSkillTreeList_3; break; } } //----------------------------------------------------------------------------------------------------------------- // 스킬 리스트 갱신 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::UpdateSkillList( int nTabType, int nGrade ) { m_nTabType = nTabType; m_nScrollPos = 0; m_nGrade = nGrade; KUISimpleTabControl* pTab( dynamicCast(GetChild(c_szTAB)) ); if( pTab ) pTab->SetSelectedItem( (DWORD)nTabType ); ClearSkillList(); RefreshSkillInfo(); RefreshScrollbar( nGrade ); RefreshSkillSlot( nGrade, m_nScrollPos ); } //----------------------------------------------------------------------------------------------------------------- // 스킬 리스트 비우기 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::ClearSkillList() { m_vActiveSkillTreeList.clear(); m_vActiveSkillTreeList_1.clear(); m_vActiveSkillTreeList_2.clear(); m_vActiveSkillTreeList_3.clear(); m_vPassiveSkillTreeList.clear(); m_vPassiveSkillTreeList_1.clear(); m_vPassiveSkillTreeList_2.clear(); m_vPassiveSkillTreeList_3.clear(); } //----------------------------------------------------------------------------------------------------------------- // 스킬 인가? //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::IsSkill( int nIndex, int nGrade ) { vector* pSkillTreeList(NULL); GetSkillList( nGrade, !IsActiveTab(), pSkillTreeList ); if( pSkillTreeList && nIndex >= 0 && nIndex < pSkillTreeList->size() ) return true; return false; } //----------------------------------------------------------------------------------------------------------------- // 스킬 정보 갱신 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::RefreshSkillInfo() { const SCreatureInfo* creatureInfo( m_CreatureSlotMgr.GetCreatureInfo( m_CreatureSlotMgr.GetSelectedCreature() ) ); if( creatureInfo == NULL ) return ; // update tab by evolution count UpdateTab( GetEvolution( *creatureInfo ) ); ClearSkillList(); // 진화 이전 크리쳐 ID 도 얻어 와서, 배우지 않은 스킬 모두를 표시 한다. vector creatureIDs; GetCreatureDB().GetEvolveID( creatureInfo->GetID(), creatureIDs ); if( creatureIDs.empty() ) return ; // 2010.05.18 크리쳐 슬롯 정보- prodongi SInventorySlot* slot( m_InventoryMgr.GetItemInfo(m_CreatureSlotMgr.GetSelectedCreatureCard()) ); int enhance = (slot) ? slot->GetEnhance() : 0; for( unsigned int grade = 0; grade < creatureIDs.size(); ++grade ) { // 왜 여기서는 vector에 SkillTree를 보관하고 아래서는 주소값을 보관하는 것인가??? // SkillTreeData가 어차피 DB상에서 얻어오는 것이기 때문에 변화할 일은 없겠지만 // 서로 저장하는 방식이 다르다는 것이 옳은 것인가?? OTL int creatureID = creatureIDs[ grade ]; const _SUMMON_INFO_FILE* pSummonDB = GetCreatureDB().GetCreatureData( creatureID ); if( pSummonDB == NULL ) continue; for( int i = 0; i < _countof( pSummonDB->skill_tree_id ); ++i ) { if( pSummonDB->skill_tree_id[i] == 0 ) continue; const vector< SkillTreeEx >* creatureSkillTree = GetSkillTreeDB().GetSkillTreeData( pSummonDB->skill_tree_id[i] ); if( !creatureSkillTree ) continue; vector< SkillTreeEx >::const_iterator it = creatureSkillTree->begin(), itEnd = creatureSkillTree->end(); while( it != itEnd ) { SkillTreeEx stSkillTree( (*it) ); // DB상에 들어있는 데이터는 크리처가 5렙단위로 특정 스킬을 몇렙까지 // 학습할 수 있는가의 데이터이다. // ex) tree.jop_lv = 5 && tree.skill_id = 1 && tree.max_skill_lv 이라는 데이터가 있다면.... // 잡렙이 5이상이라면 1이라는 스킬을 max_skill_lv만큼 올릴 수 있다. // tree.jop_lv = 10 && tree.skill_id = 1 && tree.max_skill_lv 이 또 정의 되있다면... // 앞에서 잡렙 5렙일때의 조건은 무시해버려야한다 잡렙이 10일때의 max_skill_lv이 // 기준이 된다. // 크리처가 기본형렙 50, 성장형 35렙이라면.... // 스킬트리를 돌면서 잡렙요구 35렙이하의 스킬트리정보를 리스트에 저장한다. // 반복문을 돌다가 동일한 아이디의 스킬이 나온다면 무조건 max_skill_lv높은 // 스킬트리 정보를 저장한다. // 여기서 저장해야 할 스킬트리 정보는 내가 학습가능한 스킬트리 정보이다. // 아래 컨트롤들을 업데이트할때 스킬트리 정보를 뽑아서 배운 스킬이라면 // 현재 학습한 스킬렙+1을 학습 안한것은 1로 컨트롤에 업데이트한다. if( stSkillTree.skill_tree_id != pSummonDB->skill_tree_id[i] ) { it++; continue; } int nSkillID = 0; if( stSkillTree.bIsRandomSkill ) { const SUMMON_RANDOM_SKILL_ID* const pRandomSkillIDList = GetSummonRandomSkillDB().GetRandomSkillIDList( stSkillTree.skill_group_id ); if( NULL == pRandomSkillIDList ) { SDEBUGLOG( "[SUICreatureSkillFundWnd] 랜덤 스킬 ID 리스트 정보를 얻어 올 수 없습니다. - 그룹 ID [ %u ]", stSkillTree.skill_group_id ); assert( NULL ); continue; } bool bIsFind( false ); for( UINT nCount = 0; nCount < pRandomSkillIDList->vecSkillID.size(); nCount++ ) { if( m_CreatureSkillSlotMgr.IsExistSkill( pRandomSkillIDList->vecSkillID[nCount], m_CreatureSlotMgr.GetSelectedCreature() ) ) { int nChangedSkillID( pRandomSkillIDList->vecSkillID[nCount] ); stSkillTree.nChangedSkillID = nChangedSkillID; nSkillID = nChangedSkillID; bIsFind = true; } } // 랜덤 스킬인데 스킬 리스트 중에 없다면, 아직 배우지 않은 스킬이다. if( false == bIsFind ) nSkillID = stSkillTree.skill_id; } else nSkillID = stSkillTree.skill_id; if( NULL == nSkillID ) { SDEBUGLOG( "[SUICreatureSkillFundWnd] 스킬 ID가 유효하지 않습니다. - 스킬트리 ID [ %d ]", stSkillTree.skill_tree_id ); assert( NULL ); it++; continue; } SkillBaseEx* pSkillData( GetSkillDB().GetSkillData( nSkillID ) ); if( NULL == pSkillData ) { SDEBUGLOG( "[SUICreatureSkillFundWnd] 스킬 데이터를 얻어 올 수 없습니다. - 스킬트리 ID [ %d ]", stSkillTree.skill_tree_id ); assert( NULL ); ++it; continue; } // 스킬을 배우기위한 크리처의 필요 잡렙을 충족하지 못하여 continue; if( creatureInfo->GetEvolLevel( grade ) < stSkillTree.jop_lv ) { ++it; continue; } // 이미 배운 스킬인데 배운 레벨이 더 높으니 continue; if( !m_CreatureSkillSlotMgr.AbleLearnSkill( nSkillID, stSkillTree.max_skill_lv, m_CreatureSlotMgr.GetSelectedCreature() ) ) { ++it; continue; } // 2010.05.18 강화 조건 검색 - prodongi // AziaMafia Fix enhance Max stSkillTree.cenhance_max //if (enhance < stSkillTree.cenhance_min || enhance > stSkillTree.cenhance_max) if (enhance < stSkillTree.cenhance_min || enhance > 25) { ++it; continue; } vector* activeList = 0; vector* passiveList = 0; // ChangeSkill() : 이미 스킬이 등록되있는데 // 새로 등록하려는 트리정보가 스킬상승 레벨이 더 높다면 change if( !pSkillData->IsPassive() ) { GetSkillList( grade, false, activeList ); if( !ChangeSkill( stSkillTree, m_vActiveSkillTreeList ) ) { m_vActiveSkillTreeList.push_back( stSkillTree ); } if( activeList ) activeList->push_back( stSkillTree ); } else { GetSkillList( grade, true, passiveList ); if( !ChangeSkill( stSkillTree, m_vPassiveSkillTreeList ) ) { m_vPassiveSkillTreeList.push_back( stSkillTree ); } if( passiveList ) passiveList->push_back( stSkillTree ); } ++it; } } } creatureIDs.clear(); RefreshSkillSlot( m_nGrade ); RefreshScrollbar( m_nGrade ); } //----------------------------------------------------------------------------------------------------------------- // 진화 단계 얻기 //----------------------------------------------------------------------------------------------------------------- int SUICreatureSkillFundWnd::GetEvolution( const SCreatureInfo& creatureInfo ) { int evolution( NULL ), evolutionLv( NULL ); for( int i = 0; i < SCreatureInfo::MAX_CREATURE_EVOLUTION; ++i ) { evolutionLv = creatureInfo.GetEvolLevel( i ); if( evolutionLv != -1 && evolutionLv ) ++evolution; else break; } return evolution; } //----------------------------------------------------------------------------------------------------------------- // 스킬 변경 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::ChangeSkill( const SkillTreeEx& rTree, vector& rcmpSkillList ) { vector::iterator It = rcmpSkillList.begin(); while( It != rcmpSkillList.end() ) { const SkillTreeEx stSkillTree( (*It) ); if( stSkillTree.skill_id == rTree.skill_id ) { if( stSkillTree.max_skill_lv > rTree.max_skill_lv ) { rcmpSkillList.erase( It ); rcmpSkillList.push_back( stSkillTree ); } return true; } ++It; } return false; } //----------------------------------------------------------------------------------------------------------------- // 트리 체크 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::IsTreeCheck( const vector& vSkill_list, int nSkillID ) { vector::const_iterator iter = vSkill_list.begin(); for( ; iter != vSkill_list.end(); ++iter ) { if( (*iter).skill_id == nSkillID ) return true; } return false; } //----------------------------------------------------------------------------------------------------------------- // 스킬 아이디 얻기 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::GetSkillID( int& outId, int& outLv, int index, int grade ) { vector* pActiveSkillTreeList( NULL ); GetSkillList( grade, !IsActiveTab(), pActiveSkillTreeList ); if( !pActiveSkillTreeList ) return false; if( index >= 0 && index < pActiveSkillTreeList->size() ) { const SkillTreeEx stSkillTree( pActiveSkillTreeList->at( index ) ); if( true == stSkillTree.bIsRandomSkill && // 랜덤 스킬이고 NULL != stSkillTree.nChangedSkillID ) // 바뀐 스킬 아이디가 있다면 (랜덤으로 결정 된) { outId = stSkillTree.nChangedSkillID; // 바뀐 스킬 아이디 } else { outId = stSkillTree.skill_id; } outLv = m_CreatureSkillSlotMgr.GetBaseSkillLevel( outId, m_CreatureSlotMgr.GetSelectedCreature() ); return true; } return false; } //----------------------------------------------------------------------------------------------------------------- // 습득 가능 한 스킬 정보 얻기 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::GetLearnableSkillIDnLv( int& outId, int& outoriginskilliD, int& outLearnableLv, int index, int grade ) { vector* pActiveSkillTreeList( NULL ); GetSkillList( grade, !IsActiveTab(), pActiveSkillTreeList ); if( !pActiveSkillTreeList ) return false; if( index >= 0 && index < pActiveSkillTreeList->size() ) { const SkillTreeEx stSkillTree( pActiveSkillTreeList->at( index ) ); // 기존 스킬이라면, 기존 대로 outId에 스킬 ID를 넣는다. // 랜덤 스킬이라면, 기존의 결정되지 않은 스킬 ID (? 스킬 ID)를 outoriginskilliD에 넣어주고 // 랜덤 스킬로 인해 바뀐 Skill ID 를 outId에 넣는다. if( true == stSkillTree.bIsRandomSkill && // 랜덤 스킬이고 NULL != stSkillTree.nChangedSkillID ) // 바뀐 스킬 아이디가 있다면 (랜덤으로 결정 된) { outId = stSkillTree.nChangedSkillID; // 바뀐 스킬 아이디 outoriginskilliD = stSkillTree.skill_id; // 바뀌기 전의 스킬 아이디 } else { outId = stSkillTree.skill_id; outoriginskilliD = 0; } outLearnableLv = m_CreatureSkillSlotMgr.GetBaseSkillLevel( outId, m_CreatureSlotMgr.GetSelectedCreature() ) + 1; if( outLearnableLv > stSkillTree.max_skill_lv ) return false; return m_CreatureSkillSlotMgr.AbleLearnSkill( outId, outLearnableLv, m_CreatureSlotMgr.GetSelectedCreature() ); } return false; } //----------------------------------------------------------------------------------------------------------------- // 스킬 슬롯 갱신 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::RefreshSkillSlot( int nGrade, int nRange ) { HideSelectBar(); DisableAllSlot( false ); vector* pActiveSkillTreeList( NULL ); GetSkillList( nGrade, !IsActiveTab(), pActiveSkillTreeList ); if( !pActiveSkillTreeList ) return; int nStart = nRange; int nActiveSize = pActiveSkillTreeList->size(); for( int index = 0; index < m_nMaxLine; index++, nStart++ ) { if( nStart >= 0 && nStart < nActiveSize ) { //gmpbigsun(20130708, #26906 ) : 이게 뭔가... 지역변수를 넘기고 자빠볐?.. //SkillTreeEx stSkillTree( pActiveSkillTreeList->at( nStart ) ); SkillTreeEx* pSkillTree = &pActiveSkillTreeList->at( nStart ); DisableSlot( index, true ); SetSkillData( pSkillTree, index, true ); } } } //----------------------------------------------------------------------------------------------------------------- // 스킬 //----------------------------------------------------------------------------------------------------------------- bool SUICreatureSkillFundWnd::IsPrecedentSkillSatisfied( const SkillTreeEx& tree ) { bool bPrecedentSkillSatisfied = false; for( int index = 0; index < 3; index++ ) { if( tree.need_skill_id[ index ] == 0 ) bPrecedentSkillSatisfied = true; else { if( m_CreatureSkillSlotMgr.GetBaseSkillLevel( tree.need_skill_id[ index ], m_CreatureSlotMgr.GetSelectedCreature() ) >= tree.need_skill_lv[ index ] ) { bPrecedentSkillSatisfied = true; } else { bPrecedentSkillSatisfied = false; break; } } } return bPrecedentSkillSatisfied; } //----------------------------------------------------------------------------------------------------------------- // 스킬 데이터 설정 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::SetSkillData( const SkillTreeEx* pSkillTree, int nIndex, bool bShow ) { if( pSkillTree == NULL ) return; int nSkillID( NULL ); if( true == pSkillTree->bIsRandomSkill && // 랜덤 스킬이고 NULL != pSkillTree->nChangedSkillID ) // 바뀐 스킬 아이디가 있다면 { nSkillID = pSkillTree->nChangedSkillID; } else nSkillID = pSkillTree->skill_id; if( NULL == nSkillID ) { SDEBUGLOG( "[SUICreatureSkillFundWnd] 스킬 ID가 유효하지 않습니다. - 스킬트리 ID [ %d ]", pSkillTree->skill_tree_id ); assert( NULL ); return; } SkillBaseEx* skillData( GetSkillDB().GetSkillData( nSkillID ) ); if( skillData == NULL ) { SDEBUGLOG( "[SUICreatureSkillFundWnd] 스킬 데이터를 얻어 올 수 없습니다. - 스킬트리 ID [ %d ]", pSkillTree->skill_tree_id ); assert( NULL ); return; } // 존재하지 않는 스킬이라면 // 필요스킬 1, 2, 3 이 이미 있고 // 필요스킬[0] 이 필요 없는 경우 는 무조건 저장 bool bPrecedentSkillSatisfied = false; if( m_CreatureSkillSlotMgr.GetBaseSkillLevel( nSkillID, m_CreatureSlotMgr.GetSelectedCreature() ) >= ( pSkillTree->min_skill_lv - 1 ) && IsPrecedentSkillSatisfied( *pSkillTree ) ) // sonador 7.0.30 크리처 스킬 습득 프로세스 오류 수정 { bPrecedentSkillSatisfied = true; } // 스킬 아이콘 ============= KUIControlIconStatic* pSkillIcon = dynamicCast(GetChild(CStringUtil::StringFormat( "creature_skillfund_icon%02d", nIndex ).c_str() )); if( pSkillIcon && bShow ) { pSkillIcon->SetIcon( c_szDEF_SPR_NAME, skillData->icon_file_name ); if( bPrecedentSkillSatisfied ) { pSkillIcon->SetIcon( c_szDEF_SPR_NAME, skillData->icon_file_name ); pSkillIcon->SetIconColor( g_enabledSkillIconColor ); } else { pSkillIcon->SetIconColor( g_disabledSkillIconColor ); } } // 스킬 레벨 표시 ============= int nSkillLevel( NULL ); if( m_CreatureSkillSlotMgr.IsExistSkill( nSkillID, m_CreatureSlotMgr.GetSelectedCreature() ) ) { // 스킬이 있는 경우 보유스킬레벨 + 1 과 max 중 큰것 nSkillLevel = max( m_CreatureSkillSlotMgr.GetBaseSkillLevel( nSkillID, m_CreatureSlotMgr.GetSelectedCreature() ) + 1, pSkillTree->min_skill_lv ); } else { // 스킬이 없는 경우 min nSkillLevel = pSkillTree->min_skill_lv; } if( pSkillIcon && bShow ) { // sonador 1.2.5 Lazy Tooltip 구현 // sonador #2.1.2.4.3 팻 조작 UI 연동 pSkillIcon->SetLazyTooltip( new KLazyCreatureSkillFundTooltip( *m_pDisplayInfo, pSkillTree, bPrecedentSkillSatisfied, IsActiveTab(), nSkillID, nSkillLevel, true ) ); } // 필요 MP ============= SetChildCaption( CStringUtil::StringFormat( "static_use_mp_value%02d", nIndex ).c_str(), CStringUtil::StringFormat( "%s%d", S(6425), skillData->GetCostMP(nSkillLevel) ).c_str() ); // 필요 JP ============= SetChildShow( CStringUtil::StringFormat( "creature_skillfund_jp%02d", nIndex ).c_str(), bPrecedentSkillSatisfied ); SetChildCaption( CStringUtil::StringFormat( "creature_skillfund_jp%02d", nIndex ).c_str(), CStringUtil::StringFormat( "%s%d", S(6425), skillData->GetNeedJopPoint(nSkillLevel) ).c_str() ); // 스킬 설명 =========== if( bPrecedentSkillSatisfied ) { SetChildCaption( CStringUtil::StringFormat( "creature_skillfund_01info%02d_value", nIndex ).c_str(), CStringUtil::StringFormat( "%s%d", S(6425), nSkillLevel ).c_str() ); SetChildCaption( CStringUtil::StringFormat( "creature_skillfund_02info%02d", nIndex ).c_str(), GetStringDB().GetString( skillData->GetNameID() ) ); } else { SetChildCaption( CStringUtil::StringFormat( "creature_skillfund_01info%02d_value", nIndex ).c_str(), CStringUtil::StringFormat( "%s%d", S(6425), nSkillLevel).c_str() ); SetChildCaption( CStringUtil::StringFormat( "creature_skillfund_02info%02d", nIndex ).c_str(), CStringUtil::StringFormat( "<#ff0000>%s", GetStringDB().GetString( skillData->GetNameID() ) ).c_str() ); } // 내 jp 가 필요 jp 보다 많으면 업버튼 활성화 KUIControlButton* pFundButton = dynamicCast(GetChild(CStringUtil::StringFormat( "creature_skillfund_up%02d", nIndex ).c_str() )); if( pFundButton ) { const SCreatureInfo* pInfo = m_CreatureSlotMgr.GetCreatureInfo( m_CreatureSlotMgr.GetSelectedCreature() ); if( pInfo == NULL ) return; if( pInfo->GetJP() >= skillData->GetNeedJopPoint( nSkillLevel ) && bPrecedentSkillSatisfied ) pFundButton->Enable(); else pFundButton->Disable(); } } //----------------------------------------------------------------------------------------------------------------- // 스킬 슬롯 비 활성화 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::DisableSlot( int nMode, bool bShow ) { KUIControlIconStatic* pIcon = dynamicCast(GetChild( CStringUtil::StringFormat( "creature_skillfund_icon%02d", nMode ).c_str() )); if( pIcon ) { pIcon->SetIcon( c_szDEF_SPR_NAME, "static_common_itemslot" ); pIcon->SetIconColor( g_enabledSkillIconColor ); pIcon->SetLazyTooltip(); pIcon->SetShow(true); } SetChildShow( CStringUtil::StringFormat( "creature_skillfund_up%02d" , nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "creature_skillfund_01info%02d" , nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "creature_skillfund_01info%02d_value", nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "static_use_jp%02d" , nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "creature_skillfund_02info%02d" , nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "creature_skillfund_jp%02d" , nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "static_use_mp%02d" , nMode ).c_str(), bShow); SetChildShow( CStringUtil::StringFormat( "static_use_mp_value%02d" , nMode ).c_str(), bShow); } //----------------------------------------------------------------------------------------------------------------- // 모든 스킬 슬롯 비 활성화 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::DisableAllSlot( bool bShow ) { for( int index = 0; index < m_nMaxLine; index++ ) { DisableSlot( index, bShow ); } } //----------------------------------------------------------------------------------------------------------------- // 스크롤 바 갱신 //----------------------------------------------------------------------------------------------------------------- void SUICreatureSkillFundWnd::RefreshScrollbar( int nGrade ) { vector* pActiveSkillTreeList( NULL ); GetSkillList( nGrade, !IsActiveTab(), pActiveSkillTreeList ); if( !pActiveSkillTreeList ) return; int nCurCount( pActiveSkillTreeList->size() ); int nScrollRange( max(nCurCount - m_nMaxLine, 0) ); KUIControlVScroll* pScrollBar( dynamicCast(GetChild( "creature_skillfund_scroll" )) ); if( NULL != pScrollBar ) { pScrollBar->SetMaxRange( DWORD(nScrollRange)+1 ); m_nScrollPos = pScrollBar->GetPosition(); } } ///////////////////////////////////////////// // 스킬투자 스킬업 ///////////////////////////////////////////// void SUICreatureSkillFundWnd::SkillUP( int nIndex, int nGrade ) { if( !IsSkill(m_nScrollPos+nIndex, nGrade) ) return; int nSkillID( -1 ); int nOriginSkillID( -1 ); int nSkillLv( -1 ); if( GetLearnableSkillIDnLv( nSkillID, nOriginSkillID, nSkillLv, m_nScrollPos + nIndex, nGrade ) ) { SIMSG_UI_ACT_LEARN_SKILL msg; msg.handle = m_CreatureSlotMgr.GetSelectedCreature(); msg.nSkillID = nSkillID; msg.nOriginSkillID = nOriginSkillID; msg.nSkillLv = nSkillLv; m_pGameManager->ProcMsgAtStatic(&msg); } } ///////////////////////////////////////////// // 스킬투자 선택바 ///////////////////////////////////////////// void SUICreatureSkillFundWnd::ShowSelectBar( int nIndex, int nGrade ) { HideSelectBar(); if( IsSkill(m_nScrollPos+nIndex, nGrade) ) { // 아이콘 선택 보이기 KUIWnd* pIcon = GetChild( CStringUtil::StringFormat( "creature_skillfund_icon%02d", nIndex ).c_str() ); if( pIcon ) { KUIWnd* pSelect = GetChild( "static_select_over" ); KUIWnd* pBGWnd = GetChild( "static_select_over_back" ); KUIWnd* pIconOverWnd = GetChild( "icon_select_over" ); if( pSelect ) { pSelect->MovePos( pIcon->GetRect().left-39, pIcon->GetRect().top-c_nIconSelectDelta ); pSelect->SetShow(true); } if( pBGWnd ) { pBGWnd->MovePos( pIcon->GetRect().left-39 , pIcon->GetRect().top-c_nIconSelectDelta ); pBGWnd->SetShow(true); } if( pIconOverWnd ) { pIconOverWnd->MovePos( pIcon->GetRect().left, pIcon->GetRect().top ); pIconOverWnd->SetShow(true); } } } } void SUICreatureSkillFundWnd::HideSelectBar() { KUIWnd* pWnd = NULL; // 아이콘 선택 감추기 pWnd = GetChild( "static_select_over" ); if( pWnd ) pWnd->SetShow(false); pWnd = GetChild( "static_select_over_back" ); if( pWnd ) pWnd->SetShow(false); pWnd = GetChild( "icon_select_over" ); if( pWnd ) pWnd->SetShow(false); } ///////////////////////////////////////////////////// // 탭 ///////////////////////////////////////////////////// bool SUICreatureSkillFundWnd::IsActiveTab() const { return ( m_nTabType == TAB_ACTIVE ); } void SUICreatureSkillFundWnd::SelectTab() { KUISimpleTabControl* pTab = dynamicCast(GetChild(c_szTAB)); if( pTab == NULL ) return; m_nTabType = pTab->GetSelectedItem(); pTab = dynamicCast(GetChild("creature_skillfund_tab2")); if( pTab == NULL ) return; m_nGrade = pTab->GetSelectedItem(); RefreshScrollbar( m_nGrade ); RefreshSkillSlot( m_nGrade, m_nScrollPos ); } // { [sonador][7.3.10]스크롤 바 오류 수정 void SUICreatureSkillFundWnd::InitScrollPosition() { KUIControlVScroll* pScrollBar = dynamicCast(GetChild( "creature_skillfund_scroll" )); if( NULL != pScrollBar ) { pScrollBar->SetPosition( 0 ); m_nScrollPos = pScrollBar->GetPosition(); } } // } void SUICreatureSkillFundWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd ) { SUIWnd::OnNotifyUIWindowOpen(bOpen); if( bOpen ) { KUIWnd *pInfoWnd = m_pManager->FindWnd( "window_summon_skill" ); if( pInfoWnd ) MovePos( pInfoWnd->GetRect().right, pInfoWnd->GetRect().bottom - GetRect().GetHeight() ); RefreshSkillInfo(); RefreshScrollbar( m_nGrade ); RefreshSkillSlot( m_nGrade, m_nScrollPos ); } } void SUICreatureSkillFundWnd::UpdateTab( int nCnt ) { KUISimpleTabControl* pTabControl = dynamicCast(GetChild("creature_skillfund_tab2")); if( pTabControl && 0 < nCnt && nCnt <= 3 ) { pTabControl->RemoveTabAllItem(); KRect rt = pTabControl->GetRect(); rt.right = rt.left + ( 80 * (float)nCnt ); pTabControl->SetRect(rt); pTabControl->SetTabProperty( 0, false, nCnt ); if( nCnt > 0 ) pTabControl->AddTabItem( S(35), S(35) ); if( nCnt > 1 ) pTabControl->AddTabItem( S(36), S(36) ); if( nCnt > 2 ) pTabControl->AddTabItem( S(37), S(37) ); pTabControl->SetSelectedItem( m_nGrade ); } }