#include "stdafx.h" #include "KTypes.h" //#include "Util.h" #include "SUIDefine.h" #include "SStringDB.h" #include "SItemDB.h" #include "SInventoryMgr.h" #include "SGameSystem.h" //#include "SUIWnd.h" #include "SUIDisplayInfo.h" #include "KUIControlStatic.h" //#include "SUIUtil.h" #include "SDebug_Util.h" // 2010.05.11 - prodongi #include "SSummonSlotMgr.h" #include "SCreatureDB.h" // 2010.07.27 - prodongi #include "SGameSystem.h" #include "SGameAvatarEx.h" #include "SGameUIMgr.h" #include "SMessengerMgr.h" // 2010.08.06 - prodongi #include "SPlayerInfoMgr.h" #include "SSKillSlot.h" // 2010.09.17 - prodongi #include "SCreatureEnhanceDB.h" #include "SGameMessage.h" /// 2011.01.20 - prodongi #include "SUISysMsgDefine.h" #include "SSkillDB.h" /// 2011.08.03 - prodongi #include "SGameManager.h" #include "KResourceManager.h" extern SGameSystem* g_pCurrentGameSystem; // helper ----------------------------------------------------------------------------------------- using namespace sui; std::string sui::helper::int_to_comma_numeric( __int64 number ) { return CStringUtil::GetCommaNumberString( number ); } __int64 sui::helper::comma_numeric_to_int( const char* number ) { std::string num( number ); num.erase( std::remove( num.begin(), num.end(), ',' ), num.end() ); return ::_atoi64( num.c_str() ); } std::string sui::helper::indexed_id( const char* format, int index ) { std::string id; XStringUtil::Format( id, format, index ); return id; } // null property property null_property; // sonador #2.1.2.4.3 팻 조작 UI 연동 // property array --------------------------------------------------------------------------------- property_array::property_array() { } property_array::property_array( const property_array& other ) { _copy( other ); } property_array& property_array::operator = ( const property_array& rhs ) { if( this == &rhs ) return *this; _copy( rhs ); return *this; } property_array::~property_array() { sui::wipe_seq( m_properties ); } property_array& property_array::add( property* prop ) { m_properties.push_back( prop ); return *this; } property& property_array::get( const char* name ) { if( !m_properties.empty() ) { properties_t::iterator found = std::find_if( m_properties.begin(), m_properties.end(), property::finder( name ) ); if( found != m_properties.end() ) return **found; } return null_property; } property& property_array::at( int index ) { if( index < 0 && index >= m_properties.size() ) return null_property; return *m_properties.at( index ); } property& property_array::operator[]( int index ) { return at( index ); } property& property_array::operator[]( const char* name ) { return get( name ); } int property_array::size() const { return m_properties.size(); } bool property_array::empty() const { return m_properties.empty(); } property_array::iterator property_array::begin() { return m_properties.begin(); } property_array::iterator property_array::end() { return m_properties.end(); } property_array::const_iterator property_array::begin() const { return m_properties.begin(); } property_array::const_iterator property_array::end() const { return m_properties.end(); } void property_array::_copy( const property_array& other ) { sui::wipe_seq( m_properties ); if( other.empty() ) return; property_array::const_iterator ci = other.begin(), ce = other.end(); for( ; ci != ce; ++ci ) { const property* other_prop = *ci; if( other_prop ) { property* this_prop = new property( *other_prop ); add( this_prop ); } } } // null updatable window kui_updatable_window null_updatable_window; // updatable window array ------------------------------------------------------------------------- kui_updatable_window_array::kui_updatable_window_array() { } kui_updatable_window_array::~kui_updatable_window_array() { clear(); } kui_updatable_window_array& kui_updatable_window_array::add( kui_updatable_window* window ) { m_windows.push_back( window ); return *this; } kui_updatable_window& kui_updatable_window_array::get( const char* name ) { if( !m_windows.empty() ) { window_container_t::iterator found = std::find_if( m_windows.begin(), m_windows.end(), kui_updatable_window::finder( name ) ); if( found != m_windows.end() ) return **found; } return null_updatable_window; } kui_updatable_window& kui_updatable_window_array::at( int index ) { if( index < 0 && index >= m_windows.size() ) return null_updatable_window; return *m_windows.at( index ); } kui_updatable_window& kui_updatable_window_array::operator[]( int index ) { return at( index ); } kui_updatable_window& kui_updatable_window_array::operator[]( const char* name ) { return get( name ); } int kui_updatable_window_array::size() const { return m_windows.size(); } bool kui_updatable_window_array::empty() const { return m_windows.empty(); } kui_updatable_window_array::iterator kui_updatable_window_array::begin() { return m_windows.begin(); } kui_updatable_window_array::iterator kui_updatable_window_array::end() { return m_windows.end(); } kui_updatable_window_array::const_iterator kui_updatable_window_array::begin() const { return m_windows.begin(); } kui_updatable_window_array::const_iterator kui_updatable_window_array::end() const { return m_windows.end(); } void kui_updatable_window_array::clear() { sui::wipe_seq( m_windows ); } void kui_updatable_window_array::update() { std::for_each( begin(), end(), std::mem_fun( &kui_updatable_window::update ) ); } // proxy_list ------------------------------------------------------------------------------------- proxy_list::proxy_list( SUIWnd* window, const char* id, int limit, int item_offset ) : m_id( id ) , m_limit( limit ) , m_item_offset( item_offset ) , m_offset( 0 ) , m_current_index( INVALID_VALUE ) , m_saved_offset( 0 ) , m_saved_index( INVALID_VALUE ) , m_window( window ) , m_scroll( 0 ) , m_selection_mask( 0 ) , m_selection_mask_origin_offset( 0 ) , m_proc_mouse( true ) { m_control_matrix.reserve( limit ); for( int i = 0; i < limit; ++i ) m_control_matrix.push_back( new control_row_t ); } proxy_list::~proxy_list() { wipe_seq( m_items ); control_matrix_t::iterator iRow = m_control_matrix.begin(), iRowEnd = m_control_matrix.end(); for( ; iRow != iRowEnd; ++iRow ) { control_row_t* row = *iRow; if( row ) { control_row_t::iterator iProp = row->begin(), iPropEnd = row->end(); for( ; iProp != iPropEnd; ++iProp ) { kui_window_property* prop = *iProp; if( prop ) delete prop; } delete row; } } } void proxy_list::initialize( const char* selectable_id, const char* selection_mask_id, const char* scroll_id ) { _init_selectables( selectable_id ); _init_selection_mask( selection_mask_id ); _init_scroll( scroll_id ); } void proxy_list::clear() { sui::wipe_seq( m_items ); m_offset = 0; _update_scroll_range(); _select_item_by( INVALID_VALUE ); } void proxy_list::proc_pumpup( LPCSTR id, DWORD message, DWORD lparam, DWORD wparam ) { switch( message ) { case KUI_MESSAGE::KSCROLL_SELECT: { if( m_scroll && ::stricmp( id, m_scroll->GetID() ) == 0 ) { int pos = int( lparam ); pos = std::max( pos, 0 ); pos = std::min( pos, (int)m_items.size() - 1 ); m_offset = pos; update_data(); } } break; } } void proxy_list::proc_mouse( DWORD msg, int x, int y ) { if( !m_proc_mouse ) return; if( m_window->IsInRect( x, y ) ) { switch( msg ) { case KLBUTTON_DOWN: { int index = _mouse_to_index( x, y ); if( INVALID_VALUE != index ) { _select_item_by( index ); m_window->PumpUpMessage( m_id, KUI_MESSAGE::KLIST_ITEM_CLICK, static_cast< DWORD >( m_current_index ), static_cast< DWORD >( index ) ); } } break; case KLBUTTON_DBLCLK: { int index = _mouse_to_index( x, y ); if( index != INVALID_VALUE ) { _select_item_by( index ); m_window->PumpUpMessage( m_id, KUI_MESSAGE::KLIST_ITEM_LDBLCLK, static_cast< DWORD >( m_current_index ), static_cast< DWORD >( index ) ); } } break; /// 2011.05.12 - prodongi case KRBUTTON_DOWN: { int index = _mouse_to_index( x, y ); if( index != INVALID_VALUE ) { m_window->PumpUpMessage( m_id, KUI_MESSAGE::KICON_RCLICK, static_cast< DWORD >( _to_item_index(index) ), 0 ); } } break; default: break; } } } void proxy_list::activate_mouse_proc( bool activity ) { if( m_proc_mouse != activity ) { m_proc_mouse = activity; if( !m_proc_mouse ) { _locate_selection_mask_at( INVALID_VALUE ); } } } void proxy_list::save_state() { m_saved_offset = m_offset; m_saved_index = m_current_index; } void proxy_list::load_state() { m_offset = _normalize_offset( m_saved_offset ); if( m_scroll ) m_scroll->SetPosition( m_offset ); int index_delta = m_offset - m_saved_offset; _select_item_by( _to_control_index( m_saved_index + index_delta ) ); } proxy_list::this_t& proxy_list::add( item_t* item ) { m_items.push_back( item ); _update_scroll_range(); return *this; } void proxy_list::remove( item_t* item ) { m_items.erase( std::remove( m_items.begin(), m_items.end(), item ), m_items.end() ); _update_scroll_range(); } int proxy_list::size() const { return m_items.size(); } bool proxy_list::empty() const { return m_items.empty(); } proxy_list::iterator proxy_list::begin() { return m_items.begin(); } proxy_list::iterator proxy_list::end() { return m_items.end(); } proxy_list::iterator proxy_list::visible_begin() { if( !m_items.empty() ) return m_items.begin() + m_offset; return m_items.end(); } proxy_list::iterator proxy_list::visible_end() { if( !m_items.empty() ) { int visible_end = _get_visible_end_index(); if( visible_end == m_items.size() ) return m_items.end(); return m_items.begin() + visible_end; } return m_items.end(); } proxy_list::item_t* proxy_list::at( int item_index ) { if( item_index < 0 || item_index >= m_items.size() ) return 0; return m_items.at( item_index ); } proxy_list::item_t* proxy_list::operator[ ]( int item_index ) { return at( item_index ); } void proxy_list::next_page() { if( m_items.empty() ) return; int next_page = page() + 1; if( next_page >= page_end() ) return; _set_offset_by( next_page ); update_data(); } void proxy_list::prev_page() { if( m_items.empty() ) return; int prev_page = page() - 1; if( prev_page < page_begin() ) return; _set_offset_by( prev_page ); update_data(); } int proxy_list::page_begin() const { if( m_items.empty() ) return INVALID_VALUE; return 0; } int proxy_list::page_end() const { if( m_items.empty() ) return INVALID_VALUE; return static_cast< int >( m_items.size() - 1 ) / m_limit + 1; } int proxy_list::page() const { int page = _get_page_from( m_offset ); if( !_is_valid_page( page ) ) return INVALID_VALUE; return page; } void proxy_list::update_data() { item_container_t::iterator i_item = visible_begin(); item_container_t::iterator i_item_end = visible_end(); // foreach all row for( int index = 0; index < m_limit; ++index ) { control_row_t* row = m_control_matrix.at( index ); control_row_t::iterator i_wnd = row->begin(), i_wnd_end = row->end(); // foreach all control in a row for( ; i_wnd != i_wnd_end; ++i_wnd ) { property item_prop; kui_window_property* wnd_prop = static_cast< kui_window_property* >( *i_wnd ); if( i_item != i_item_end ) { item_t* item = *i_item; item_prop = item->get( wnd_prop->get_name() ); } wnd_prop->on_update( item_prop ); } if( i_item != i_item_end ) ++i_item; } _locate_selection_mask_at( _to_control_index( m_current_index ) ); } property* proxy_list::get_window_property( int row, const char* column_id ) { property* prop = 0; if( row >= 0 && row < m_control_matrix.size() ) { control_row_t* cont = m_control_matrix.at( row ); control_row_t::iterator found = std::find_if( cont->begin(), cont->end(), property::finder( column_id ) ); if( found != cont->end() ) prop = *found; } return prop; } void proxy_list::_init_scroll( const char* window_id ) { if( !window_id ) return; m_scroll = dynamicCast< KUIControlScrollBase* >( m_window->GetChild( window_id ) ); // TODO: temporary m_window->SetChildAsTop( window_id ); } void proxy_list::_init_selectables( const char* window_id ) { if( !window_id ) return; std::string indexed_id_orig = helper::indexed_id( window_id , 0 ); KUIWnd* wnd = m_window->GetChild( indexed_id_orig.c_str() ); if( wnd == 0 ) return; m_window->SetChildAsTop( indexed_id_orig.c_str() ); m_selectables.push_back( wnd ); RECT region_offset; region_offset.left = 0; region_offset.right = 0; // n = 1 : our original control index ... for( int n = 1; n < m_limit; ++n ) { int offset = n * m_item_offset; region_offset.top = offset; region_offset.bottom = offset; m_selectables.push_back( m_window->CopyControl( indexed_id_orig.c_str(), helper::indexed_id( window_id, n ).c_str(), region_offset ) ); } } void proxy_list::_init_selection_mask( const char* selection_mask_id ) { if( !selection_mask_id ) return; m_selection_mask = m_window->GetChild( selection_mask_id ); if( m_selection_mask ) { m_window->SetChildAsTop( selection_mask_id ); m_selection_mask_origin_offset = m_selection_mask->GetRect().top - m_window->GetRect().top; _select_item_by(); } else { m_selection_mask_origin_offset = 0; } } int proxy_list::_normalize_offset( int offset ) { int result = 0; int offset_limit = m_items.size() - m_limit + 1; if( offset_limit > 0 ) { if( offset < offset_limit ) result = offset; else if( offset >= offset_limit ) result = offset - ( offset - offset_limit + 1 ); } return result; } bool proxy_list::_is_valid_index( int control_index ) const { return ( control_index < 0 || control_index >= m_limit ) ? false : true; } bool proxy_list::_is_visible_index( int control_index ) const { int item_index = _to_item_index( control_index ); return ( item_index < m_offset || item_index >= _get_visible_end_index() ) ? false : true; } int proxy_list::_get_visible_end_index() const { return std::min( m_offset + m_limit, m_items.size() ); } int proxy_list::_to_item_index( int control_index ) const { return control_index + m_offset; } int proxy_list::_to_control_index( int item_index ) const { return item_index - m_offset; } int proxy_list::_mouse_to_index( int x, int y ) const { selectables_t::const_iterator i = m_selectables.begin(), e = m_selectables.end(); for( int index = 0; i != e; ++i, ++index ) { KUIWnd* window = *i; if( window && window->IsInRect( x, y ) ) return index; } return INVALID_VALUE; } int proxy_list::_change_current_index( int new_item_index ) { if( m_current_index != new_item_index ) { int old_item_index = m_current_index; m_current_index = new_item_index; m_window->PumpUpMessage( m_id, KUI_MESSAGE::KLIST_ITEM_CHANGE, static_cast< DWORD >( new_item_index ), static_cast< DWORD >( old_item_index ) ); } m_window->PumpUpMessage( m_id, KUI_MESSAGE::KLIST_ITEM_SELECT, static_cast< DWORD >( m_current_index ), 0 ); return m_current_index; } int proxy_list::_get_page_from( int item_index ) const { if( m_items.empty() ) return INVALID_VALUE; return item_index / m_limit; } bool proxy_list::_is_valid_page( int page ) const { if( page == INVALID_VALUE ) return false; return ( page < page_begin() || page >= page_end() ) ? false : true; } void proxy_list::_set_offset_by( int page ) { if( !_is_valid_page( page ) ) return; m_offset = page * m_limit; } int proxy_list::_select_item_by( int control_index ) { _locate_selection_mask_at( control_index ); if( control_index == INVALID_VALUE || !_is_valid_index( control_index ) || !_is_visible_index( control_index ) ) { return _change_current_index( INVALID_VALUE ); } return _change_current_index( _to_item_index( control_index ) ); } void proxy_list::_locate_selection_mask_at( int control_index ) { if( !m_selection_mask ) return; if( control_index == INVALID_VALUE || !_is_valid_index( control_index ) || !_is_visible_index( control_index ) ) { m_selection_mask->SetShow( false ); return; } m_selection_mask->SetShow( true ); int x = m_selection_mask->GetRect().left; int y = m_window->GetRect().top + m_selection_mask_origin_offset + control_index * m_item_offset; m_selection_mask->MovePos( x, y ); } void proxy_list::_update_scroll_range() { if( m_scroll == 0 ) return; int range = m_items.size() - m_limit + 1; if( range >= 0 && range < m_items.size() ) m_scroll->SetMaxRange( range ); else m_scroll->SetMaxRange( 0 ); } void tickable::set_ticker( ticker* _ticker ) { m_ticker = _ticker; } bool ticker::append_tickable( tickable* _tickable ) { if( _tickable ) { ticker* tickable_ticker = _tickable->get_ticker(); if( tickable_ticker != this ) { if( tickable_ticker ) { tickable_ticker->remove_tickable( _tickable ); } _tickable->set_ticker( this ); if( is_on_tick() ) _tickable->on_enter(); if( m_lock ) m_candidates.push( _tickable ); else m_tickables.push_back( _tickable ); return true; } } return false; } bool ticker::remove_tickable( tickable* _tickable ) { if( _tickable ) { ticker* tickable_ticker = _tickable->get_ticker(); if( tickable_ticker == this ) { if( is_on_tick() ) _tickable->on_leave(); _tickable->set_ticker( 0 ); if( m_lock ) m_garbages.push( _tickable ); else remove_seq( m_tickables, _tickable ); return true; } } return false; } void ticker::tick( DWORD time ) { m_time = time; // ticking m_lock = true; if( !m_tickables.empty() ) std::for_each( m_tickables.begin(), m_tickables.end(), std::mem_fun( &tickable::on_tick ) ); m_lock = false; // remove garbages while( !m_garbages.empty() ) { tickable* _tickable = m_garbages.front(); m_garbages.pop(); remove_seq( m_tickables, _tickable ); } // push cadidates while( !m_candidates.empty() ) { tickable* _tickable = m_candidates.front(); m_candidates.pop(); m_tickables.push_back( _tickable ); } } void ticker::enter() { m_is_on_tick = true; } void ticker::leave() { m_is_on_tick = false; } void ticker::on_enter() { enter(); tickable_vector_t::iterator i = m_tickables.begin(), e = m_tickables.end(); for( ; i != e; ++i ) { tickable* tickable_pointer = *i; if( tickable_pointer ) tickable_pointer->on_enter(); } } void ticker::on_leave() { leave(); tickable_vector_t::iterator i = m_tickables.begin(), e = m_tickables.end(); for( ; i != e; ++i ) { tickable* tickable_pointer = *i; if( tickable_pointer ) tickable_pointer->on_leave(); } } void fixed_rate_ticker::on_tick() { DWORD time_diff = m_ticker->time() - m_time; if( time_diff >= m_frequency ) ticker::on_tick(); } void fixed_rate_ticker::on_enter() { // initialize timer if( m_ticker ) m_time = m_ticker->time(); ticker::on_enter(); } void fixed_rate_ticker::on_leave() { ticker::on_leave(); // reset timer m_time = 0; } void fixed_rate_one_time_ticker::on_tick() { DWORD time_diff = m_ticker->time() - m_time; if( time_diff >= m_frequency ) { ticker::on_tick(); if( m_ticker ) m_ticker->remove_tickable( this ); } } void conditional_fixed_rate_one_time_ticker::on_tick() { if( m_satisfaction ) { DWORD time_diff = m_ticker->time() - m_time; if( time_diff >= m_frequency ) { ticker::on_tick(); if( m_ticker ) m_ticker->remove_tickable( this ); } } } void conditional_fixed_rate_one_time_ticker::on_enter() { fixed_rate_ticker::on_enter(); m_satisfaction = false; } void conditional_fixed_rate_one_time_ticker::satisfy() { m_satisfaction = true; if( m_ticker ) m_time = m_ticker->time(); } // ##2.1.2.12 void Page::SetButton( KUIControl* pPrevButton, KUIControl* pNextButton ) { m_pPrevButton = pPrevButton; m_pNextButton = pNextButton; } void Page::Update( int nCurrentPage ) { m_nCurrentPage = nCurrentPage; } void Page::Update( int nCurrentPage, int nEndPage ) { m_nCurrentPage = nCurrentPage; m_nEndPage = nEndPage; // normalize button if( m_pNextButton ) { if( _IsEnd() ) m_pNextButton->Disable(); else m_pNextButton->Enable(); } if( m_pPrevButton ) { if( _IsBegin() ) m_pPrevButton->Disable(); else m_pPrevButton->Enable(); } } int Page::Current() const { return _GetNormalizedPage( m_nCurrentPage ); } int Page::End() const { return m_nEndPage; } int Page::Next() const { return _GetNormalizedPage( m_nCurrentPage + 1 ); } int Page::Prev() const { return _GetNormalizedPage( m_nCurrentPage - 1 ); } int Page::_GetNormalizedPage( int nPage ) const { if( nPage > m_nEndPage ) nPage = m_nEndPage; if( nPage < 1 ) nPage = 1; return nPage; } bool Page::_IsEnd() const { return ( m_nCurrentPage >= m_nEndPage ) ? true : false; } bool Page::_IsBegin() const { return ( m_nCurrentPage <= 1 ) ? true : false; } /// 2011.01.20 - prodongi void sMarkState::sInfo::setStateSlot(SStateSlot const* slot) { m_stateCode = slot->GetStateCode(); m_endTime = slot->GetEndTime(); m_stateLevel = slot->GetStateLevel(); m_toggleSkill = slot->IsToggleSkill(); m_stateValue = slot->GetStateValue(); } void sMarkState::hideAll() { for (int i = 0; i < MAX; ++i) m_info[i].m_show = false; } void sMarkState::hideAllControl(KUIWnd* wnd) { wnd->SetChildShow("mark_state_04"); wnd->SetChildShow("mark_state_03"); wnd->SetChildShow("mark_state_02"); wnd->SetChildShow("mark_state_01"); } void sMarkState::updateMarkStateList(KUIWnd* wnd, SUIDisplayInfo* displayInfo, SGameAvatarEx* avatar) { if (!avatar) return ; m_info[eState::FREEPASS].m_show = false; m_info[eState::PC].m_show = false; vec_state_slot const& markStateList = avatar->getMarkStateList(); for (size_t i = 0; i < markStateList.size(); ++i) { int state_code = markStateList[i]->GetStateCode(); SStateSlot const* slot = markStateList[i]; if (9004 == slot->GetStateCode()) { sMarkState::sInfo* info = m_info + sMarkState::FREEPASS; info->m_show = true; info->setStateSlot(slot); } else if (9005 == slot->GetStateCode() || 9006 == slot->GetStateCode()) { sMarkState::sInfo* info = m_info + sMarkState::PC; info->m_show = true; info->setStateSlot(slot); } } sortMarkState(wnd, displayInfo); } void sMarkState::updateMarkStatusList(KUIWnd* wnd, SUIDisplayInfo* displayInfo, int status) { m_info[eState::PVP].m_show = false; m_info[eState::PK].m_show = false; if (SMSG_MARK_STATUS_CHANGE::PVP & status) { m_info[eState::PVP].m_show = true; } if (SMSG_MARK_STATUS_CHANGE::PK_NORMAL & status) { m_info[eState::PK].m_show = true; m_info[eState::PK].m_status = status; } else if (SMSG_MARK_STATUS_CHANGE::PK_DEMONIAC & status) { m_info[eState::PK].m_show = true; m_info[eState::PK].m_status = status; } sortMarkState(wnd, displayInfo); } /// 2011.01.19 - prodongi void sMarkState::sortMarkState(KUIWnd* wnd, SUIDisplayInfo* displayInfo) { hideAllControl(wnd); int controlIndex = 0; for (int i = 0; i < eState::MAX; ++i) { sMarkState::sInfo* info = m_info + i; if (info->m_show) { std::string controlName = CStringUtil::StringFormat("mark_state_%02d", controlIndex+1); KUIControl* control = dynamicCast(wnd->GetChild(controlName.c_str())); control->SetShow(true); if (i == eState::PVP) { control->SetBack(wnd->GetSprName(), "common_mark_state_pvp_normal"); control->SetTooltip(S(7235)); info->m_strMarkControlName = controlName; } else if (i == eState::PK) { if (SMSG_MARK_STATUS_CHANGE::PK_NORMAL & info->m_status) { control->SetBack(wnd->GetSprName(), "common_mark_state_pk_normal"); control->SetTooltip(S(7236)); } else if (SMSG_MARK_STATUS_CHANGE::PK_DEMONIAC & info->m_status) { control->SetBack(wnd->GetSprName(), "common_mark_state_pk_demoniac"); control->SetTooltip(S(7237)); } info->m_strMarkControlName = controlName; } else if (i == eState::FREEPASS) { control->SetBack(wnd->GetSprName(), "common_mark_state_freepass_90"); control->SetTooltip(displayInfo->GetStateToolTipText(info->m_stateCode, info->m_endTime, info->m_stateLevel, info->m_stateValue, info->m_toggleSkill).c_str() ); info->m_strMarkControlName = controlName; } else if (i == eState::PC) { control->SetBack(wnd->GetSprName(), "common_mark_state_pcbangpremium"); control->SetTooltip( displayInfo->GetStateToolTipText( info->m_stateCode, info->m_endTime, info->m_stateLevel, info->m_stateValue, info->m_toggleSkill).c_str() ); info->m_strMarkControlName = controlName; } else __noop; ++controlIndex; } } } //----------------------------------------------------------------------------------------------------------------- // 시쿠르트 이용권 ( FREEPASS )의 위에 마우스가 있는가? //----------------------------------------------------------------------------------------------------------------- bool sMarkState::IsInRectFreePass( KUIWnd* pDestWnd, const KPoint ptMouse ) { if( NULL == pDestWnd ) return false; sMarkState::sInfo* pInfo( &m_info[eState::FREEPASS] ); if( NULL == pInfo ) return false; if( false == pInfo->m_show ) return false; KUIControl* pControl( dynamicCast( pDestWnd->GetChild( pInfo->m_strMarkControlName.c_str() ) ) ); if( pControl ) return pControl->GetRect().IsInRect( ptMouse.x, ptMouse.y ); return false; } //----------------------------------------------------------------------------------------------------------------- // 시쿠르트 이용권 ( FREEPASS )의 남은 시간 툴팁 갱신 //----------------------------------------------------------------------------------------------------------------- void sMarkState::UpdateFreePassEndTimeTooltip( KUIWnd* pDestWnd, SUIDisplayInfo* pDisplayInfo ) { if( NULL == pDestWnd ) return ; sMarkState::sInfo* pInfo( &m_info[eState::FREEPASS] ); if( NULL == pInfo ) return ; if( false == pInfo->m_show ) return ; KUIControl* pControl( dynamicCast( pDestWnd->GetChild( pInfo->m_strMarkControlName.c_str() ) ) ); if( pControl ) pControl->SetTooltip( pDisplayInfo->GetStateToolTipText( pInfo->m_stateCode, pInfo->m_endTime, pInfo->m_stateLevel, pInfo->m_stateValue, pInfo->m_toggleSkill).c_str() ); } sOpacityMouseChecker::~sOpacityMouseChecker() { m_childList.clear(); } void sOpacityMouseChecker::open() { setAlpha(0.0f); changeAlpha(); } void sOpacityMouseChecker::update(DWORD dwTime, int x, int y, SUIWnd* wnd) { if (!wnd) return ; float t = (float)dwTime/1000.0f; float s = t * m_alphaV; if (wnd->IsInRect(x, y)) { setAlpha(m_alpha + s); } else { setAlpha(m_alpha - s); } changeAlpha(); } void sOpacityMouseChecker::setAlpha(float alpha) { if (fabs(alpha-m_alpha) < FLT_EPSILON) { return ; } if (1.0f < alpha) alpha = 1.0f; else if (0.0f > alpha) alpha = 0.0f; m_alpha = alpha; } void sOpacityMouseChecker::addChild(SUIWnd* parent, char const* id) { KUIWnd* wnd = parent->GetChild(id); if (id && wnd) m_childList.push_back(wnd); } void sOpacityMouseChecker::setShow(bool show) { std::vector::iterator it = m_childList.begin(); for (; it != m_childList.end(); ++it) (*it)->SetShow(show); } void sOpacityMouseChecker::changeAlpha() { std::vector::iterator it = m_childList.begin(); for (; it != m_childList.end(); ++it) (*it)->ChangeAlpha(m_alpha); } // 2010.05.11 - prodongi void getEnhanceIconName(char* enhanceIconName, SCreatureInfo const* info, int enhance) { // 2010.08.31 - prodongi getEnhanceIconName(enhanceIconName, info->GetID(), enhance); } // 2010.08.31 - prodongi void getEnhanceIconName(char* enhanceIconName, ENC_INT creatureId, int enhance) { char const* iconName = GetCreatureDB().GetIconName(creatureId); if (0 == enhance) { strcpy(enhanceIconName, (iconName) ? iconName : ""); return ; } sprintf(enhanceIconName, "%s_ultimate01", iconName); //gmpbigsun( 20130411 ) : 파일이 존재하지 않는다면 강화전이름으로 SPRITE_SET * pSprSet = KSpriteManager::GetManager()->GetSpriteSet( enhanceIconName ); if( NULL == pSprSet ) strcpy( enhanceIconName, iconName ); } // 2010.05.13 - prodongi std::string getItemName(int itemId) { const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( itemId ); if (!pItemBase) return ""; return GetStringDB().GetString( pItemBase->nNameId ); } // 2010.06.09 - prodongi void getIconNameAtDurability(SInventorySlot const* slot, std::string& iconName) { if (!slot) return ; // 2010.07.06 - prodongi /* iconName = GetItemDB().GetIconName(slot->GetItemCode()); if (ItemBase::TYPE_CARD == GetItemDB().GetUseType(slot->GetItemCode()) && ItemBase::GROUP_SUMMONCARD == GetItemDB().GetGroup(slot->GetItemCode())) { // 강화된 카드 일경우에 내구도가 0이면 사용할수 없는 카드로 변경해준다 if (0 != slot->GetEnhance()) { if (0 == slot->GetEtherealDurability()) iconName += "_uesless"; } } */ // getIconNameAtDurability(slot->GetItemCode(), slot->GetEnhance(), slot->GetEtherealDurability(), iconName); getIconNameAtDurability(slot, 0, iconName); } // 2010.07.06 - prodongi void getIconNameAtDurability(ItemBase::ItemCode itemCode, int enhance, int etherealDurability, std::string& iconName, int nFlag, int nSummonID ) { if( IsInstanceUnstackable( nFlag ) ) { // 봉인된 크리쳐카드 const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { iconName = pSummonInfo->face_file_name; } } else { iconName = GetItemDB().GetIconName(itemCode); } // 2010.07.14 - prodongi /* if (ItemBase::TYPE_CARD == GetItemDB().GetUseType(itemCode) && ItemBase::GROUP_SUMMONCARD == GetItemDB().GetGroup(itemCode)) { // 강화된 카드 일경우에 내구도가 0이면 사용할수 없는 카드로 변경해준다 if (0 != enhance) { if (0 == etherealDurability) iconName += "_uesless"; } } */ if (isExhaustedSummonCard(itemCode, enhance, etherealDurability)) iconName += "_uesless"; } void getIconNameAtDurability(ItemBase::ItemCode itemCode, int enhance, int etherealDurability, std::string& iconName, XFlag tFlag, int nSummonID ) { if( IsInstanceUnstackable( tFlag ) ) { // 봉인된 크리쳐카드 const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { iconName = pSummonInfo->face_file_name; } } else { iconName = GetItemDB().GetIconName(itemCode); } // 2010.07.14 - prodongi /* if (ItemBase::TYPE_CARD == GetItemDB().GetUseType(itemCode) && ItemBase::GROUP_SUMMONCARD == GetItemDB().GetGroup(itemCode)) { // 강화된 카드 일경우에 내구도가 0이면 사용할수 없는 카드로 변경해준다 if (0 != enhance) { if (0 == etherealDurability) iconName += "_uesless"; } } */ if (isExhaustedSummonCard(itemCode, enhance, etherealDurability)) iconName += "_uesless"; } void getIconNameAtDurability( SInventorySlot const* pSlot, int nTmep, std::string& iconName ) { int nItemCode = pSlot->GetItemCode(); int nEnhance = pSlot->GetEnhance(); int nEtherealDurability = pSlot->GetEtherealDurability(); if( pSlot->GetXFlag().IsOn( ItemInstance::ITEM_FLAG_SUMMON ) ) //봉인된 크리쳐 카드 { //gmpbigsun( 20130326 ) : 봉카의 경우 face_file_name이 슬롯icon const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( pSlot->GetSummonID() ); if( pSummonInfo ) { // 1. 봉인된 크리쳐의 color_id를 얻는다. // 2. "icon_card_creature_" + "color_id" 를 합성한다. iconName = pSummonInfo->face_file_name; } } else { iconName = GetItemDB().GetIconName(nItemCode); } if (isExhaustedSummonCard(nItemCode, nEnhance, nEtherealDurability)) iconName += "_uesless"; } bool setIconNameEquipment_ENHANCE( KUIControlMultiIcon* icon, ENC_INT itemCode, const int nEnhance ) { const ItemBaseEx_info* pItem = GetItemDB().GetItemData( itemCode ); if (pItem) { std::string strTemp; if( pItem->nType == ItemBase::TYPE_CARD && pItem->nGroup == ItemBase::GROUP_SUMMONCARD ) return false; switch (nEnhance) { case 1: strTemp = "game_mark_enhence01"; break; case 2: strTemp = "game_mark_enhence02"; break; case 3: strTemp = "game_mark_enhence03"; break; case 4: strTemp = "game_mark_enhence04"; break; case 5: strTemp = "game_mark_enhence05"; break; case 6: strTemp = "game_mark_enhence06"; break; case 7: strTemp = "game_mark_enhence07"; break; case 8: strTemp = "game_mark_enhence08"; break; case 9: strTemp = "game_mark_enhence09"; break; case 10: strTemp = "game_mark_enhence10"; break; case 11: strTemp = "game_mark_enhence11"; break; case 12: strTemp = "game_mark_enhence12"; break; case 13: strTemp = "game_mark_enhence13"; break; case 14: strTemp = "game_mark_enhence14"; break; case 15: strTemp = "game_mark_enhence15"; break; case 16: strTemp = "game_mark_enhence16"; break; case 17: strTemp = "game_mark_enhence17"; break; case 18: strTemp = "game_mark_enhence18"; break; case 19: strTemp = "game_mark_enhence19"; break; case 20: strTemp = "game_mark_enhence20"; break; case 21: strTemp = "game_mark_enhence21"; break; case 22: strTemp = "game_mark_enhence22"; break; case 23: strTemp = "game_mark_enhence23"; break; case 24: strTemp = "game_mark_enhence24"; break; case 25: strTemp = "game_mark_enhence25"; break; default: return false; } icon->SetIcon( 7, c_szDEF_SPR_NAME, strTemp.c_str() ); } return false; } bool getIconNameSummonCard_BORDER( std::string& strTemp, int nSummonID, int nEnhance, int nDurability ) { if( false == strTemp.empty() ) strTemp.clear(); //테두리가 내구도 표현까지 추가댐 if( nEnhance != 0 && nDurability == 0 ) { strTemp = "game_panel_creaturecard_useless"; return true; } BYTE byRank( SummonBase::RATE_BASIC ); //크리쳐 카드가 벨트에 장착 되어 있으면, E 표시 const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { //1.희귀 등급에 따라 테두리 결정 byRank = GetCreatureDB().GetRate( nSummonID ); switch( byRank ) { case SummonBase::RATE_BASIC: strTemp = "game_panel_creaturecard_rank_0"; return true; case SummonBase::RATE_NORMAL_BASIC: strTemp = "game_panel_creaturecard_rank_1"; return true; case SummonBase::RATE_SPECIAL_BASIC: strTemp = "game_panel_creaturecard_rank_2"; return true; case SummonBase::RATE_NORMAL_RARE: strTemp = "game_panel_creaturecard_rank_3"; return true; case SummonBase::RATE_SPECIAL_RARE: strTemp = "game_panel_creaturecard_rank_4"; return true; case SummonBase::RATE_UNIQUE: strTemp = "game_panel_creaturecard_rank_5"; return true; // AziaMafia Pet Rarity case SummonBase::RATE_VERACRUZ: strTemp = "game_panel_creaturecard_rank_6"; return true; case SummonBase::RATE_PHANTOM: strTemp = "game_panel_creaturecard_rank_7"; return true; case SummonBase::RATE_AURA: strTemp = "game_panel_creaturecard_rank_8"; return true; case SummonBase::RATE_SHINNY: strTemp = "game_panel_creaturecard_rank_9"; return true; case SummonBase::RATE_GALAXY: strTemp = "game_panel_creaturecard_rank_10"; return true; default: { SDEBUGLOG( "[Summon DB] Unknown creature grade. - [%u]", byRank ); assert( NULL ); } break; } } return false; } bool getIconNameSummonCard_FORMATION( std::string& strTemp, AR_HANDLE nHandle ) { if( false == strTemp.empty() ) strTemp.clear(); if( g_pCurrentGameSystem->GetCreatureSlotMgr().IsExistCreatureCard( nHandle ) ) { strTemp = "common_mark_titanium_creature"; return true; } return false; } bool getIconNameSummonCard_BELT( std::string& strTemp, AR_HANDLE nHandle ) { if (false == strTemp.empty()) strTemp.clear(); if (g_pCurrentGameSystem->GetInventoryMgr().IsBeltSlotCard( nHandle )) { strTemp = "common_mark_titanium_belt"; return true; } return false; } bool getIconNameSummonCard_STAGE( std::string& strTemp, const int nSummonID, const int nEnhance ) { if( false == strTemp.empty() ) strTemp.clear(); _SUMMON_INFO_FILE* pCreature = GetCreatureDB().GetCreatureData( nSummonID ); if( pCreature ) { switch( nEnhance ) { case 1: strTemp = "game_mark_creature_evolution_01"; return true; case 2: strTemp = "game_mark_creature_evolution_02"; return true; case 3: strTemp = "game_mark_creature_evolution_03"; return true; case 4: strTemp = "game_mark_creature_evolution_04"; return true; case 5: strTemp = "game_mark_creature_evolution_05"; return true; default: return false; } } return false; } // 2010.07.14 - prodongi bool isExhaustedSummonCard(ItemBase::ItemCode itemCode, int enhance, int etherealDurability) { if (ItemBase::TYPE_CARD == GetItemDB().GetUseType(itemCode) && ItemBase::GROUP_SUMMONCARD == GetItemDB().GetGroup(itemCode)) { // 강화된 카드 일경우에 내구도가 0이면 사용할수 없는 카드로 변경해준다 if (0 != enhance) { if (0 == etherealDurability) return true; } } return false; } EquipItemAddtionalIconSetter::EquipItemAddtionalIconSetter( KUIControlMultiIcon* pIcon, ItemBase::ItemCode nItemCode, int nEnhance, int nEtherealDurability, XFlag xFlag ) { SetIcon( pIcon, nItemCode, nEnhance, nEtherealDurability, xFlag ); } EquipItemAddtionalIconSetter::EquipItemAddtionalIconSetter( KUIControlMultiIcon* pIcon, SInventorySlot* pSlot ) { SetIcon( pIcon, pSlot->GetItemCode(), pSlot->GetEnhance(), pSlot->GetItem()->ethereal_durability, pSlot->GetXFlag() ); } void EquipItemAddtionalIconSetter::SetIcon( KUIControlMultiIcon* pIcon, ItemBase::ItemCode nItemCode, int nEnhance, int nEtherealDurability, XFlag xFlag ) { SGameAvatarEx* pOwner = g_pCurrentGameSystem->GetLocalPlayer(); ::setIconNameEquipment_ENHANCE( pIcon, nItemCode, nEnhance ); if (pOwner) ::setCantWearIcon( pIcon, nItemCode, pOwner->GetJobID(), pOwner->GetRace(), pOwner->GetLevel(), xFlag, g_pCurrentGameSystem->GetSkillSlotMgr() ); ::setDurabilityIcon( pIcon, nItemCode, nEtherealDurability ); ::setEnhanceFailedIcon( pIcon, xFlag ); } bool isWearableDecoItem( const ItemBaseEx_info* pItem ) { // 꾸미기 무기/방패일 경우 장착 위치에 대응하는 장비 위치에 현재 장착하고있는 아이템과 타입이 맞는지 체크 if( pItem->WearType == ItemBase::WEAR_DECO_WEAPON || pItem->WearType == ItemBase::WEAR_DECO_SHIELD ) { SGameAvatarEx* pOwner = g_pCurrentGameSystem->GetLocalPlayer(); ItemBase::ItemWearType nRelativePos = ( pItem->WearType == ItemBase::WEAR_DECO_WEAPON ) ? ItemBase::WEAR_WEAPON : ItemBase::WEAR_LEFTHAND; SInventorySlot* pWearItem = g_pCurrentGameSystem->GetInventoryMgr().GetItemInfo( nRelativePos ); if( pWearItem == NULL ) { return false; } int nWearClass = GetItemDB().GetItemData( pWearItem->GetItemCode() )->nClass; switch( nWearClass ) { case ItemBase::CLASS_ONEHAND_SWORD: if( pItem->nClass != ItemBase::CLASS_DECO_ONEHAND_SWORD ) return false; break; case ItemBase::CLASS_TWOHAND_SWORD: if( pItem->nClass != ItemBase::CLASS_DECO_TWOHAND_SWORD ) return false; break; case ItemBase::CLASS_DAGGER: if( pItem->nClass != ItemBase::CLASS_DECO_DAGGER ) return false; break; case ItemBase::CLASS_TWOHAND_SPEAR: if( pItem->nClass != ItemBase::CLASS_DECO_TWOHAND_SPEAR ) return false; break; case ItemBase::CLASS_TWOHAND_AXE: if( pItem->nClass != ItemBase::CLASS_DECO_TWOHAND_AXE ) return false; break; case ItemBase::CLASS_ONEHAND_MACE: if( pItem->nClass != ItemBase::CLASS_DECO_ONEHAND_MACE ) return false; break; case ItemBase::CLASS_TWOHAND_MACE: if( pItem->nClass != ItemBase::CLASS_DECO_TWOHAND_MACE ) return false; break; case ItemBase::CLASS_HEAVY_BOW: if( pItem->nClass != ItemBase::CLASS_DECO_HEAVY_BOW ) return false; break; case ItemBase::CLASS_LIGHT_BOW: if( pItem->nClass != ItemBase::CLASS_DECO_LIGHT_BOW ) return false; break; case ItemBase::CLASS_CROSSBOW: if( pItem->nClass != ItemBase::CLASS_DECO_CROSSBOW ) return false; break; case ItemBase::CLASS_ONEHAND_STAFF: if( pItem->nClass != ItemBase::CLASS_DECO_ONEHAND_STAFF ) return false; break; case ItemBase::CLASS_TWOHAND_STAFF: if( pItem->nClass != ItemBase::CLASS_DECO_TWOHAND_STAFF ) return false; break; case ItemBase::CLASS_ONEHAND_AXE: if( pItem->nClass != ItemBase::CLASS_DECO_ONEHAND_AXE ) return false; break; case ItemBase::CLASS_SHIELD: if( pItem->nClass != ItemBase::CLASS_DECO_SHIELD ) return false; break; default: return false; } } return true; } bool isWearableSkillCardItem( const ItemBaseEx_info* pItem, SSkillSlotMgr& SkillSlotMgr ) { if( ItemBase::GROUP_SKILLCARD == pItem->nGroup ) { if( SkillSlotMgr.GetSkillSlot( pItem->nSkillID ) == NULL ) { return false; } } return true; } void setCantWearIcon(KUIControlMultiIcon* icon, ENC_INT itemCode, int nJobID, int nRace, int nLevel, XFlag xFlag, SSkillSlotMgr& SkillSlotMgr ) { const ItemBaseEx_info* pItem = GetItemDB().GetItemData( itemCode ); ////////////////////////////////////////////////////////////////////////// // 장비품 아님 if( pItem->WearType == ItemBase::WEAR_CANTWEAR && pItem->nCode != 804000 ) { return; } // 크리처 장비(크리처 전용장비와 카드화된 아이템) 무시 if( pItem->WearType == ItemBase::WEAR_SUMMON_ONLY || xFlag.IsOn( ItemInstance::ITEM_FLAG_CARD ) ) { return; } ////////////////////////////////////////////////////////////////////////// if( isWearableSkillCardItem( pItem, SkillSlotMgr ) == false || isWearableDecoItem( pItem ) == false || SItemDB::IsWearable( pItem, nJobID, nRace, nLevel ) == false ) // 착용불가 { icon->SetIcon( 3, c_szDEF_SPR_NAME, "static_cant_wear_item" ); } } // 2010.07.20 - prodongi void setDurabilityIcon(KUIControlMultiIcon* icon, ENC_INT itemCode, int etherealDurability) { /// 2011.08.03 스킬카드는 내구도를 갖지 않고, 3 layer를 equip으로 쓰고 있다. - prodongi if( GetItemDB().GetUseType(itemCode) == ItemBase::TYPE_CARD ) { if (GetItemDB().GetGroup(itemCode) == ItemBase::GROUP_SKILLCARD) return; } const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData(itemCode); if(pItemBase) { if(pItemBase->nEthereal_durability > 0) { // pItemBase->nGrade가 0이면 에테리얼 스톤으로 간주해서 깨진 아이템으로 표시해주지 않는다 /// 2010.10.05 보스카드도 nGrade가 0이기 때문에 보스 카드 체크를 추가 해줘야 된다- prodongi if (etherealDurability == 0) { if (pItemBase->nGrade > 0 || GetItemDB().GetGroup(itemCode) == ItemBase::GROUP_BOSSCARD) { icon->SetIcon( 3, c_szDEF_SPR_NAME, "static_Durability_item_destroy" ); } } } } } void setEnhanceFailedIcon(KUIControlMultiIcon* icon, XFlag xFlag) { if( xFlag.IsOn( ItemInstance::ITEM_FLAG_FAILED ) ) // 강화 실패 작 { icon->SetIcon( 3, c_szDEF_SPR_NAME, "static_enhance_failed_item" ); } } // 2010.06.11 - prodongi bool checkUseEqualHairTypeItem(ItemBase const* item) { if (123 == item->nOptType[0]) { int itemHairId = item->dOptVar1[0]; SGameAvatarEx* pLocalPlayer = g_pCurrentGameSystem->GetLocalPlayer(); int curHairId = pLocalPlayer->GetHair(); if (101 == curHairId || 102 == curHairId) { if (101 == itemHairId || 102 == itemHairId) { _oprint("don't use equal default hair item\n"); return true; } } else if (103 == curHairId || 104 == curHairId) { if (103 == itemHairId || 104 == itemHairId) { _oprint("don't use equal default hair item\n"); return true; } } else if (105 == curHairId || 106 == curHairId) { if (105 == itemHairId || 106 == itemHairId) { _oprint("don't use equal default hair item\n"); return true; } } } return false; } // 2010.07.27 - prodongi bool checkEnableUseItem(ItemBase const* item, int itemCode, SUIDisplayInfo* displayInfo, int& msgId) { msgId = SYS_MSG_USE_ITEM_FAIL; /// 기본 // 소환의 깃털 if (112 == item->nOptType[0]) { // 2011.10.18 : servantes : SPartyMgr 관리 클래스 CPartyListMgr CPartyListMgr* partMgr = dynamicCast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PARTY_MGR )); if (0 == partMgr->GetMemberCount()) return false; int optVar_1 = (int)item->dOptVar1[0]; if (8 == optVar_1) { if (1 >= partMgr->GetLoginMemberCount()) { return false; } } else if (1 == optVar_1) { // 2010.08.06 - prodongi AR_HANDLE selectedHandle; SPlayerInfoMgr* playerInfoMgr = displayInfo->GetPlayerInfoManager(); if (playerInfoMgr->GetTarget()) selectedHandle = playerInfoMgr->GetTarget(); else selectedHandle = displayInfo->GetPartyHandle(); if (!selectedHandle) return false; SGameAvatarEx* localPlayer = g_pCurrentGameSystem->GetLocalPlayer(); if (selectedHandle == localPlayer->GetArID()) return false; if (!partMgr->IsExistLoginMember(selectedHandle)) { return false; } } } /// 2011.07.20 인스턴스 던전에서 귀환의 깃털 사용 - prodongi if (910006 == itemCode) { if (PLAYER_IN_INSTANCE_DUNGEON_AUTO == displayInfo->GetPlayerInfoManager()->GetCurrentLocation()) { msgId = SYS_MSG_INVALID_ACT_IN_DUN; return false; } } return true; } // 2010.08.20 - prodongi void setStaticWndGage(KUIWnd* wnd, int maxSize, float percent) { KRect rt = wnd->GetRect(); rt.right = rt.left + (int)((float)maxSize * percent); wnd->Resize( rt ); } // 2010.09.17 - prodongi float getEquipCardDurPercent(SInventorySlot const* slot) { int slotDurability = slot->GetEtherealDurability(); int maxDurability = slot->getMaxEtherealDurability(); if (0 < maxDurability) return (float)slotDurability/(float)maxDurability; return 0.0f; } // 2010.09.17 - prodongi /* Level 0 : 0.0 <= p < 0.33; Level 1 : 0.33 <= p < 0.66; Level 2 : 0.66 <= p <= 1.0; */ int getEquipCardDurPercentLevel(SInventorySlot const* slot) { float p = getEquipCardDurPercent(slot); if (0.0f <= p && 0.33f > p) return 0; else if (0.33f <= p && 0.66f > p) return 1; else if (0.66f <= p && 1.0f >= p ) return 2; return 0; } // 2010.09.17 - prodongi float getCreatureCardDurPercent(SInventorySlot const* slot, int enhance) { return getCreatureCardDurPercent(slot->GetEtherealDurability(), enhance); } /// 2011.03.29 - prodongi float getCreatureCardDurPercent(int etherealDurability, int enhance) { int slotDurability = etherealDurability; int maxDurability = GetCreatureEnhanceDB().getCardDurability(enhance); if (0 < maxDurability) return (float)slotDurability/(float)maxDurability; return 0.0f; } // 2010.09.17 - prodongi /* Level 0 : 0.0 <= p < 0.33; Level 1 : 0.33 <= p < 0.66; Level 2 : 0.66 <= p <= 1.0; */ int getCreatureCardDurPercentLevel(SInventorySlot const* slot, int enhance) { return getCreatureCardDurPercentLevel(slot->GetEtherealDurability(), enhance); } /// 2011.03.29 - prodongi int getCreatureCardDurPercentLevel(int etherealDurability, int enhance) { float p = getCreatureCardDurPercent(etherealDurability, enhance); if (0.0f <= p && 0.33f > p) return 0; else if (0.33f <= p && 0.66f > p) return 1; else if (0.66f <= p && 1.0f >= p ) return 2; return 0; } /// 2010.12.17 - prodongi void setChildControlEnable(KUIWnd* parent, char const* childId, bool enable) { KUIControl* control = dynamicCast(parent->GetChild(childId)); if (!control) return ; if (enable) control->Enable(); else control->Disable(); } std::string expToString(__int64 exp) { std::string str = ""; if (exp > c_nEXPMLimit) { exp /= 1000000; str += CStringUtil::StringFormat( "%I64d<#4ad55d>M<#ffffff>", exp); } else if(exp > c_nEXPKLimit ) { exp /= 1000; str += CStringUtil::StringFormat( "%I64d<#fafa01>K<#ffffff>", exp); } else { str += CStringUtil::StringFormat( "%I64d", exp); } return str; } /// 2011.02.09 - prodongi void jpToString(__int64 jp, std::string& str) { str = ""; if (jp > c_nJPMLimit) { jp /= 1000000; str += CStringUtil::StringFormat( "%I64dM", jp); } else if( jp > c_nJPKLimit ) { jp /= 1000; str += CStringUtil::StringFormat( "%I64dK", jp); } else { str += CStringUtil::StringFormat( "%I64d", jp); } } /// 2011.03.07 - prodongi void convertMagicTypeToString(int type, std::string& str) { int strId = 0; switch(type) { case StateInfo::ET_FIRE: //화속성 strId = 7083; break; case StateInfo::ET_WATER: //수속성 strId = 7084; break; case StateInfo::ET_WIND: //풍속성 strId = 7085; break; case StateInfo::ET_EARTH: //토속성 strId = 7086; break; case StateInfo::ET_LIGHT: //명속성 strId = 7087; break; case StateInfo::ET_DARK: //암속성 strId = 7088; break; case StateInfo::ET_ALL: strId = 7089; break; default: strId = 7082; break; } str = S(strId); } /// 2011.03.18 - prodongi void getNpcIconAniName(std::string& str, unsigned int type, unsigned int status) { if( status == 0 ) { if (0 == type) str = "common_mark_minimap_npc"; else if (1 == type) str = "common_mark_minimap_npc_merchant"; else if (2 == type) str = "common_mark_minimap_npc_telepoter"; /// 2011.06.14 - prodongi else if (3 == type) str = "common_mark_minimap_npc_guide"; else if (4 == type) str = "common_mark_minimap_npc_laktrader"; /// 2011.08.03 - prodongi else if (5 == type) str = "common_mark_minimap_npc_warehouse"; else if (6 == type) str = "common_mark_minimap_npc_auction"; return ; } if( status & TS_ENTER::NPCInfo::FLAG_HAS_STARTABLE_QUEST ) { str = "common_mark_minimap_npc_quest01"; } if( status & TS_ENTER::NPCInfo::FLAG_HAS_IN_PROGRESS_QUEST ) { str = "common_mark_minimap_npc_quest02"; } if( status & TS_ENTER::NPCInfo::FLAG_HAS_FINISHABLE_QUEST ) { str = "common_mark_minimap_npc_quest03"; } } /// 2011.07.21 - prodongi void getDungeonGateIconAniName(std::string& str, int type) { /// 인스턴스 던전 if (1 == type) { str = "common_mark_minimap_npc_dungeon"; } /// 일반 던전 else if (2 == type) { str = "common_mark_minimap_npc_dungeon"; } } bool setHPGaugeTexture(int percent, KUIControlGauge* pGauge, int nPixelHeight) { if(pGauge == NULL) return false; char const* aniName = NULL; if( nPixelHeight == 4 ) { if ( percent > 50 ) aniName = "common_gauge_titanium_player_hp100_himini"; else if( percent > 20 ) aniName = "common_gauge_titanium_player_hp50_himini"; else aniName = "common_gauge_titanium_player_hp20_himini"; } else if( nPixelHeight == 5 ) { if ( percent > 50 ) aniName = "common_gauge_titanium_player_hp100_mini"; else if( percent > 20 ) aniName = "common_gauge_titanium_player_hp50_mini"; else aniName = "common_gauge_titanium_player_hp20_mini"; } else if( nPixelHeight == 11 ) { if ( percent > 50 ) aniName = "common_gauge_titanium_player_hp100_middle"; else if( percent > 20 ) aniName = "common_gauge_titanium_player_hp50_middle"; else aniName = "common_gauge_titanium_player_hp20_middle"; } if (aniName) { if( stricmp( pGauge->GetAniName(), aniName ) != 0 ) pGauge->SetBack( "ui_frame.spr", aniName ); } return true; } /// 2011.04.22 - prodongi bool isLastBR(char const* str) { if (!str) return false; int size = strlen(str); if (size < strlen("
")) return false; if (str[size-1] != '>') return false; char temp[10]; int start, end; bool closed = true; for (int i = size-1; i > 0; --i) { if (str[i] == '>') { closed = false; end = i; } else if (str[i] == '<') { start = i; closed = true; int copyLen = min(end - start + 1, 10); strncpy(temp, str+start, copyLen); temp[copyLen] = 0x00; if (0 == strcmp(temp, "
")) return true; if (0 == strcmp(temp, "
")) return true; } else { if (closed) return false; } } return false; } /// 2011.04.27 - prodongi bool isFirstBR(char const* str) { if (!str) return false; int size = strlen(str); if (size < strlen("
")) return false; if (str[0] != '<') return false; char temp[10]; int start, end; bool closed = true; for (int i = 0; i < size; ++i) { if (str[i] == '<') { closed = false; start = i; } else if (str[i] == '>') { end = i; closed = true; int copyLen = min(end - start + 1, 10); strncpy(temp, str+start, copyLen); temp[copyLen] = 0x00; if (0 == strcmp(temp, "
")) return true; if (0 == strcmp(temp, "
")) return true; } else { if (closed) return false; } } return false; } /// 2011.08.03 - prodongi bool setSkillCardIcon(KUIControlMultiIcon* icon, int itemCode, bool isEquip) { if (!icon) return false; if( GetItemDB().GetUseType(itemCode) != ItemBase::TYPE_CARD ) return false; if( GetItemDB().GetGroup(itemCode) != ItemBase::GROUP_SKILLCARD ) return false; ItemBaseEx_info const* item = GetItemDB().GetItemData(itemCode); if (item) { SkillBaseEx* skill = GetSkillDB().GetSkillData(item->nSkillID); if (skill) { icon->SetIcon(0, c_szDEF_SPR_NAME, skill->icon_file_name); int jp = skill->GetNeedJopPoint(1); std::string raceIconName; int limit = item->nLimit; if (0 > jp) { raceIconName = "icon_card_tpskill"; } else if (ItemBase::LIMIT_DEVA & limit && ItemBase::LIMIT_ASURA & limit && ItemBase::LIMIT_GAIA & limit) { raceIconName = "icon_card_skill"; } else if (ItemBase::LIMIT_DEVA & limit) { raceIconName = "icon_card_devaskill"; } else if (ItemBase::LIMIT_ASURA & limit) { raceIconName = "icon_card_asuraskill"; } else if (ItemBase::LIMIT_GAIA & limit) { raceIconName = "icon_card_gaiaskill"; } icon->SetIcon(2, c_szDEF_SPR_NAME, raceIconName.c_str()); } } icon->SetIcon( 3, c_szDEF_SPR_NAME, isEquip ? "common_mark_titanium_equipicon" : NULL); return true; } bool setSummonCardIcon( KUIControlMultiIcon* pIcon, SInventorySlot const* pSlot ) { if( NULL == pIcon || NULL == pSlot ) return false; int nItemCode = pSlot->GetItemCode(); if( GetItemDB().GetUseType(nItemCode) != ItemBase::TYPE_CARD || GetItemDB().GetGroup(nItemCode) != ItemBase::GROUP_SUMMONCARD ) return false; if( IsInstanceUnstackable( (SInventorySlot*)pSlot ) ) { int nSummonID = pSlot->GetSummonID(); const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { std::string strTemp; //0. 본체 getIconNameAtDurability(pSlot, strTemp); pIcon->SetIcon( 0, c_szDEF_SPR_NAME, strTemp.c_str()); //1. 등급마크 getIconNameSummonCard_BORDER( strTemp, pSlot->GetSummonID(), pSlot->GetEnhance(), pSlot->GetEtherealDurability() ); pIcon->SetIcon( 4, c_szDEF_SPR_NAME, strTemp.c_str() ); //2. 강화마크 getIconNameSummonCard_FORMATION( strTemp, pSlot->GetHandle() ); pIcon->SetIcon( 6, c_szDEF_SPR_NAME, strTemp.c_str() ); //3. 진화마크 getIconNameSummonCard_STAGE( strTemp, pSlot->GetSummonID(), pSlot->GetEnhance() ); pIcon->SetIcon( 7, c_szDEF_SPR_NAME, strTemp.c_str() ); return true; } } return false; } bool setSummonCardIcon( KUIControlMultiIcon* pIcon, int nItemCode, int nSummonID, int nEnhance, int nFlag, int nDurability ) { if( NULL == pIcon ) return false; if( GetItemDB().GetUseType(nItemCode) != ItemBase::TYPE_CARD || GetItemDB().GetGroup(nItemCode) != ItemBase::GROUP_SUMMONCARD ) return false; if( IsInstanceUnstackable( nFlag ) ) { std::string strTemp; const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { std::string strTemp; //0. 본체 getIconNameAtDurability(nItemCode, nEnhance, nDurability, strTemp, nFlag, nSummonID ); pIcon->SetIcon( 0, c_szDEF_SPR_NAME, strTemp.c_str()); //1. 등급마크 getIconNameSummonCard_BORDER( strTemp, nSummonID, nEnhance, nDurability ); pIcon->SetIcon( 4, c_szDEF_SPR_NAME, strTemp.c_str() ); //2. 강화마크 getIconNameSummonCard_FORMATION( strTemp, nEnhance ); pIcon->SetIcon( 6, c_szDEF_SPR_NAME, strTemp.c_str() ); //3. 진화마크 getIconNameSummonCard_STAGE( strTemp, nSummonID, nEnhance ); pIcon->SetIcon( 7, c_szDEF_SPR_NAME, strTemp.c_str() ); return true; } } return false; } bool setSummonCardIcon( KUIControlMultiIcon* pIcon, int nItemCode, int nSummonID, int nEnhance, XFlag tFlag, int nDurability ) { if( NULL == pIcon ) return false; if( GetItemDB().GetUseType(nItemCode) != ItemBase::TYPE_CARD || GetItemDB().GetGroup(nItemCode) != ItemBase::GROUP_SUMMONCARD ) return false; if( IsInstanceUnstackable( tFlag ) ) { const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { std::string strTemp; //0. 본체 getIconNameAtDurability(nItemCode, nEnhance, nDurability, strTemp, tFlag, nSummonID ); pIcon->SetIcon( 0, c_szDEF_SPR_NAME, strTemp.c_str()); //1. 등급마크 getIconNameSummonCard_BORDER( strTemp, nSummonID, nEnhance, nDurability ); pIcon->SetIcon( 5, c_szDEF_SPR_NAME, strTemp.c_str() ); //2. 강화마크 getIconNameSummonCard_FORMATION( strTemp, nEnhance ); pIcon->SetIcon( 6, c_szDEF_SPR_NAME, strTemp.c_str() ); //3. 진화마크 getIconNameSummonCard_STAGE( strTemp, nSummonID, nEnhance ); pIcon->SetIcon( 7, c_szDEF_SPR_NAME, strTemp.c_str() ); return true; } } return false; } bool setSummonCardIconForPortrait( KUIControlMultiIcon* pIcon, SInventorySlot const* pSlot ) //초상화 슬롯을 위한 { if( NULL == pIcon || NULL == pSlot ) return false; int nItemCode = pSlot->GetItemCode(); if( GetItemDB().GetUseType(nItemCode) != ItemBase::TYPE_CARD || GetItemDB().GetGroup(nItemCode) != ItemBase::GROUP_SUMMONCARD ) return false; if( IsInstanceUnstackable( (SInventorySlot*)pSlot ) ) { int nSummonID = pSlot->GetSummonID(); const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo ) { std::string strTemp; //0. 본체 getIconNameAtDurability(pSlot, strTemp); pIcon->SetIcon( 0, c_szDEF_SPR_NAME, strTemp.c_str()); //1. 등급마크 getIconNameSummonCard_BORDER( strTemp, nSummonID, pSlot->GetEnhance(), pSlot->GetEtherealDurability() ); pIcon->SetIcon( 1, c_szDEF_SPR_NAME, strTemp.c_str() ); return true; } } return false; } void ResetMultiIcon( KUIControlMultiIcon* pIcon, const int nBegin, const int nEnd ) { if( NULL == pIcon ) return; for( int i = nBegin; i < nEnd; ++i ) { pIcon->SetIcon( i, NULL ); } } /// 2011.10.21 - prodongi bool isEmptyCreatureCard(int itemCode, XFlag const& xFlag) { if( GetItemDB().GetUseType(itemCode) == ItemBase::TYPE_CARD ) { if( GetItemDB().GetGroup( itemCode ) == ItemBase::GROUP_SUMMONCARD ) { bool isSummon = xFlag.IsOn( ItemInstance::ITEM_FLAG_SUMMON ); if (!isSummon) { return true; } } } return false; } sEmptyControlRegionChecker::~sEmptyControlRegionChecker() { m_controlList.clear(); } void sEmptyControlRegionChecker::add(KUIWnd* control) { if (!control) return ; m_controlList.push_back(control); } bool sEmptyControlRegionChecker::isIn(int x, int y) const { std::list::const_iterator it = m_controlList.begin(); for (; it != m_controlList.end(); ++it) { if ((*it)->IsInRect(x, y)) return true; } return false; } int refreshItemDurability(SInventorySlot* pSlot, KUIWnd* pGauge, float fGaugeWidth) { int nResult = 0; if( pSlot == NULL || pGauge == NULL || fGaugeWidth < 0.0f ) return nResult; // 내구도 게이지 SpriteSet. 내구없는 일반아이템, 33%, 66%, 100%. const char * g_arrGaugeAni[] = { "common_guage_titanium_line_lightgrey", "common_guage_titanium_line_red", "common_guage_titanium_line_cyan", "common_guage_titanium_line_yellowgreen", "gauge_repair_line_grey" }; enum ITEM_STATE { ITEM_STATE_NONE = -1,// 장비X. ITEM_STATE_GENERAL = 0, // 일반. ITEM_STATE_UPPER, // 상급. ITEM_STATE_BROKEN, // 부서진 상급. }; ITEM_STATE itemState = ITEM_STATE::ITEM_STATE_NONE; pGauge->SetShow(false); float per = 0.0f; int nIndexAni = 0; if ( GetItemDB().GetGroup( pSlot->GetItemCode() ) == ItemBase::GROUP_SUMMONCARD ) { // AziaMafia Off Dura Pets if( pSlot->GetEnhance() > 0 ) { per = (float)pSlot->GetEtherealDurability() / (float)GetCreatureEnhanceDB().getCardDurability( pSlot->GetEnhance() ); per = per > 0.99f ? 1.0f : per; pGauge->SetShow(true); if( per < 0.33f ) // red. nIndexAni = 1; else if( per < 0.66f ) // cyan. nIndexAni = 2; else // yellowgreen. nIndexAni = 3; nResult = 1; // 내구도 있음 } else { per = 1.0f; nIndexAni = 0; // 내구도가 없을 경우 lightgrey 로 pGauge->SetShow(true); nResult = 1; // 내구도 없음 } } else { const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( pSlot->GetItemCode() ); if(pItemBase && pSlot->GetEtherealDurability() > 0.0f && pSlot->getMaxEtherealDurability() > 0.0f) { // 상급아이템. if(pSlot->getMaxEtherealDurability() > 0) { int crrEthereal = pSlot->GetEtherealDurability(); int maxEthereal = pSlot->getMaxEtherealDurability(); if( crrEthereal > 0 ) { itemState = ITEM_STATE::ITEM_STATE_UPPER; per = (float)crrEthereal / (float)maxEthereal; } else { itemState = ITEM_STATE::ITEM_STATE_BROKEN; //per = 0.0f; } } // 일반아이템. else itemState = ITEM_STATE::ITEM_STATE_GENERAL; nIndexAni = 4; // 내구도에 따른 SpriteSet Index; switch( itemState ) { // 장비X. case ITEM_STATE::ITEM_STATE_NONE: { nIndexAni = 4; break; } // 일반아이템. case ITEM_STATE::ITEM_STATE_GENERAL: { nIndexAni = 0; pGauge->SetAniName( "common_mark_titanium_repair_none" ); break; } // 상급아이템. case ITEM_STATE::ITEM_STATE_UPPER: { if( per < 0.33f ) // red. nIndexAni = 1; else if( per < 0.66f ) // cyan. nIndexAni = 2; else // yellowgreen. nIndexAni = 3; break; } // 파괴된아이템. case ITEM_STATE_BROKEN: { nIndexAni = 4; pGauge->SetAniName( "common_mark_titanium_repair_zero" ); break; } } // 아이템 내구도 비율 계산 per = (float)pSlot->GetEtherealDurability() / (float)pSlot->getMaxEtherealDurability(); per = per > 0.99f ? 1.0f : per; pGauge->SetShow(true); nResult = 1; // 내구도 있음 } else { per = 1.0f; nIndexAni = 0; // 내구도가 없을 경우 lightgrey 로 pGauge->SetShow(true); nResult = 1; // 내구도 없음 } } KRect rt = pGauge->GetRect(); rt.right = rt.left + fGaugeWidth * per; pGauge->Resize( rt ); pGauge->SetAniName( g_arrGaugeAni[ nIndexAni ] ); return nResult; } void UISendStringMessage(SGameManager* pGameManager, int nToUI, const char* pSendStr, bool bForceSend) { if(pGameManager == NULL || pSendStr == NULL) return ; SUIWnd* pWnd = pGameManager->GetSUI( nToUI ); if( pWnd == NULL ) return ; // bForceSend ( false ) : UI가 열려있으면 메세지 보낸다 // bForceSend ( true ) : UI가 열려있지 않아도 강제로 메세지 보낸다 if( bForceSend == false ) { if( pWnd->IsShow() == true ) pGameManager->PostMsgAtDynamic( new SIMSG_UI_SEND_DATA( (SIMSG_TOGGLE_UIWINDOW::_UIWINDOW_TYPE)nToUI, pSendStr ) ); } else { pGameManager->PostMsgAtDynamic( new SIMSG_UI_SEND_DATA( (SIMSG_TOGGLE_UIWINDOW::_UIWINDOW_TYPE)nToUI, pSendStr ) ); } }