#include "stdafx.h" #include #include "SStringDB.h" #include "SItemDB.h" #include "SCombineDB.h" #include "SMixCategoryDB.h" //#include "SUIUtil.h" #include "SUIDisplayInfo.h" #include "SUISysMsgDefine.h" #include "SGameManager.h" #include "SGameMessage.h" //#include "SGameMessageUI.h" #include "SInventoryMgr.h" #include "KUIDragAndDrop.h" #include "KUIControlStatic.h" #include "SUIMixWnd.h" #include "SUILazyTooltip.h" #include "SGameSystem.h" extern SGameSystem * g_pCurrentGameSystem; namespace { //---------------------------------------------------------------------------------- // 조합창. // 조합창 슬롯 개수. int c_nCombineSlotCount = 9; const int c_nCombineSlotNameLength = int( ::strlen( "slot_blue_" ) ); const int c_nCombineSlotCountLength = 2; const int c_nCombineItemCountLimit = 65535; // 매매갯수는 65535로 제한한다. ( 패킷에 갯수를 unsigned short을 사용하고 있음. ) const int g_nMaxFormalLine = 6; // 공식 리스트 행 개수. const int nLayer = 8; } bool SUIInvCombineWnd::InitControls( KPoint kPos ) { m_pCtrlFormalResult = GetChild( "text_mix_result_content" ); // 결과출력 static 컨트롤. CStringUtil::GetTextDecoration( m_pCtrlFormalResult->GetCaption(), m_strDecoResult ); // 결과 텍스트 꾸미기 태그. m_nScrollPos = 0; m_pScrollFormal = dynamicCast< KUIControlVScrollSmallEx * >( GetChild("scrollbar_mix") ); // 스크롤. m_pFormalTextControl = dynamicCast< KUIControl * >( GetChild( "text_mix_formula_content" ) ); // 공식출력 static 컨트롤. m_FormalHeight = m_pFormalTextControl->GetRect().GetHeight(); // 공식출력 static 컨트롤 기본 높이. CStringUtil::GetTextDecoration( m_pFormalTextControl->GetCaption(), m_strDecoFormal ); // 공식 텍스트 꾸미기 태그. CStringUtil::GetTextFontName( m_strDecoFormal, m_strFontNameFormal ); // 공식 텍스트 폰트명. m_pCtrlMixState = GetChild( "text_09" ); // 조합 상태. CStringUtil::GetTextDecoration( m_pCtrlMixState->GetCaption(), m_strDecoState ); // 결과 꾸미기 태그. for( int nSlotNum( 0 ); nSlotNum < c_nCombineSlotCount; ++nSlotNum ) { KUIControlMultiIcon* pSlotControl = dynamicCast(GetChild( CStringUtil::StringFormat( "slot_blue_%02d", nSlotNum ).c_str() )); if( NULL != pSlotControl ) pSlotControl->SetIconLayer( nLayer ); } SetCustomMovingRect( GetChild( "titlebar" )->GetRect() ); // 이동 //---------------- // 툴팁 추가. KUIWnd * pControl = NULL; pControl = GetChild( "button_help" ); if( pControl ) dynamicCast< KUIControl * >( pControl )->SetLazyTooltip( new KLazyTip( S( 6872 ) ) ); pControl = GetChild( "button_mixlist" ); if( pControl ) dynamicCast< KUIControl * >( pControl )->SetLazyTooltip( new KLazyTip( S( 9747 ) ) ); return SUIWnd::InitControls( kPos ); } bool SUIInvCombineWnd::InitData( bool bReload ) { RefreshSlots(); return SUIWnd::InitData(bReload); } void SUIInvCombineWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd ) { SUIWnd::OnNotifyUIWindowOpen(bOpen); if( bOpen ) // servantes 2010.12.16 { RemoveAllCombineItems(); m_pManager->SetMouseClickWnd(this); } else { m_pManager->SetMouseClickWnd(NULL); } } void* SUIInvCombineWnd::Perform( KID id, KArg& msg ) { _CID( UI_BEGIN_DRAG ); _CID( UI_SEND_DROP ); _CID( UI_RECV_DROP ); if ( id == id_UI_BEGIN_DRAG ) { KUIBeginDragMessage* pBeginMsg = static_cast( &msg ); const char* szControlID = pBeginMsg->sDragControlID.c_str(); KUIControlMultiIcon* pWndMultiIcon = dynamicCast(GetChild( szControlID )); if( NULL != pWndMultiIcon ) { const KUIControlMultiIcon::ICON_INFO& rIconInfo = pWndMultiIcon->GetIconInfoByLayer(0); AR_HANDLE hItem = GetItemHandle( szControlID ); SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( NULL != pSlot ) { m_pDisplayInfo->SetUIDragInfo( new SUICombineItemDragInfo( hItem ) ); m_pDragAndDropIcon->SetStateIcon( pWndMultiIcon->GetSprName(), rIconInfo.sAniName.c_str(), rIconInfo.nFrameIndex, STATE_NORMAL ); pBeginMsg->pDragAndDropRenderer = m_pDragAndDropIcon; } } return NULL; } else if ( id == id_UI_SEND_DROP ) { KUISendRecvDropMessage* pSendMsg = static_cast( &msg ); SUIDragInfo* pUIDragInfo = m_pDisplayInfo->GetUIDragInfo(); if( NULL != pUIDragInfo && SUIDragInfo::DRAGTYPE_COMBINEITEM == pUIDragInfo->m_type ) { SUICombineItemDragInfo* pCombineDragInfo = (SUICombineItemDragInfo*)pUIDragInfo; //servantes 2010.10.20 SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pCombineDragInfo->m_hItem ); if( !pSlot ) return NULL; count_t nCnt = pSlot->GetItemCount(); if(nCnt > 1) { m_hLeaveItem = pCombineDragInfo->m_hItem; m_sLeaveItemWnd = pSendMsg->sRecvDropParentID; m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, pSlot->GetItemCount(), SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); } else { // 동일한 창이 아닌 곳에 드롭했다면 슬롯을 비운다. if( pSendMsg->sRecvDropParentID != std::string(GetID()) ) RemoveCombineItem( pCombineDragInfo->m_hItem ); } // Drag & Drop 정보 제거 m_pDisplayInfo->SetUIDragInfo(); } return NULL; } else if ( id == id_UI_RECV_DROP ) { KUISendRecvDropMessage* pRecvMsg = static_cast( &msg ); SUIDragInfo* pUIDragInfo = m_pDisplayInfo->GetUIDragInfo(); if( NULL != pUIDragInfo && SUIDragInfo::DRAGTYPE_INVENITEM == pUIDragInfo->m_type ) // 아이템인 경우만 { SUIInvenItemDragInfo* pItemDragInfo = (SUIInvenItemDragInfo*)pUIDragInfo; const char* szDropControlID = pRecvMsg->sRecvDropControlID.c_str(); SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pItemDragInfo->m_hItem ); if( !pSlot ) return NULL; if(pSlot->GetItemCount() > 1) //servantes 2010.10.20 { m_hRecvItem = pItemDragInfo->m_hItem; // 던저 넣을 아이템 핸들을 저장한다 m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, pSlot->GetItemCount(), SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); return NULL; } else { if( AbleAddSlot( COMBINEITEM(pSlot->GetHandle(), pSlot->GetItemCount()) ) == false ) return NULL; //bool bMain = AbleMainSlot( pSlot ); bool bSub = AbleSubSlot( pSlot ); //if( bMain ) //{ // if( m_SourceItem.handle == 0 ) //메인등록 가능하면서 메인에 아무것도 없으면 메인 // AddMainCombineItem( pItemDragInfo->m_hItem, count_t( 1 ) ); // else if( bSub ) //메인 등록 가능하지만 이미 메인이 차있으면서 서브에 등록 가능한 아이템이면 서브 // AddSubCombineItem( pItemDragInfo->m_hItem, count_t( 1 ) ); // else AddMainCombineItem( pItemDragInfo->m_hItem, count_t( 1 ) ); //메인만 등록이 가능하지만 메인에 이미 아템 있으니 바꿈 //} //else if( bSub ) { AddSubCombineItem( pItemDragInfo->m_hItem, count_t( 1 ) ); m_pGameManager->StartSound( m_pDisplayInfo->GetMaterialSound( GetItemDB().GetMaterial(pSlot->GetItemCode()) ) ); } } } return NULL; } return SUIWnd::Perform( id, msg ); } void SUIInvCombineWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam ) { switch( nMessage ) { // Scroll case KUI_MESSAGE::KSCROLL_SELECT : m_nScrollPos = max( (int)lparam, 0 ); //RefreshFormal(); // 공식출력. SetTextList( g_nMaxFormalLine, m_strFormal, m_strDecoFormal, const_cast< char * >( m_strFontNameFormal.c_str() ), m_pFormalTextControl, m_pScrollFormal, m_nScrollPos, m_vLineList ); break; case KUI_MESSAGE::KBUTTON_CLICK: { // 공식리스트윈도우 열기. if( !::_stricmp( lpszControlID, "button_mixlist" ) ) { // 분류( 조합, 강화 ) 값을 보내야한다. m_pGameManager->PostMsgAtDynamic( new SIMSG_SYNTHETIC_ID( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_FORMULA, SMixCategoryDB::SYNTHETIC_TYPE::SYNTHETIC_TYPE_MIX ) ); m_pGameManager->PostMsgAtDynamic( new SIMSG_TOGGLE_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_FORMULA ) ); } // 닫기. else if( ::_stricmp( lpszControlID, "button_close" ) == 0 ) { m_CombineItemsVector.clear(); m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, false ) ); } /*else if( ::_stricmp( lpszControlID, "button_cancel" ) == 0 ) { RemoveAllCombineItems(); }*/ // 조합. else if( ::_stricmp( lpszControlID, "button_mix" ) == 0 ) { m_pGameManager->StartSound( "ui_click_compound01.wav" ); //if( NULL != m_SourceItem.handle || 0 < m_CombineItemsVector.size() ) //{ // 아이템합성 시작 전달. m_pGameManager->PostMsgAtDynamic( new SIMSG_SYNTHETIC_ITEM( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MIX_PROGRESS, SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE ) ); // 아이템합성 진행률 출력 윈도우 열기. m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MIX_PROGRESS, true, true ) ); //} } // 도움말윈도우. else if( ::_stricmp( lpszControlID, "button_help" ) == 0 ) { const KRect & rt = GetChild( "button_help" )->GetRect(); m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_HELP_WND, false ) ); // 닫기. m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_MOVE( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_HELP_WND, rt.left, rt.top ) ); // 위치전달. m_pGameManager->PostMsgAtDynamic( new SIMSG_HELP_TEXT( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_HELP_WND, std::string( S( 9762 ) ) ) ); // 텍스트전달. m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_HELP_WND, true ) ); // 열기. } } break; case KUI_MESSAGE::KGENWND_MOVE: { LimitMoveWnd(); } break; case KUI_MESSAGE::KICON_PRESSING: //servantes 2010.10.19 { if(m_bShiftKey) { AR_HANDLE hHandle = GetItemHandle( lpszControlID ); if(hHandle == NULL) break; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hHandle ); if(pSlot == NULL) break; count_t nCnt = pSlot->GetItemCount(); if(nCnt > 1 && GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable(pSlot) )) // 여러개가 있을 경우 { m_CombineItemHandel = hHandle; m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, pSlot->GetItemCount(), SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); SetMoveItemToInventoryFlag( true ); } else // 한 개일 경우 { m_CombineItemHandel = hHandle; m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, count_t(1) ) ); // 1개를 옮긴다 SetMoveItemToInventoryFlag( true ); } } if(m_bControlKey) { AR_HANDLE hHandle = GetItemHandle( lpszControlID ); if(hHandle == NULL) break; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hHandle ); if(pSlot == NULL) break; count_t nCnt = pSlot->GetItemCount(); if(nCnt > 1 && GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable(pSlot) )) // 아이템이 1개이상 있다면 { m_CombineItemHandel = hHandle; m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, count_t(1) ) ); // 1개를 옮긴다 SetMoveItemToInventoryFlag( true ); } } } break; case KUI_MESSAGE::KICON_DBLCLK: { AR_HANDLE hHandle = GetItemHandle( lpszControlID ); if(hHandle == NULL) break; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hHandle ); if(pSlot == NULL) break; count_t nCnt = pSlot->GetItemCount(); if(nCnt > 1 && GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable(pSlot) )) // 여러개가 있을 경우 { m_CombineItemHandel = hHandle; count_t nCount(0); int nSize = m_CombineItemsVector.size(); for(int k=0; kPostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, pSlot->GetItemCount(), SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, nCount, SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); SetMoveItemToInventoryFlag( true ); } else // 한 개일 경우 { m_CombineItemHandel = hHandle; m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, count_t(1) ) ); // 1개를 옮긴다 SetMoveItemToInventoryFlag( true ); } } break; } SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam ); } void SUIInvCombineWnd::ProcMsgAtStatic( SGameMessage* pMsg ) { switch( pMsg->nType ) { case MSG_UPDATE_ITEM_COUNT: case MSG_ITEM_DESTROY: case MSG_ITEM_INVEN: case MSG_ITEM_WEAR_INFO: { bool bRemoved = false; //// 원본 아이템이 사라졌거나 장착된 경우 제거한다. //// 조합창과 관련 없는 아이템이 장비 탈착시 조합창의 Main 슬롯을 제거하지 않는다. - 2009.08.24 sfreer //bool bMainRemoved = false; //if( pMsg->nType != MSG_ITEM_WEAR_INFO && NULL != m_SourceItem.handle ) // bMainRemoved = true; //if( pMsg->nType == MSG_ITEM_WEAR_INFO && NULL != m_SourceItem.handle ) //{ // if( ((SMSG_ITEM_WEAR_INFO *)(pMsg))->item_handle == m_SourceItem.handle ) // { // bMainRemoved = true; // } //} //if(bMainRemoved) //{ // SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( m_SourceItem.handle ); // if( pSlot == NULL || !pSlot->IsEquipItem() ) // { // m_SourceItem = COMBINEITEM(); // bRemoved = true; // } //} COMBINEITEM_VECTOR::iterator itItem = m_CombineItemsVector.begin(); while( itItem != m_CombineItemsVector.end() ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( (*itItem).handle ); if( pSlot && !pSlot->IsEquipItem() ) { // 조합창에 올려놓은 양보다 실제 인벤아이템의 양이 줄어있는 경우 if( (*itItem).usiCount > pSlot->GetItemCount() ) (*itItem).usiCount = pSlot->GetItemCount(); // 존재하고 장착하지 않은 것은 그대로 유지 itItem++; } else { // 없어졌거나 장착된 아이템은 제거한다. itItem = m_CombineItemsVector.erase( itItem ); bRemoved = true; } } if( bRemoved ) RefreshSlots(); } break; case MSG_MIX_RESULT: { if( this->IsShow() ) { RemoveAllCombineItems( false ); SMSG_MIX_RESULT* pMixResultMsg = (SMSG_MIX_RESULT*)pMsg; //KUIWnd * pWnd = GetChild( "text_09" ); if( m_pCtrlMixState ) { std::string strDeco( m_strDecoState ); // 조합 성공. if( pMixResultMsg->count > 0 ) { const char * pStr = S( 9722 ); strDeco.append( pStr ); m_pCtrlMixState->SetCaption( strDeco.c_str() ); m_pDisplayInfo->AddSystemMessage( pStr, 0 ); // 채팅창에 출력. } // 조합 실패. else { const char * pStr = S( 9723 ); strDeco.append( pStr ); m_pCtrlMixState->SetCaption( strDeco.c_str() ); m_pDisplayInfo->AddSystemMessage( pStr, 0 ); // 채팅창에 출력. } } //if( 0 < pMixResultMsg->count ) //{ // for( int n( 0 ); n < int(pMixResultMsg->count); ++n ) // { // SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pMixResultMsg->pArHandle[n] ); // if( pSlot ) // { // // 장착용 아이템인 경우 원본 아이템으로 // if( NULL == m_SourceItem.handle && ItemBase::TYPE_ARMOR == GetItemDB().GetUseType( pSlot->GetItemCode() ) ) // m_SourceItem = COMBINEITEM( pSlot->GetHandle() ); // } // } // RefreshSlots(); //} //else //{ // RefreshSlots(); //} RefreshSlots(); pMsg->bUse = true; } } break; case MSG_RESULT: { SMSG_RESULT* pResultMsg = (SMSG_RESULT*)pMsg; if( TM_CS_MIX == pResultMsg->request_msg_id ) { RemoveAllCombineItems(); } } break; case IMSG_UI_MOVE: { SIMSG_UI_MOVE* pMoveMsg = (SIMSG_UI_MOVE*)pMsg; //MovePos( pMoveMsg->m_nX - GetRect().GetWidth(), pMoveMsg->m_nY - GetRect().GetHeight() ); MovePos( pMoveMsg->m_nX, pMoveMsg->m_nY ); pMsg->bUse = true; } break; case IMSG_UI_INPUTNUMBER: { SIMSG_UI_INPUTNUMBER* pInputNumberMsg = (SIMSG_UI_INPUTNUMBER*)pMsg; if( pInputNumberMsg->m_nValue > 0 ) { if(m_CombineItemHandel != 0) { AR_HANDLE hItem = m_CombineItemHandel; count_t usiCount = pInputNumberMsg->m_nValue; m_CombineItemHandel = 0; if(m_bMoveItemToInventory) //servantes 2010.10.19 { if(m_bControlKey) { COMBINEITEM_VECTOR::iterator itItem = GetItemIterator( hItem ); if (m_CombineItemsVector.end() != itItem) /// 2011.07.25 redmine #18785 조건 체크 - prodongi { count_t tC = itItem->usiCount; tC -= pInputNumberMsg->m_nValue; if(tC <= 0) { RemoveCombineItem(hItem); } else { itItem->usiCount -= count_t(1); RefreshSlots(); } } } else { if( pInputNumberMsg->m_nValue > 1 ) { COMBINEITEM_VECTOR::iterator itItem = GetItemIterator( hItem ); if (m_CombineItemsVector.end() != itItem) /// 2011.07.25 redmine #18785 조건 체크 - prodongi { count_t tC = itItem->usiCount; tC -= pInputNumberMsg->m_nValue; if(tC <= 0) { RemoveCombineItem(hItem); } else { itItem->usiCount -= pInputNumberMsg->m_nValue; RefreshSlots(); } } } else { RemoveCombineItem(hItem); } } SetMoveItemToInventoryFlag( false ); } else { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( !pSlot ) break; if( AbleAddSlot( COMBINEITEM(pSlot->GetHandle(), pSlot->GetItemCount()) ) == false ) break; if(usiCount > pSlot->GetItemCount()) //servantes 2010.12.20 usiCount = pSlot->GetItemCount(); bool bSub = AbleSubSlot( pSlot ); if( bSub ) { AddSubCombineItem( hItem, usiCount ); m_pGameManager->StartSound( m_pDisplayInfo->GetMaterialSound( GetItemDB().GetMaterial(pSlot->GetItemCode()) ) ); } } } if(m_hRecvItem) //servantes 2010.10.19 { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( m_hRecvItem ); if( !pSlot ) break; if( AbleAddSlot( COMBINEITEM(pSlot->GetHandle(), pInputNumberMsg->m_nValue) ) == false ) break; bool bSub = AbleSubSlot( pSlot ); if( bSub ) { AddSubCombineItem( m_hRecvItem, pInputNumberMsg->m_nValue ); m_pGameManager->StartSound( m_pDisplayInfo->GetMaterialSound( GetItemDB().GetMaterial(pSlot->GetItemCode()) ) ); } m_hRecvItem = 0; } } if(m_hLeaveItem) //servantes 2010.10.19 { if( m_sLeaveItemWnd != std::string(GetID()) ) { COMBINEITEM_VECTOR::iterator itItem = GetItemIterator( m_hLeaveItem ); if (m_CombineItemsVector.end() != itItem) /// 2011.07.25 redmine #18785 조건 체크 - prodongi { count_t tC = itItem->usiCount; tC -= pInputNumberMsg->m_nValue; if(tC <= 0) { RemoveCombineItem(m_hLeaveItem); } else { itItem->usiCount -= pInputNumberMsg->m_nValue; RefreshSlots(); } } } m_hLeaveItem = 0; } pMsg->bUse = true; } break; case IMSG_SET_COMBINEITEM: { SIMSG_SET_COMBINEITEM * pCombineItemMsg = (SIMSG_SET_COMBINEITEM*)pMsg; AR_HANDLE hItem = pCombineItemMsg->hItem; count_t usiCount = pCombineItemMsg->usiCount; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( pSlot && AbleAddSlot( COMBINEITEM(pSlot->GetHandle(), pSlot->GetItemCount()) ) ) { //bool bMain = AbleMainSlot( pSlot ); bool bSub = AbleSubSlot( pSlot ); bool bAddMain = true; if(usiCount.getAmount() < 0) { m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, pSlot->GetItemCount() ) ); m_CombineItemHandel = hItem; } else if(bSub) { if(usiCount == 1) //servantes 2010.10.19 { AddSubCombineItem( hItem, usiCount ); m_pGameManager->StartSound( m_pDisplayInfo->GetMaterialSound( GetItemDB().GetMaterial(pSlot->GetItemCode()) ) ); } else if(usiCount > 10) { // 2011.07.25 - servantes m_CombineItemHandel = hItem; // 2011.07.25 - servantes : redmine 18784 - 강화 조합 등의 재료 넣는 곳에서 더블 클릭 문제 m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, usiCount, SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); } else { if(pCombineItemMsg->bMove10 && usiCount == 10) { AddSubCombineItem( hItem, usiCount ); m_pGameManager->StartSound( m_pDisplayInfo->GetMaterialSound( GetItemDB().GetMaterial(pSlot->GetItemCode()) ) ); break; } m_CombineItemHandel = hItem; m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, usiCount, SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); } } else __noop; } pMsg->bUse = true; } break; // 공식리스트에서 공식 텍스트 ID 전달. case IMSG_FORMAL_ID: { pMsg->bUse = true; SIMSG_FORMAL_ID * pData = dynamicCast< SIMSG_FORMAL_ID * >( pMsg ); m_strFormal = S( pData->formal_id ); // 공식. if( m_strFormal != "0" ) { std::string strResult( m_strDecoResult ); strResult.append( S( pData->result_id ) ); m_pCtrlFormalResult->SetCaption( strResult.c_str() ); // 결과. m_nScrollPos = 0; //RefreshFormal(); // 공식출력. m_vLineList.clear(); SetTextList( g_nMaxFormalLine, m_strFormal, m_strDecoFormal, const_cast< char * >( m_strFontNameFormal.c_str() ), m_pFormalTextControl, m_pScrollFormal, m_nScrollPos, m_vLineList, true ); } } break; // 아이템합성 진행률출력 윈도우에서 진행완료 전달. case IMSG_SYNTHETIC_ITEM: { pMsg->bUse = true; int size = m_CombineItemsVector.size(); if( size < 1 ) { /// 2011.05.16 ProcMsgAtStatic는 정적 입력 변수이다 - prodongi //m_pGameManager->ProcMsgAtStatic( new SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::_MSGBOXID::MSGBOX_GENERAL, S( 2502 ), true ) ); m_pGameManager->ProcMsgAtStatic( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::_MSGBOXID::MSGBOX_GENERAL, S( 2502 ), true ) ); } else { SIMSG_UI_ACT_ITEMCOMBINE combineMsg; // 원본 아이템 추가 bool bSucceed = true; // 강화 아이템 추가 bool bAllEquipment = true; int nWearType; AR_HANDLE handle; SInventorySlot * pSlot; for( COMBINEITEM_VECTOR::const_iterator itItem = m_CombineItemsVector.begin(); itItem != m_CombineItemsVector.end(); itItem++ ) { handle = (*itItem).handle; // 모든슬롯의 아이템이 장비인 경우 에는 조합요청 하지않는다. ( 에테리얼스톤 충전을 막기위함 ). pSlot = m_InventoryMgr.GetItemInfo( handle ); if( pSlot ) { nWearType = GetItemDB().GetWearType( pSlot->GetItemCode() ); if( nWearType == ItemBase::WEAR_CANTWEAR || nWearType == ItemBase::WEAR_STORAGE || ( nWearType < ItemBase::WEAR_WEAPON || nWearType > ItemBase::WEAR_FACE ) && !ItemBase::WEAR_TWOHAND ) bAllEquipment = false; } if( m_InventoryMgr.IsExistItem( handle ) ) combineMsg.vtItems.push_back( SIMSG_UI_ACT_ITEMCOMBINE::CombineItemInfo( handle, (*itItem).usiCount.getAmount() ) ); else { bSucceed = false; break; } /*if( m_InventoryMgr.IsExistItem( (*itItem).handle ) ) combineMsg.vtItems.push_back( SIMSG_UI_ACT_ITEMCOMBINE::CombineItemInfo( (*itItem).handle, (*itItem).usiCount.getAmount() ) ); else { bSucceed = false; break; }*/ } // 모든슬롯의 아이템이 장비인 경우 에는 조합요청 하지않는다. ( 에테리얼스톤 충전을 막기위함 ). if( bAllEquipment ) bSucceed = false; // 슬롯제거. RemoveAllCombineItems(); // 조합!. if( bSucceed ) { m_pGameManager->ProcMsgAtStatic( &combineMsg ); } } } break; case IMSG_HOTKEY_EX: //servantes 2010.10.19 { SIMSG_HOTKEY_EX* pHotKey = dynamicCast(pMsg); if( pHotKey->wParam == VK_SHIFT ) m_bShiftKey = (pHotKey->bUp == 0); //servantes 2010.10.15 if( pHotKey->wParam == VK_CONTROL ) //servantes 2010.10.15 m_bControlKey = (pHotKey->bUp == 0); if( pHotKey->wParam == VK_MENU ) { bool bPreState = m_bAltKey; m_bAltKey = (pHotKey->bUp == 0); if( bPreState != m_bAltKey && IsShow() ) { RefreshSlots(); } } } break; } } AR_HANDLE SUIInvCombineWnd::GetItemHandle( const char* szControlID ) const { //// 원본 아이템 //if( 0 == ::_stricmp( szControlID, "icon_itemsrc" ) ) // return m_SourceItem.handle; // 강화 아이템 if( 0 == ::strnicmp( szControlID, "slot_blue_", c_nCombineSlotNameLength ) ) { if( ::strlen( szControlID ) >= (c_nCombineSlotNameLength + c_nCombineSlotCountLength) ) { std::string strSlotNum; strSlotNum.assign( szControlID, c_nCombineSlotNameLength, c_nCombineSlotCountLength ); int nSlotNum = ::atoi( strSlotNum.c_str() ); if( 0 <= nSlotNum && nSlotNum < int(m_CombineItemsVector.size()) ) return m_CombineItemsVector[ nSlotNum ].handle; } } return NULL; } SUIInvCombineWnd::COMBINEITEM_VECTOR::iterator SUIInvCombineWnd::GetItemIterator( AR_HANDLE hItem ) { if(m_CombineItemsVector.size() <=0 ) //servantes 2010.10.19 return m_CombineItemsVector.end(); for( COMBINEITEM_VECTOR::iterator itItem = m_CombineItemsVector.begin(); itItem != m_CombineItemsVector.end(); itItem++ ) if( (*itItem).handle == hItem ) return itItem; return m_CombineItemsVector.end(); } bool SUIInvCombineWnd::IsEquipItem( SInventorySlot* pSlot, count_t usiCount ) { if( !pSlot ) return false; bool bEquip = false; if( GetItemDB().GetUseType(pSlot->GetItemCode()) == ItemBase::TYPE_CARD ) bEquip = m_InventoryMgr.IsEquipCard( pSlot->GetHandle() ); else bEquip = pSlot->IsEquipItem(); return bEquip; } void SUIInvCombineWnd::AddMainCombineItem( AR_HANDLE hItem, count_t usiCount ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( !pSlot ) return; // 장착중인 아이템은 제외. if( IsEquipItem( pSlot, usiCount ) ) return; m_SourceItem = COMBINEITEM( hItem ); RefreshSlots(); } void SUIInvCombineWnd::AddSubCombineItem( AR_HANDLE hItem, count_t usiCount ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( !pSlot ) return; // 장착중인 아이템 제외. if( IsEquipItem( pSlot, usiCount ) ) return; /// 2011.07.25 최대 개수 체크 - prodongi if(usiCount > pSlot->GetItemCount()) usiCount = pSlot->GetItemCount(); COMBINEITEM_VECTOR::iterator itItem = GetItemIterator( hItem ); if( m_CombineItemsVector.end() != itItem ) // 이미 존재하는 경우 { // 중첩 가능한 아이템인 경우 if( GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable( pSlot ) ) ) { // 기존 아이템의 갯수를 증가시킨다. count_t nTotalCount = (*itItem).usiCount + usiCount; if( nTotalCount > pSlot->GetItemCount() ) nTotalCount = pSlot->GetItemCount(); // 갖고있는 아이템의 전체 갯수보다 커지지 않도록 조정 if( nTotalCount > c_nCombineItemCountLimit ) nTotalCount = count_t( c_nCombineItemCountLimit ); if( (*itItem).usiCount != nTotalCount ) { (*itItem).usiCount = nTotalCount; RefreshSlots(); } } } else // 처음 추가하는 경우 { if(m_CombineItemsVector.size() < c_nCombineSlotCount) { m_CombineItemsVector.push_back( COMBINEITEM( hItem, usiCount ) ); } RefreshSlots(); } RefreshSlots(); } void SUIInvCombineWnd::AddCombineItem( AR_HANDLE hItem, count_t usiCount ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if (!pSlot) return ; bool bEquip = false; if( GetItemDB().GetUseType(pSlot->GetItemCode()) == ItemBase::TYPE_CARD ) bEquip = m_InventoryMgr.IsEquipCard( pSlot->GetHandle() ); else bEquip = pSlot->IsEquipItem(); if( pSlot && !bEquip ) // 장착된 아이템은 배제 { if( m_SourceItem.handle == 0 ) m_SourceItem = COMBINEITEM( hItem ); else { COMBINEITEM_VECTOR::iterator itItem = GetItemIterator( hItem ); if( m_CombineItemsVector.end() != itItem ) // 이미 존재하는 경우 { // 중첩 가능한 아이템인 경우 if( GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable(pSlot) ) ) { // 기존 아이템의 갯수를 증가시킨다. count_t nTotalCount = (*itItem).usiCount + usiCount; if( nTotalCount > pSlot->GetItemCount() ) nTotalCount = pSlot->GetItemCount(); // 갖고있는 아이템의 전체 갯수보다 커지지 않도록 조정 if( nTotalCount > c_nCombineItemCountLimit ) nTotalCount = count_t( c_nCombineItemCountLimit ); if( (*itItem).usiCount != nTotalCount ) { (*itItem).usiCount = nTotalCount; RefreshSlots(); } } } else // 처음 추가하는 경우 { if(m_CombineItemsVector.size() < c_nCombineSlotCount) { m_CombineItemsVector.push_back( COMBINEITEM( hItem, usiCount ) ); } RefreshSlots(); } } } else { m_pDisplayInfo->AddSystemMessage( S(292), 99 ); // Enable after releasing equipment } } bool SUIInvCombineWnd::AbleAddSlot( COMBINEITEM Item ) { if( Item.handle == m_SourceItem.handle && Item.usiCount == m_SourceItem.usiCount ) return false; for( COMBINEITEM_VECTOR::iterator itItem = m_CombineItemsVector.begin(); itItem != m_CombineItemsVector.end(); itItem++ ) { int nHandle = int((*itItem).handle); count_t nCount = (*itItem).usiCount; if( Item.handle == nHandle && Item.usiCount == nCount ) return false; } return true; } bool SUIInvCombineWnd::AbleMainSlot( SInventorySlot* pSlot ) { int nBigGroup = GetItemDB().GetGroup( pSlot->GetItemCode() ); int nGroup = GetItemDB().GetClassID( pSlot->GetItemCode() ); int nID = pSlot->GetItemCode(); int nRank = GetItemDB().GetItemRank( pSlot->GetItemCode() ); int nLv = pSlot->GetLevel(); const XFlag xFlag = pSlot->GetXFlag(); int nEnhance = pSlot->GetEnhance(); int nItemCount = pSlot->GetItemCount().getAmount(); return GetCombineDB().IsMain( nBigGroup, nGroup, nID, nRank, nLv, xFlag, nEnhance, nItemCount ); } bool SUIInvCombineWnd::AbleSubSlot( SInventorySlot* pSlot ) { int nBigGroup = GetItemDB().GetGroup( pSlot->GetItemCode() ); int nGroup = GetItemDB().GetClassID( pSlot->GetItemCode() ); int nID = pSlot->GetItemCode(); int nRank = GetItemDB().GetItemRank( pSlot->GetItemCode() ); int nLv = pSlot->GetLevel(); const XFlag xFlag = pSlot->GetXFlag(); int nEnhance = pSlot->GetEnhance(); int nItemCount = pSlot->GetItemCount().getAmount(); return GetCombineDB().IsSub( nBigGroup, nGroup, nID, nRank, nLv, xFlag, nEnhance, nItemCount ); } void SUIInvCombineWnd::RemoveCombineItem( AR_HANDLE hItem ) { //// 원본 아이템 //if( m_SourceItem.handle == hItem ) //{ // m_SourceItem = COMBINEITEM(); // RefreshSlots(); //} //// 강화 아이템 //else { COMBINEITEM_VECTOR::iterator itItem = GetItemIterator( hItem ); if( m_CombineItemsVector.end() != itItem ) { m_CombineItemsVector.erase( itItem ); RefreshSlots(); } } } void SUIInvCombineWnd::RemoveAllCombineItems( bool bRefreshSlot/* = true*/ ) { //m_SourceItem = COMBINEITEM(); m_CombineItemsVector.clear(); if( bRefreshSlot ) RefreshSlots(); } void SUIInvCombineWnd::RefreshSlots() { //// 원본 아이템 //KUIControlMultiIcon* pSrcSlotControl = (KUIControlMultiIcon*)GetChild( "icon_itemsrc" ); //if( NULL != pSrcSlotControl ) SetItemIconStatic( pSrcSlotControl, NULL, count_t( 0 ), m_InventoryMgr.GetItemInfo( m_SourceItem.handle ) ); if( !m_CombineItemsVector.empty() && m_pCtrlMixState && m_strDecoState != m_pCtrlMixState->GetCaption() ) { m_pCtrlMixState->SetCaption( m_strDecoState.c_str() ); } // 강화 아이템 for( int nSlotNum( 0 ); nSlotNum < c_nCombineSlotCount; ++nSlotNum ) { std::string strIconControlID = CStringUtil::StringFormat( "slot_blue_%02d" , nSlotNum ); std::string strStaticCountID = CStringUtil::StringFormat( "static_itemcount%02d", nSlotNum ); KUIControlMultiIcon* pSlotControl = dynamicCast(GetChild( strIconControlID.c_str() )); KUIWnd* pItemCountControl = GetChild( strStaticCountID.c_str() ); if( nSlotNum < int(m_CombineItemsVector.size()) ) { const COMBINEITEM& rCombineItem = m_CombineItemsVector[ nSlotNum ]; SetItemIconStatic( pSlotControl, pItemCountControl, rCombineItem.usiCount, m_InventoryMgr.GetItemInfo( rCombineItem.handle ) ); } else { SetItemIconStatic( pSlotControl, pItemCountControl ); } } } void SUIInvCombineWnd::SetItemIconStatic( KUIControlMultiIcon* pIconStatic, KUIWnd* pItemCountControl, count_t nCount, SInventorySlot* pSlot/* = NULL*/ ) { if( pSlot ) { if( NULL != pIconStatic ) { /// 2011.08.03 - prodongi if( !setSkillCardIcon(pIconStatic, pSlot->GetItemCode()) && !setSummonCardIcon( pIconStatic, pSlot ) ) { std::string iconName; getIconNameAtDurability(pSlot, iconName); pIconStatic->SetIcon(0, c_szDEF_SPR_NAME, iconName.c_str()); pIconStatic->SetIcon(2); pIconStatic->SetIcon(3); pIconStatic->SetIcon(4); pIconStatic->SetIcon(5); pIconStatic->SetIcon(6); pIconStatic->SetIcon(7); } if( pSlot->GetItemAppearance() ) pIconStatic->SetIcon( 4, c_szDEF_SPR_NAME, g_strLookChangeIcon ); // 2012. 7. 27 - marine 아이템 형상변환 아이콘 pIconStatic->SetIcon( 1, c_szDEF_SPR_NAME, pSlot->GetXFlag().IsOn( ItemInstance::ITEM_FLAG_CARD ) ? "static_common_useunitcardicon" : NULL ); EquipItemAddtionalIconSetter icon_setter( pIconStatic, pSlot ); pIconStatic->SetLazyTooltip( new rp::KLazyItemTooltip( *m_pDisplayInfo, pSlot, true ) ); if( m_bAltKey ) { m_pDisplayInfo->SetComparableEquipItemSubTooltip( pIconStatic, pSlot ); } } if( NULL != pItemCountControl ) { __int64 amount = GetItemDB().IsJoin(pSlot->GetItemCode(),IsInstanceUnstackable(pSlot)) ? nCount.getAmount() : 0; pItemCountControl->SetShow( (amount != 0) ? true : false ); pItemCountControl->SetCaption( CStringUtil::StringFormat( "%s%I64d", S(6425), GetItemDB().IsJoin(pSlot->GetItemCode(),IsInstanceUnstackable(pSlot)) ? nCount.getAmount() : 0 ).c_str() ); } } else { if( NULL != pIconStatic ) { pIconStatic->SetIcon( 0, c_szDEF_SPR_NAME, "common_panel_titanium_slot_icon" ); pIconStatic->SetIcon( 1 ); pIconStatic->SetIcon( 2 ); ////2010.01.19. 아이템내구도처리sfreer pIconStatic->SetIcon( 3 ); pIconStatic->SetIcon( 4 ); pIconStatic->SetIcon(5); pIconStatic->SetIcon(6); pIconStatic->SetIcon(7); pIconStatic->SetTooltip(); } if( NULL != pItemCountControl ) pItemCountControl->SetShow(false); } } // 공식텍스트 출력. void SUIInvCombineWnd::RefreshFormal() { std::string strNewStory; const int MAX_STORY_LINE_COUNT = 6; // 대화내용 넘침 방지 std::vector< std::string > vLineList; //m_pFormalTextControl->SplitLine( vLineList, m_strFormal, S(6425), m_pFormalTextControl->GetFontSize(), false, true ); #ifdef _COUNTRY_ME_ m_pFormalTextControl->SplitLine( vLineList, m_strFormal, KFontManager::KDEFAULT_FONT_NAME, m_pFormalTextControl->GetFontSize() ); strNewStory += ""; #else m_pFormalTextControl->SplitLine( vLineList, m_strFormal, S(6425), m_pFormalTextControl->GetFontSize() ); strNewStory += std::string( S(6313)/*""*/ ); #endif int size = vLineList.size(); if( size > MAX_STORY_LINE_COUNT ) { for( int i = 0; i < size; ++i ) { if( i >= MAX_STORY_LINE_COUNT || size <= m_nScrollPos + i ) break; strNewStory += vLineList[ m_nScrollPos + i ]; strNewStory += "
"; } } else { #ifdef _COUNTRY_ME_ strNewStory += m_strFormal; #else strNewStory = m_strFormal; #endif m_nScrollPos = 0; } vLineList.clear(); // 스크롤바 Thumb 조절. m_pScrollFormal->SetScrollRange( MAX_STORY_LINE_COUNT, size ); // 텍스트 적용. m_pFormalTextControl->SetCaption( strNewStory.c_str() ); }