#include "stdafx.h" #include "KUIWndManager.h" #include "KUIControlStatic.h" #include "KUIControlClockBox.h" #include "SGameManager.h" //#include "SGameMessageUI.h" #include "SUITargetStateWnd.h" #include "SUIDisplayInfo.h" #include "STenacityDB.h" #include "SkillBaseFile.h" #include "SGameOption.h" #include "SPlayerInfoMgr.h" #include "KUIControlQuickEffect.h" #include "SGameAvatarEx.h" #include "KUIWnd.h" #include "SGame.h" #include "SSummonSlotMgr.h" #include "./Target/SUITargetWnd_Player.h" #include "./Target/SUITargetWnd_Creature.h" namespace { enum SHOW_TYPE { SHOW_SHORT = 0, SHOW_MIDDLE, SHOW_LONG, }; const int c_nMaxStateIcon = 36; const int c_nMaxNum = 36; const int c_nIconHeight = 20; /// 2011.01.19 - prodongi const int REITERATION_OFFSET = 5; /// 2011.03.30 오버렙 아이콘의 상태 아이콘에 대한 옵셋값 - prodongi const int MAX_REITERATION_LEVEL = 99; /// 2011.04.01 - prodongi }; bool SUITargetStateWnd::InitControls( KPoint kPos ) { CreateItemIcon(); // 아이콘 생성 KRect rReiteration; /// 2011.03.30 - prodongi KUIWnd* pWnd = NULL; // state 재사용 시간 컨트롤 for( int i = 1; i <= c_nMaxStateIcon; i++ ) { KUIWnd* pIcon = GetChild( CStringUtil::StringFormat("state_effect_h_icon%02d", i).c_str() ); if( pIcon ) { pWnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "clockbox", CStringUtil::StringFormat("state_effect_h_clock%02d", i).c_str(), " ", pIcon->GetRect(), 0, KFLAG_NO_GET_MESSAGE, this, "", c_szDEF_SPR_NAME, m_pManager, 0, "", KANCHOR_LEFT | KANCHOR_TOP ) ); if( pWnd ) ((KUIControlClockBox*)pWnd)->SetColor( c_ColorClockControl ); /// 2011.03.30 중첩 아이콘 생성 - prodongi rReiteration.left = pIcon->GetRect().left + REITERATION_OFFSET; rReiteration.top = pIcon->GetRect().top + REITERATION_OFFSET; rReiteration.right = pIcon->GetRect().right; rReiteration.bottom = pIcon->GetRect().bottom; pWnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "static", CStringUtil::StringFormat("state_effect_h_reiteration%02d", i).c_str(), " ", rReiteration, 0, KFLAG_GET_PASS_MESSAGE, this, "", c_szDEF_SPR_NAME, m_pManager, 0, "", KANCHOR_LEFT | KANCHOR_TOP ) ); if (pWnd) { pWnd->SetShow(false); } } } return SUIWnd::InitControls(kPos); } bool SUITargetStateWnd::InitData( bool bReload ) { m_nShowType = -1; m_nCurNegativePos = 0; DisableSlot( 0, c_nMaxNum, false ); return SUIWnd::InitData(bReload); } void SUITargetStateWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam ) { switch(nMessage) { case KUI_MESSAGE::KBUTTON_CLICK: break; case KUI_MESSAGE::KGENWND_MOVE: // 윈도우 이동 break; } SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam ); } void SUITargetStateWnd::ProcMsgAtStatic( SGameMessage* pMsg ) { switch(pMsg->nType) { case MSG_STATE: { pMsg->bUse = true; } break; case IMSG_UI_STATE_UPDATE: { if( IsSetTarget() ) { CheckState(); if( !IsShow() && IsSlot() ) m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, true ) ); if( IsShow() && !IsSlot() ) m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, false ) ); } pMsg->bUse = true; } break; case IMSG_UI_TARGET_INFO: { SIMSG_UI_TARGET_INFO* pTargetMsg = ( SIMSG_UI_TARGET_INFO* )pMsg; if( pTargetMsg->handle ) { CalcOpenPosition( pTargetMsg->nObjType ); m_pTarget = NULL; //타겟이 바뀔경우 이곳을 들어오니 m_pTarget을 NULL로 초기화하는 것 IsSetTarget(); //갱신 if( IsSlot() ) //-N4- 갱신후 슬롯의 데이터 유무에 따라 구분 { RefreshAllStateInfo(); m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, true ) ); } else m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, false ) ); } else { // 리스트 초기화 하고 닫는다 CloseWnd(); } pMsg->bUse = true; } break; case IMSG_UI_STATE_LIST_UPDATE: { UpdateStateData(pMsg); pMsg->bUse = true; } break; } } void SUITargetStateWnd::CalcOpenPosition( int nObjType ) { if( NULL == m_pGameManager ) return ; if( TS_ENTER::GAME_PLAYER == nObjType ) { SUITargetWnd_Player* pTargetWnd_Player( dynamicCast( m_pGameManager->GetSUI(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_PLAYER) ) ); if( pTargetWnd_Player ) { KRect rtTargetPlayer( pTargetWnd_Player->GetRect() ); KRect rtTargetState( GetRect() ); int nOffset( ( rtTargetPlayer.GetWidth() - rtTargetState.GetWidth() ) / 2 ); MovePos( rtTargetPlayer.left + nOffset, rtTargetPlayer.bottom ); } return ; } if( TS_ENTER::GAME_SUMMON == nObjType || TS_ENTER::GAME_MOB == nObjType || TS_ENTER::GAME_PET == nObjType ) { SUITargetWnd_Creature* pTargetWnd_Creature( dynamicCast( m_pGameManager->GetSUI(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_CREATURE) ) ); if( pTargetWnd_Creature ) { KRect rtTargetCreature( pTargetWnd_Creature->GetRect() ); KRect rtTargetState( GetRect() ); int nOffset( ( rtTargetCreature.GetWidth() - rtTargetState.GetWidth() ) / 2 ); MovePos( rtTargetCreature.left + nOffset, rtTargetCreature.bottom ); } return ; } } void SUITargetStateWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd ) { SUIWnd::OnNotifyUIWindowOpen( bOpen, bLimitWnd ); if( bOpen ) { IsSetTarget(); RefreshAllStateInfo(); } else { m_pTarget = NULL; } } // ========================================= // 윈도우 // ========================================= void SUITargetStateWnd::CreateItemIcon() { KUIControlIconStatic* pIcon = dynamicCast(GetChild( "state_effect_h_icon01" )); if( pIcon == NULL ) return; KRect rt = pIcon->GetRect(); KRect EffectRT = rt; EffectRT.right = EffectRT.left + c_nIconHeight; EffectRT.bottom = EffectRT.top + c_nIconHeight; int nLeft, nTop = 0; nLeft = rt.left; nTop = rt.top; rt.left += c_nIconHeight; KUIWnd* pWnd = NULL; for( int i = 2; i <= c_nMaxNum; i++ ) { rt.right = rt.left + c_nIconHeight; rt.bottom = rt.top + c_nIconHeight; pWnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "iconstatic", CStringUtil::StringFormat( "state_effect_h_icon%02d", i ).c_str(), " ", rt, 0, 0, this, "static_job_unknownicon", c_szDEF_SPR_NAME, m_pManager, 0, "tooltip", KANCHOR_LEFT | KANCHOR_TOP ) ); if( i%12 == 0 ) { rt.left = nLeft; rt.top = nTop + c_nIconHeight; nTop = rt.top; } else rt.left += c_nIconHeight; } /*pWnd = m_pManager->CreateControl( KUIWND_CREATE_ARG( "quick_effect", "icon_effect", " ", EffectRT, 0, KFLAG_NO_GET_MESSAGE, this, "", c_szDEF_SPR_NAME, m_pManager, 0, "", KANCHOR_LEFT | KANCHOR_TOP ) ); if( pWnd ) { KUIControlQuickEffect* pSlotEffect( ((KUIControlQuickEffect*)pWnd) ); pSlotEffect->ToggleOn(true); pSlotEffect->SetShow(false); pSlotEffect->SetAniTargetSize( EffectRT.GetWidth()*2.5, EffectRT.GetHeight()*2.5 ); pSlotEffect->MovePos( EffectRT.left-17, EffectRT.top-17 ); SetChildAsTop( "icon_effect" ); }*/ } // ========================================= // 스테이트 리스트 // ========================================= bool SUITargetStateWnd::IsCashState( int nCode ) { for( int i(0); iPostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, false ) ); } bool SUITargetStateWnd::IsSlot() { if( !m_pTarget ) return false; // sonador 7.0.20 Mantis 0002775: [버프] 라펠즈PC방이나 시크루트 버프를 받은 아바타 타겟 시 제대로 보이지 않음 return ( !m_pTarget->GetCashStateList().empty() || !m_pTarget->GetPositiveStateList().empty() || !m_pTarget->GetNegativeStateList().empty() ); } bool SUITargetStateWnd::IsSetTarget() { if( !m_pTarget ) { SGame* pGame = m_pGameManager->GetActiveGame(); if( !pGame || pGame->GetGameType() != GAME_TYPE_WORLD ) return false; AR_HANDLE handle = m_PlayerInfoMgr.GetTarget(); m_pTarget = (SGameAvatarEx*)(pGame->GetGameObject(handle)); if( !m_pTarget ) return false; } return true; } void SUITargetStateWnd::RefreshAllStateInfo() { if( !IsSetTarget() ) return; vec_state_slot& PositiveList = m_pTarget->GetPositiveStateList(); vec_state_slot& NegativeList = m_pTarget->GetNegativeStateList(); int nPositiveCount = static_cast(PositiveList.size()); int nNegativeCount = static_cast(NegativeList.size()); if( nPositiveCount>24 ) nPositiveCount = 24; //이로운 지속효과를 세팅 for( int i(0); i 1~10 = 10 / 11~20 = 20 으로 NULL로 쎄팅해야할 마지막 부분을 구하는 식 nPositiveEndIndex = ((nPositiveCount-1)/12+1) * 12; for( int i(nPositiveCount); iGetPositiveStateList(); vec_state_slot& NegativeList = m_pTarget->GetNegativeStateList(); int nPositiveCount = static_cast(PositiveList.size()); int nNegativeCount = static_cast(NegativeList.size()); int nMaxCnt( nPositiveCount ); if( nMaxCnt > nIndex ) { int nPositiveIndex( nIndex ); if( 0 <= nPositiveIndex && nPositiveIndex < nPositiveCount && PositiveList[ nPositiveIndex ] ) return PositiveList[ nPositiveIndex ]->GetStateCode(); } else { int nStartIndex = (int)( (nMaxCnt+11) / 12 ) * 12; int nNegativeIndex = nIndex - nStartIndex; if( 0 <= nNegativeIndex && nNegativeIndex < nNegativeCount && nNegativeCount < c_nMaxStateIcon-1 ) { if( NegativeList[ nNegativeIndex ] ) return NegativeList[ nNegativeIndex ]->GetStateCode(); } } return -1; } void SUITargetStateWnd::SetStateData( int Index, SStateSlot* pInfo, bool bCash, bool bOnlyTime/*=false*/ ) { if( Index < 0 ) return; KUIControlIconStatic* pIcon(NULL); KUIControlClockBox* pClock(NULL); /// 2011.03.30 - prodongi KUIControlStatic* ctrlReIteration = NULL; pIcon = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_icon%02d", Index+1).c_str() )); pClock = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_clock%02d", Index+1).c_str() )); /// 2011.03.30 - prodongi ctrlReIteration = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_reiteration%02d", Index+1).c_str() )); if( pIcon ) { if( bCash ) pIcon->SetAbleReSizeRes(false); if( pInfo ) { pIcon->SetShow(true); if(!bOnlyTime) pIcon->SetIcon( c_szDEF_SPR_NAME, GetTenacityDB().GetIconName(pInfo->GetStateCode()) ); pIcon->SetTooltip( m_pDisplayInfo->GetStateToolTipText(pInfo->GetStateCode(), pInfo->GetEndTime(), pInfo->GetStateLevel(), pInfo->GetStateValue(), pInfo->IsToggleSkill()).c_str() ); } else pIcon->SetShow(false); } if( pClock ) //토글형 스킬은 쿨타임 생략 { if( pInfo && !pInfo->IsToggleSkill() ) { pClock->SetShow(true); pClock->SetMaxTime( pInfo->GetMaxTime() ); pClock->SetCurTime( pInfo->GetRemainTime() ); pClock->Begin( true ); } else pClock->SetShow(false); } /// 2011.03.30 - prodongi if (ctrlReIteration) { setReiterationCount(pInfo, ctrlReIteration); } } void SUITargetStateWnd::CheckState() { if( !IsSetTarget() ) return; vec_state_slot& CashStateList = m_pTarget->GetCashStateList(); vec_state_slot& PositiveList = m_pTarget->GetPositiveStateList(); vec_state_slot& NegativeList = m_pTarget->GetNegativeStateList(); CheckStateList( 0, CashStateList, false, true ); CheckStateList( 0, PositiveList, false, false ); CheckStateList( 0, NegativeList, true, false ); } int SUITargetStateWnd::CheckStateList( int nIndex, std::vector& rStateList, bool bharmful, bool bCash ) { nIndex = GetUpdateStateIndex(nIndex, bharmful, bCash); if( nIndex < 0 ) return -1; if( rStateList.size() > 0 ) { iterator_state_slot it = rStateList.begin(); while( it != rStateList.end() ) { SStateSlot* pInfo = (*it); KUIControlIconStatic* pIcon = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_icon%02d", nIndex+1).c_str() )); if( pIcon ) pIcon->SetTooltip( m_pDisplayInfo->GetStateToolTipText(pInfo->GetStateCode(), pInfo->GetEndTime(), pInfo->GetStateLevel(), pInfo->GetStateValue(), pInfo->IsToggleSkill()).c_str() ); nIndex++; it++; } } return nIndex; } void SUITargetStateWnd::UpdateStateData( SGameMessage* pMsg ) { SIMSG_UI_STATE_LIST_UPDATE* pStateMsg = (SIMSG_UI_STATE_LIST_UPDATE*)pMsg; int Index(-1); switch( pStateMsg->nUpdateType ) { case SIMSG_UI_STATE_LIST_UPDATE::STATE_CHANGE: { Index = GetUpdateStateIndex(pStateMsg->nIndex, pStateMsg->bharmful, false); if( Index != -1 ) SetStateData(Index, pStateMsg->pState, false); } break; case SIMSG_UI_STATE_LIST_UPDATE::STATE_ADD: case SIMSG_UI_STATE_LIST_UPDATE::STATE_ADD_CASH: case SIMSG_UI_STATE_LIST_UPDATE::STATE_CHANGE_CASH: case SIMSG_UI_STATE_LIST_UPDATE::STATE_DELETE: case SIMSG_UI_STATE_LIST_UPDATE::STATE_DELETE_CASH: case SIMSG_UI_STATE_LIST_UPDATE::STATE_REFRESH: { RefreshAllStateInfo(); } break; } if( !IsShow() && IsSlot() ) m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, true ) ); if( IsShow() && !IsSlot() ) m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, false ) ); } int SUITargetStateWnd::GetUpdateStateIndex( int Index, bool bHarmhul, bool bCash ) { if( Index < 0 ) return -1; if( !IsSetTarget() ) return -1; vec_state_slot& CashStateList = m_pTarget->GetCashStateList(); vec_state_slot& PositiveList = m_pTarget->GetPositiveStateList(); vec_state_slot& NegativeList = m_pTarget->GetNegativeStateList(); int nCrrIndex(0); if(bHarmhul) { int nSize( CashStateList.size() + PositiveList.size() ); if( nSize>0 ) { if( nSize<=12 ) nCrrIndex = 12; else nCrrIndex = 24; nCrrIndex += Index; if( nCrrIndex<36 ) return nCrrIndex; } else if( Index<24 ) { return Index; } } else { if( !bCash ) Index += CashStateList.size(); if( Index<24 ) return Index; } return -1; } void SUITargetStateWnd::DisableSlot( int nIndex, int nEnd, bool bShow ) { KUIControlIconStatic* pIcon = NULL; KUIControlClockBox* pClock = NULL; /// 2011.03.30 - prodongi KUIControlStatic* ctrlReIteration; for( int i = nIndex; i < nEnd; i++ ) { pIcon = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_icon%02d", i+1).c_str() )); if( pIcon ) { pIcon->SetShow(bShow); pIcon->SetIcon(0); pIcon->SetTooltip(); } pClock = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_clock%02d", i+1).c_str() )); if( pClock ) { pClock->SetShow(bShow); pClock->SetCurTime(0); pClock->SetMaxTime(0); pClock->Begin(); } /// 2011.03.30 - prodongi ctrlReIteration = dynamicCast(GetChild( CStringUtil::StringFormat("state_effect_h_reiteration%02d", i+1).c_str() )); if( ctrlReIteration ) { ctrlReIteration->SetShow(bShow); } } } DWORD SUITargetStateWnd::OnMouseMessage(DWORD dwMessage, int x, int y) { if( dwMessage == KLBUTTON_DBLCLK ) { AR_HANDLE handle(NULL); KUIWnd* pIcon(NULL); for( int i(0); iIsShow() && pIcon->IsInRect(x, y) ) { int nCode = GetStateCodeForIndex(i); if( IsAbleRemove( nCode ) ) { handle = GetOwnerHandle_TargetSummonCreatureForOnlyLocalPlayer(); if( handle ) m_pGameManager->ProcMsgAtStatic( &SIMSG_REQUEST_REMOVE_STATE( handle, nCode ) ); } break; } } } return SUIWnd::OnMouseMessage( dwMessage, x, y ); } bool SUITargetStateWnd::IsAbleRemove( int nID ) { if( nID ) { StateInfoEx* s_data = GetTenacityDB().GetTenacityData(nID); if( s_data && s_data->state_time_type & 1<<5 ) return true; } return false; } AR_HANDLE SUITargetStateWnd::GetOwnerHandle_TargetSummonCreatureForOnlyLocalPlayer() { if( IsSetTarget() ) { AR_HANDLE hTarget = m_pTarget->GetArID(); if( hTarget && ( m_CreatureSlotMgr.IsExistSummonedCreature(hTarget) || m_PlayerInfoMgr.IsLocalPlayer(hTarget) ) ) { return hTarget; } } return NULL; } /// 2011.03.30 - prodongi void SUITargetStateWnd::setReiterationCount(SStateSlot const* state, KUIControlStatic* control) { if (!state) { control->SetShow(false); return ; } StateInfoEx const* info = GetTenacityDB().GetTenacityData(state->GetStateCode()); if (info && 0 < info->reiteration_count) { int level = min(state->GetStateLevel(), MAX_REITERATION_LEVEL); control->SetShow(true); control->SetCaption(CStringUtil::StringFormat("<#ffffff>%d", level).c_str()); } else { control->SetShow(false); } }