#include "stdafx.h" #include //#include #include "KUIControlEdit.h" #include "KUIControlGauge.h" #include "SUIDisplayInfo.h" #include "SGameManager.h" //#include "SGameMessageUI.h" #include "SGameEffect.h" #include "GameRule.h" #include "GameDefine.h" #include "ItemBase.h" #include "ItemEffect.h" #include "SUIDefine.h" #include "ErrorCode/ErrorCode.h" #include "SUISysMsgDefine.h" #include "SItemDB.h" #include "SStringDB.h" #include "SSkillDB.h" #include "STenacityDB.h" #include "SCreatureDB.h" #include "SWorldLocationDB.h" #include "SSetItemEffectResourceDB.h" // #2.1.2.6.1 #include "SItemEffectResourceDB.h" // 아이템 특수 성능 #include "SEnhanceEffectDB.h" #include "SGameOption.h" #include "SMessengerMgr.h" #include "SSummonSlotMgr.h" #include "SSkillSlot.h" #include "SMotionMgr.h" #include "SPlayerInfoMgr.h" #include "SStoreMgr.h" #include "SInventoryMgr.h" #include "STradeMgr.h" #include "SStorageMgr.h" #include "SPetMgr.h" // sonador #2.1.2.4.3 팻 조작 UI 연동 #include #include #include "KCommandBuilder.h" #include #include "SBotManager.h" #include "SChatType.h" #include "SDebug_Util.h" #include "SGameAvatarEx.h" //타겟한 대상이 친구인지 알아보기 위한 함수를 위해서 추가 -N4- #include "SGame.h" //타겟한 대상이 친구인지 알아보기 위한 함수를 위해서 추가 -N4- #include "SGameSystem.h" #include "SGameWorld.h" #include "CInput.h" #include "KUIControlStatic.h" #include #include #include "SkillEx.h" #include "EqExprFunctions.h" // #2.1.2.12 #include "SContents.h" // sonador #2.1.24 #include "SAutoToolTip.h" // floyd 2009. 12. 22 #include "SUILazyTooltip.h" #include "SGameWorldKeymapping.h" //sfreer 2009.03.17 #include "SGameLobbyDefine.h" #include "SDebug_Util.h" // 2010.05.14 - prodongi #include "SCreatureEnhanceDB.h" // 2010.07.27 - prodongi //#include "SUIUtil.h" #include "StringDBHelper.h" /// 2011.03.22 - prodongi #include "commonutil.h" /// 2011.11.24 - servantes #include "EqExpr.h" /// 2012.01.02 - prodongi #include "SGameInterface.h" ///2012. 2. 21 - marine #include "SUIPartyTypes.h" #include "SCommandSystem.h" #include "SUIChattingWnd.h" #include "SSKillSlot.h" extern struct USER_INFO g_UserInfo; extern SGameSystem* g_pCurrentGameSystem; extern SBotManager* g_pSBotMng; extern void MsgSplit( const char* szMsg, std::vector& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false ); const int c_MaxPoint = 5; int last_skill_request_time = 0; int delay_after_skill_request = 200; namespace { const float c_fItemSellRatio = 0.25f; // 상점판매가 1/4 로 변경. kappamind 09.03.11 const float c_fItemSellOrigRatio = 1.0f; // sonador 3.4.4 환금성 아이템 거래 관련 수정 const DWORD c_dwClientInfoSavePeriod = 600000; const short c_nCreatureRankOffSet = 17; const char* c_szClientInfoLinefeed = "|"; const char* c_szQuickSlotInfoHeaderOld = "QS="; const char* c_szQuickSlotInfoHeaderNew = "QS2="; const char* c_szQuickSlotInfoDivision = ","; // 크리처 퀵슬롯 const char* c_szCreautreQuickSlotHeader = "CQS="; // 키맵핑관련 cline_info에 저장을 위한것. const char* c_szKeymappingHeader = "KMT="; const char* c_szKeymapping2Header = "KMT2="; const char* c_szKeymappingDivision = ","; //채팅모드관련 const char* c_szEnterchatHeader="ENTERCHATMODE="; const char* c_szEnterchat2Header="ENTERCHATMODE2="; //키맵핑,퀵슬롯등 클라이언트 데이터의 버전 const char *c_szClientDataVersionHeader="CLIENTVER="; enum KEYMAP_VERSION { BEGINER = 0, // Users who have started but never saved their key mappings BEFORE_EPIC8 = 1, // Users prior to EPIC 8 EPIC8_P1_01 = 2 , }; const int c_iClinetDataVersion = KEYMAP_VERSION::EPIC8_P1_01; const char* c_szItemTooltip_Name = "#@itemname@#"; const char* c_szItemTooltip_LimitLevel = "#@limit_level@#"; const char* c_szItemTooltip_RecommendLevel = "#@recommend_level@#"; const char* c_szItemTooltip_JobDepth = "#@job_depth@#"; const char* c_szItemTooltip_Endurance = "#@endurance@#"; const char* c_szItemTooltip_AdditionalItemEffect = "#@additional_item_effect@#"; // Fraun Sky Accessories 7/12/2025 const char* c_szItemTooltip_AwakenOption = "#@itemawakeningtooltip@#"; const char* c_szItemTooltip_RandomOption = "#@itemRandomOptionToolTip@#"; int GetItemAddPoint( const ItemBaseEx_info * pItemBase, int nType, unsigned char byEnhance ) { float fAddPoint = 0.0f; if( byEnhance > 0 ) { const std::vector< ItemEnhanceEffectBase >& enhance_list = GetItemDB().Find( pItemBase->nEnhanceID ); auto pos = enhance_list.begin(); auto end = enhance_list.end(); for( ; pos != end; ++pos ) { const ItemEnhanceEffectBase& ee = (*pos); if( ee.effect_id != nType ) continue; for( unsigned char i = 0; i < byEnhance && i < _countof( ee.value ); ++i ) { fAddPoint += ee.value[i]; } } } return int(fAddPoint); } }; std::string GetCutTimeString( float f_Time, int nCutCnt/*1*/ ) { std::string strTime, strTemp; if( f_Time <= 0.0f ) return strTime; int nDay(0), nHour(0), nMin(0), nSec(0); if( f_Time >= 86400 ) { nDay = f_Time/86400; f_Time -= 86400*nDay; } if( f_Time >= 3600 ) { nHour = f_Time/3600; f_Time -= 3600*nHour; } if( f_Time >= 60 ) { nMin = f_Time/60; f_Time = f_Time - 60*nMin; } nSec = f_Time; int nAddCnt(0); if( nDay ) { nAddCnt++; strTime += CStringUtil::StringFormat( "%d%s", nDay, S(7026) ); if( nCutCnt == nAddCnt ) return strTime; } if( nHour ) { nAddCnt++; if( !strTime.empty() ) strTime += " "; strTime += CStringUtil::StringFormat( "%d%s", nHour, S(7023) ); if( nCutCnt == nAddCnt ) return strTime; } if( nMin ) { nAddCnt++; if( !strTime.empty() ) strTime += " "; strTime += CStringUtil::StringFormat( "%d%s", nMin, S(7024) ); if( nCutCnt == nAddCnt ) return strTime; } if( nSec ) { nAddCnt++; if( !strTime.empty() ) strTime += " "; strTime += CStringUtil::StringFormat( "%d%s", nSec, S(7025) ); if( nCutCnt == nAddCnt ) return strTime; } return strTime; } SUIDisplayInfo::SUIDisplayInfo() : m_RaidMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::RAID_MGR ) ) ) , m_PartyMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PARTY_MGR )) ) , m_GuildMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILD_MGR )) ) , m_FriendMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::FRIEND_MGR )) ) , m_CutMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CUT_MGR )) ) , m_TradeMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::TRADE_MGR )) ) , m_StorageMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::STORAGE_MGR )) ) , m_MotionMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::MOTION_MGR )) ) , m_PlayerInfoMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PLAYERINFO_MGR )) ) , m_InventoryMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::INVENTORY_MGR )) ) , m_CreatureSlotMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESLOT_MGR )) ) , m_SkillSlotMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::SKILLSLOT_MGR )) ) , m_CreatureSkillSlotMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESKILLSLOT_MGR )) ) , m_GuildDataMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILDDATA_MGR )) ) , m_PetMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PET_MGR )) ) , m_pSkillTooltipComposer( 0 ) // sonador 10.4.1 스킬 툴팁 리뉴얼 , m_pAutoToolTip( 0 ) // floyd 2009. 12. 22 , m_bControlPush( false ) //servantes 2010.10.25 , m_bAltPush(false) // AziaMafia Zentrix Alt { InitData(); // sonador 10.4.1 스킬 툴팁 리뉴얼 // initialize skill subject // #2.1.2.12 m_pSkillSubject = new rp::CSkillExSubject(); m_pSkillSubject->appendExpression( "(" , new rp::fx_expr::OpenGroup() ); m_pSkillSubject->appendExpression( ")" , new rp::fx_expr::CloseGroup() ); m_pSkillSubject->appendExpression( "+" , new rp::fx_expr::Add() ); m_pSkillSubject->appendExpression( "-" , new rp::fx_expr::Sub() ); m_pSkillSubject->appendExpression( "*" , new rp::fx_expr::Mul() ); m_pSkillSubject->appendExpression( "/" , new rp::fx_expr::Div() ); m_pSkillSubject->appendExpression( "&" , new rp::fx_expr::Attach() ); m_pSkillSubject->appendExpression( "," , new rp::fx_expr::Delimiter() ); m_pSkillSubject->appendExpression( "if" , new rp::fx_expr::If() ); m_pSkillSubject->appendExpression( "int" , new rp::fx_expr::Int() ); m_pSkillSubject->appendExpression( "float" , new rp::fx_expr::Float() ); /// 2011.04.26 - prodongi m_pSkillSubject->appendExpression( "absfloat" , new rp::fx_expr::AbsFloat() ); m_pSkillSubject->appendExpression( "signedfloat" , new rp::fx_expr::SignedFloat() ); /// 2011.04.14 - prodongi m_pSkillSubject->appendExpression( "signedint" , new rp::fx_expr::SignedInt() ); /// 2011.03.17 - prodongi m_pSkillSubject->appendExpression( "absint" , new rp::fx_expr::AbsInt() ); /// 2011.04.22 - prodongi m_pSkillSubject->appendExpression( "signedif" , new rp::fx_expr::SignedIf() ); /// 2011.03.22 - prodongi m_pSkillSubject->appendExpression( "onesignedif" , new rp::fx_expr::OneSignedIf() ); /// 2011.04.13 - prodongi m_pSkillSubject->appendExpression( "unsignedif" , new rp::fx_expr::UnSignedIf() ); /// 2011.04.11 - prodongi m_pSkillSubject->appendExpression( "$" , new rp::expr_functions< rp::fx_expr::numeric_t >::StringDb() ); m_pSkillSubject->appendExpression( "rep" , new rp::expr_functions< rp::fx_expr::numeric_t >::Replace() ); m_pSkillSubject->appendExpression( "tenacitydb.nameid" , new rp::expr_functions< rp::fx_expr::numeric_t >::TenacityDb_NameId() ); m_pSkillSubject->appendExpression( "skilldb.nameid" , new rp::expr_functions< rp::fx_expr::numeric_t >::SkillDb_NameId() ); /// 2011.04.27 - prodongi m_pSkillSubject->appendExpression( "itemdb.item" , new rp::expr_functions< rp::fx_expr::numeric_t >::ItemDb_Item() ); m_pSkillSubject->appendExpression( "itemdb.nameid" , new rp::expr_functions< rp::fx_expr::numeric_t >::ItemDb_NameId() ); /// 2011.03.17 - prodongi m_pSkillSubject->appendExpression( "racename" , new rp::expr_functions< rp::fx_expr::numeric_t >::RaceName() ); m_pSkillSubject->appendExpression( "attributename" , new rp::expr_functions< rp::fx_expr::numeric_t >::AttributeName() ); m_pSkillSubject->appendExpression( "descentname" , new rp::expr_functions< rp::fx_expr::numeric_t >::DescentName() ); m_pSkillSubject->appendExpression( "bitsetname_a" , new rp::expr_functions< rp::fx_expr::numeric_t >::BitSetNameA() ); m_pSkillSubject->appendExpression( "bitsetname_b" , new rp::expr_functions< rp::fx_expr::numeric_t >::BitSetNameB() ); m_pSkillSubject->appendVariable( "fx.v1" , new rp::CSkillExFxValue( 0, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v2" , new rp::CSkillExFxValue( 1, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v3" , new rp::CSkillExFxValue( 2, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v4" , new rp::CSkillExFxValue( 3, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v5" , new rp::CSkillExFxValue( 4, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v6" , new rp::CSkillExFxValue( 5, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v7" , new rp::CSkillExFxValue( 6, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v8" , new rp::CSkillExFxValue( 7, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v9" , new rp::CSkillExFxValue( 8, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v10" , new rp::CSkillExFxValue( 9, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v11" , new rp::CSkillExFxValue( 10, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v12" , new rp::CSkillExFxValue( 11, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v13" , new rp::CSkillExFxValue( 12, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v14" , new rp::CSkillExFxValue( 13, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v15" , new rp::CSkillExFxValue( 14, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v16" , new rp::CSkillExFxValue( 15, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v17" , new rp::CSkillExFxValue( 16, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v18" , new rp::CSkillExFxValue( 17, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v19" , new rp::CSkillExFxValue( 18, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "fx.v20" , new rp::CSkillExFxValue( 19, m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "slv" , new rp::CSkillExValueSkillLv( m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "ep" , new rp::CSkillExValueEnhancePoint( m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "att" , new rp::CSkillExValueUserAttack( m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "mag" , new rp::CSkillExValueUserMagic( m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "cooltime" , new rp::CSkillExValueCoolTime( m_pSkillSubject ) ); /// 2011.04.26 cool time m_pSkillSubject->appendVariable( "sv.ca.basehp" , new rp::CSkillExSvValueConsumeBaseHP( m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "sv.ca.slvhp" , new rp::CSkillExSvValueConsumeSlvHP( m_pSkillSubject ) ); m_pSkillSubject->appendVariable( "mp" , new rp::CSkillExValueMP( m_pSkillSubject ) ); /// 2011.05.19 cost_mp + slv * cost_mp_per_skl - prodongi m_pSkillSubject->appendVariable( "castingdelay" , new rp::CSkillExValueCastingDelay( m_pSkillSubject ) ); /// 2011.05.19 delay_cast + slv * delay_cast_per_skl - prodongi m_pSkillSubject->appendVariable( "maxmp" , new rp::CSkillExValueMaxMP( m_pSkillSubject ) ); /// 2011.05.27 cost_mp + slv * cost_mp_per_skl - prodongi m_pSkillSubject->appendVariable( "curmp" , new rp::CSkillExValueCurMP( m_pSkillSubject ) ); /// 2011.05.27 cost_mp + slv * cost_mp_per_skl - prodongi // initialize skill tooltip composer m_pSkillTooltipComposer = new rp::CSkillTooltip(); m_pSkillTooltipComposer ->append( "#@level@#" , new rp::CSkillLvDeco() ) ->append( "#@attribute_icon@#" , new rp::CSkillAttributeIconDeco() ) ->append( "#@use_hp@#" , new rp::CSkillHpDeco() ) ->append( "#@mp@#" , new rp::CSkillMpDeco() ) ->append( "#@casting_time@#" , new rp::CSkillCastingTimeDeco( this ) ) ->append( "#@cooltime@#" , new rp::CSkillCoolTimeDeco(this)) /// 2011.06.20 - prodongi ->append( "#@aggro@#" , new rp::CSkillAggroDeco() ) ->append( "#@type@#" , new rp::CSkillAggroTypeDeco() ) ->append( "#@critical_percentage@#" , new rp::CSkillCriticalBonusDeco() ) ->append( "#@skill_enhance@#" , new rp::CSkillEnhanceDeco() ) ->append( "#@decrease_mp@#" , new rp::CSkillImproveMpCostDeco() ) ->append( "#@decrease_casting_time@#" , new rp::CSkillImproveCastingTimeDeco( this ) ) ->append( "#@decrease_cooltime@#" , new rp::CSkillImproveCoolTimeDeco( this ) ) ->append( "#@add_hit@#" , new rp::CSkillImproveHitBonusDeco() ) ->append( "#@add_aggro@#" , new rp::CSkillImproveAggroDeco() ) ->append( "#@skill_pattern_ability@#" , new rp::CSkillFxDeco( m_pSkillSubject ) ) ->append( "#@skill_grant_ability@#" , new rp::CSkillStateFxDeco( m_pSkillSubject, this ) ) // 2010.05.17 - prodongi ->append( "#@skill_passive_ability@#" , new rp::CSkillPassiveFxDeco( m_pSkillSubject, this ) ); //->append( "#@skill_enhance_ability@#", new rp::CSkillEnDeco( m_pSkillSubject ) ); // #2.1.2.12 m_pAutoToolTip = new rp::CAutoToolTip(); // floyd 2009. 12. 22 } SUIDisplayInfo::~SUIDisplayInfo() { ClearQuickSlotsAll(); SAFE_DELETE(m_pBackupedQuickSlot); SAFE_DELETE( m_pDragInfo ); //for( int i(0); i last_time ) { last_time = dwTime; // Inside here, processing entire quickslots menu for(int i = SLOT1_01; i <= SLOT8_12; i++) { if(GetGameKeymapping().GetHotKeyState(i) == KEYSTATE::DOWN) { int nslot = i - SLOT1_01; const SUIQuickSlotInfo* pslot = GetQuickSlot( nslot ); if (pslot == NULL) continue; SUIQuickSlotSkillInfo * pskillinfo = (SUIQuickSlotSkillInfo *)pslot; if (pskillinfo->m_bEnable == FALSE) continue; UseSkill( pskillinfo->m_nSkillID, pskillinfo->m_nSkillLevel, pskillinfo->m_bPlayer, pskillinfo->m_hTarget ); } } } if( m_dwLastClientInfoSaveTime == 0 ) m_dwLastClientInfoSaveTime = dwTime; if( m_ExistEmptyItem.getReaminWaiting() ) // 2012.3.28 - marine QuickslotEmptyItemProcess(); // Save client info at regular intervals if( m_dwLastClientInfoSaveTime != 0 && c_dwClientInfoSavePeriod < (m_dwCurTime - m_dwLastClientInfoSaveTime) ) SaveActiveClientInfos(); } void SUIDisplayInfo::ProcMsgAtStatic( SGameMessage* pMsg ) { switch( pMsg->nType ) { case TMSG_REQ_CLOSE: { STMSG_REQ_CLOSE* pReqCloseMsg = (STMSG_REQ_CLOSE*)pMsg; if( !pReqCloseMsg->m_bByWndMsg ) // 윈도우메시지로부터 온 경우는 퀵슬롯 작동(alt+F4)탓에 막아버렸기 때문에 처리할 필요가 없다. SaveActiveClientInfos(); pMsg->bUse = true; } break; case TMSG_REQ_CLOSE_EX: { SaveActiveClientInfos(); pMsg->bUse = true; } break; case MSG_PROPERTY: { SMSG_PROPERTY* pPropertyMsg = (SMSG_PROPERTY*)pMsg; if( m_PlayerInfoMgr.IsLocalPlayer(pPropertyMsg->handle) ) { // 기존 나누기 전의 데이터 때문에 SMSG_PROPERTY::PROPERTY_CLIENT_INFO 메시지를 제일 처음 받아야 한다. if( pPropertyMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_CLIENT_INFO) { LoadClientInfo( pPropertyMsg->strValue ); } else if( pPropertyMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_QUICK_SLOT) { LoadQuickSlotInfo( pPropertyMsg->strValue ); } else if( pPropertyMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_CURRENT_KEY ) { LoadCurrentKeyInfo( pPropertyMsg->strValue ); } else if( pPropertyMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_SAVED_KEY ) //gmpbigsun(20130422): 유저키저장 //todo { LoadSavedKeyInfo( pPropertyMsg->strValue ); } } pMsg->bUse = true; } break; case MSG_ITEM_WEAR_INFO: case MSG_UPDATE_ITEM_COUNT: case MSG_ITEM_DESTROY: case MSG_ITEM_ERASE: case MSG_ITEM_INVEN: { // 2012. 3. 28 - marine 인벤토리에 아이템이 들어온 경우 퀵슬롯에 수량이 0인 아이템이 있을때 처리 if( pMsg->nType == MSG_ITEM_INVEN && m_ExistEmptyItem.getEmptyItemSize() ) { SMSG_ITEM_INVEN* pPropertyMsg = (SMSG_ITEM_INVEN*)pMsg; if(pPropertyMsg && pPropertyMsg->pItemInfo ) ChageToOrigianlItem(pPropertyMsg->pItemInfo->handle); } RefreshItemWeight(); RefreshItemQuickSlots(); pMsg->bUse = true; } break; case MSG_ITEM_COOL_TIME: { PostQuickSlotUpdateMsg(); } break; case MSG_GOLD_UPDATE: { // 금 소지량 업데이트 if( m_nOldGold == -1 ) m_nOldGold = m_PlayerInfoMgr.GetGold(); SetSysMsg( SYS_MSG_GET_RUPI ); pMsg->bUse = true; } break; case IMSG_HOTKEY_EX: { SIMSG_HOTKEY_EX* pHotKey = dynamicCast(pMsg); // 퀵슬롯 관련 단축키는 퀵슬롯 윈도우로 옮김. pMsg->bUse = true; } break; case MSG_ATTACK: { SMSG_ATTACK* pAttackMsg = (SMSG_ATTACK*)pMsg; if( pAttackMsg->attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_BOW || pAttackMsg->attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_CROSS_BOW ) { RefreshMotionQuickSlot( MOTION_ATTACK ); } pMsg->bUse = true; } break; case MSG_SKILL_EVENT: { SMSG_SKILL_EVENT* pSkillEvent = (SMSG_SKILL_EVENT*)pMsg; // 퀵슬롯 if( pSkillEvent->status_type == TS_SC_SKILL::FIRE ) // 쿨링 체크 시작 { RefreshSkillQuickSlot( pSkillEvent->skill_id ); //TODO : SGameInterface::ProcMsgAtStatic( SGameMessage* pMsg )로 옴겼음 //TODO : 내 스킬 만 메세지 보임. 추후에 길드, 파티원 메세지 추가 해야 할 듯. /* if( m_PlayerInfoMgr.IsLocalPlayer(pSkillEvent->caster) || m_PlayerInfoMgr.IsLocalPlayer(pSkillEvent->target) ) { if( pSkillEvent->fire.count > 0 ) { std::string strText; std::vector::iterator it; for( it = pSkillEvent->vSkillResult.begin(); it != pSkillEvent->vSkillResult.end(); it++ ) { strText = GetSkillDamageText( pSkillEvent->skill_id, &(*it), pSkillEvent->skill_level, pSkillEvent->caster, pSkillEvent->target, pSkillEvent->target_name.c_str() ); if( ::_stricmp( strText.c_str(), "empty" ) != 0 ) AddSystemMessage( strText.c_str() ); } } }*/ } else if( pSkillEvent->status_type == TS_SC_SKILL::CASTING ) { if( pSkillEvent->cast.nErrorCode == 0 ) // 캐스팅 성공 쿨링 시계 표시 100% RefreshSkillQuickSlot( pSkillEvent->skill_id ); } else if( pSkillEvent->status_type == TS_SC_SKILL::CANCEL ) { //TODO Cancel 처리 RefreshSkillQuickSlot( pSkillEvent->skill_id ); } else if( pSkillEvent->status_type == TS_SC_SKILL::CASTING_UPDATE ) { //TODO CASTING_UPDATE 처리 } else if( pSkillEvent->status_type == TS_SC_SKILL::REGION_FIRE ) { //TODO REGION_FIRE 처리 } else if( pSkillEvent->status_type == TS_SC_SKILL::COMPLETE ) { //TODO COMPLETE 처리 } pMsg->bUse = true; } break; case MSG_SKILLCARD_INFO: { //느리면, 개별 업데이트로 수정해야 함. RefreshAllQuickSlots(); pMsg->bUse = true; } break; case IMSG_UI_SKILL_TIME_UPDATE: { SIMSG_UI_SKILL_TIME_UPDATE* pSkillMsg = ( SIMSG_UI_SKILL_TIME_UPDATE* )pMsg; if( m_PlayerInfoMgr.IsLocalPlayer(pSkillMsg->m_hTarget) ) RefreshSkillQuickSlot( pSkillMsg->m_nSkillID ); pMsg->bUse = true; } break; case IMSG_UI_MOTION_TIME_UPDATE: { SIMSG_UI_MOTION_TIME_UPDATE* pMotionMsg = ( SIMSG_UI_MOTION_TIME_UPDATE* )pMsg; RefreshMotionQuickSlot( pMotionMsg->m_nMotionCommandID ); pMsg->bUse = true; } break; case IMSG_UI_TARGET_STAT: { SIMSG_UI_TARGET_STAT* pStatMsg = ( SIMSG_UI_TARGET_STAT* )pMsg; if( m_PlayerInfoMgr.IsLocalPlayer(pStatMsg->handle) ) { switch(pStatMsg->m_nMode) { case SIMSG_UI_TARGET_STAT::USE_EXP: { if( pStatMsg->m_nVar1 != -1 ) m_nDiffExp = pStatMsg->m_nVar1; if( pStatMsg->m_nVar2 != -1 ) m_nDiffJP = pStatMsg->m_nVar2; SetSysMsg(SYS_MSG_GET_EXP_JP); } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PCBANG: { SetBonusExpJpMsg(SYS_MSG_BONUS01, pStatMsg->m_nVar1, pStatMsg->m_nVar2, pStatMsg->m_nVar3 ); } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_STAMINA: { SetBonusExpJpMsg(SYS_MSG_BONUS02, pStatMsg->m_nVar1, pStatMsg->m_nVar2, pStatMsg->m_nVar3 ); } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PREMIUM_PCBANG: { SetBonusExpJpMsg(SYS_MSG_BONUS_DOUBLE, pStatMsg->m_nVar1, pStatMsg->m_nVar2, pStatMsg->m_nVar3 ); } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_OGOK:// 오곡크래커 관련 2009.04.14 sfreer { SetBonusExpJpMsg(SYS_MSG_BONUS_OGOK, pStatMsg->m_nVar1, pStatMsg->m_nVar2, pStatMsg->m_nVar3 ); } break; // 2010.10.01 - prodongi case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_SUPER_SAVE: { SetBonusExpJpMsg(SYS_MSG_BONUS_SUPER_SAVE, pStatMsg->m_nVar1, pStatMsg->m_nVar2, pStatMsg->m_nVar3 ); } break; } } } break; case IMSG_UI_RELOAD: { // 인벤/퀵슬롯/지속효과 모두 초기화 InitData(true); pMsg->bUse = true; } break; case MSG_ADDED_SKILL_LIST: //pMsg->bUse = true; //break; case MSG_SKILL_LIST: { // 퀵슬롯 RefreshAllQuickSlots(); pMsg->bUse = true; } break; case MSG_LOGIN: { static bool g_PrintLoginMsg = false; if(!g_PrintLoginMsg) //이 메시지는 로그인시 단 한번만 출력되어야 할 메시지 이다. 2009.05.06 sfreer { AddSystemMessage( GetStringDB().GetString(1126), 99 ); // Gm never ask blah-blah (Welcoming message in the chat) g_PrintLoginMsg = true; } pMsg->bUse = true; } break; } } /* bool SUIDisplayInfo::StartMsg() { }*/ bool SUIDisplayInfo::InitData( bool bReLoad ) { m_dwCurTime = 0; m_dwLastClientInfoSaveTime = 0; m_nDiffJP = 0; m_nDiffExp = 0; m_nOldGold = money_t( -1 ); m_hPartyHandle = 0; //m_CurrentButtonState = QUICKSLOT_DEFAULT; if( bReLoad ) SAFE_DELETE( m_pDragInfo ); m_pDragInfo = NULL; // 퀵슬롯 if( bReLoad ) { ClearQuickSlotsAll(); SAFE_DELETE(m_pBackupedQuickSlot); } //for( int nBtn( 0 ); nBtn < QUICKSLOT_BTN_MAXCOUNT; ++nBtn ) //for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) //m_pQuickSlots[ nBtn ][ nSlot ] = NULL; for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) m_pQuickSlots[ nSlot ] = NULL; m_pBackupedQuickSlot=NULL; if( !bReLoad ) m_pGameManager = NULL; return true; } void SUIDisplayInfo::RefreshGaugeAndStatic( KUIControlGauge* pGaugeControl, int nCurrent, int nMax, int nPer, DWORD dwFillTime ) { if( pGaugeControl == NULL ) return; nMax = max( nMax, nCurrent ); nCurrent = max( nCurrent, 0 ); pGaugeControl->SetMax( DWORD(nMax) ); pGaugeControl->SetGauge( DWORD(nCurrent), dwFillTime ); } void SUIDisplayInfo::RefreshGaugeAndStaticByPercentage( class KUIControlGauge* pGaugeControl, int nPer, DWORD dwFillTime ) // #2.3.1.31 { if( pGaugeControl == NULL ) return; int nCurrent = max( 0, min( 100, nPer ) ); pGaugeControl->SetMax( DWORD(100) ); pGaugeControl->SetGauge( DWORD(nCurrent), dwFillTime ); } ////////////////////////////////////////////////////////////////////////// // 메시지 출력 관련 void SUIDisplayInfo::AddCommandMessage( const char* szMessage ) { SMSG_CHATTING ChatMsg; ChatMsg.szSender = ""; ChatMsg.nChatType = CHAT_COMMAND; ChatMsg.strText = szMessage; m_pGameManager->ProcMsgAtStatic( &ChatMsg ); } // Fraun performance tweak (removing useless string group) void SUIDisplayInfo::AddSystemMessage( const char* szMessage, int nChatTyp /*= CHAT_SYSTEM*/ ) { SMSG_CHATTING ChatMsg; if (nChatTyp < 0) { ChatMsg.nChatType = CHAT_SYSTEM; } else { switch( nChatTyp ) { case 0 : ChatMsg.nChatType = CHAT_SYSTEM; break; //misc 0 : 무조건 나와야 하고, 사용자가 임의로 껐다 켰다 할 수 없음 case 1 : ChatMsg.nChatType = CHAT_EXP; break; //경험치 1 case 2 : ChatMsg.nChatType = CHAT_COMMUNITY; break; //커뮤니티 2 case 3 : ChatMsg.nChatType = CHAT_DAMAGE; break; //기본데미지 3 case 4 : ChatMsg.nChatType = CHAT_EXT_DAMAGE; break; //스킬데미지 4 case 5 : ChatMsg.nChatType = CHAT_ITEM; break; //아이템관련 5 case 6 : ChatMsg.nChatType = CHAT_BATTLE; break; //전투상황 6 case 7 : ChatMsg.nChatType = CHAT_SUMMON; break; //크리처관련 7 case 99 : ChatMsg.nChatType = CHAT_ETC; break; //기타 99 case 255: ChatMsg.nChatType = CHAT_SYSTEM; break; default : ChatMsg.nChatType = CHAT_SYSTEM; } } ChatMsg.szSender.clear(); // Fraun performance tweak ChatMsg.strText = szMessage; m_pGameManager->ProcMsgAtStatic( &ChatMsg ); } ////////////////////////////////////////////////////////////////////////// // 공통 사용 함수 /// 2011.02.27 jpToString 함수로 대체 /* const char* SUIDisplayInfo::GetJP( int* nJP ) { if( *nJP == 0 ) return NULL; /// 2010.12.21 메가 단위는 고려가 안되어 있는 것 같다 - prodongi /* // 메가 단위 체크 if( *nJP > c_nJPMLimit ) { *nJP /= 1000000; return "
M"; } // 키로 단위 체크 else if( *nJP > c_nJPKLimit ) { *nJP /= 1000; return "
K"; } */ /* // 키로 단위 체크 /// 2011.01.18 - prodongi if( *nJP > c_nJPKLimit ) { *nJP /= 1000; return "K"; } return NULL; } */ /* return value 1: 자기자신 2: 파티원 3: 던전시즈 중 길드원 4: NPC 5: 소환크리처 6: 파티원 크리처 7: 던전시즈 중 길드원 크리처*/ //Handle에 해당하는 대상이 친구인지 알아보는 함수 -N4- //평상시엔 파티워 아바타와 크리처 자신의 크리처, 던전 시즈중에는 길드원과 길드원의 크리처도 동료에 포함 int SUIDisplayInfo::IsFriend( AR_HANDLE Handle, unsigned char& rType ) { SGame* pGame(NULL); pGame = m_pGameManager->GetActiveGame(); if( pGame ) { SGameAvatarEx* localPlayer(NULL); localPlayer = g_pCurrentGameSystem->GetLocalPlayer(); SGameWorld* pWorld = (SGameWorld*)m_pGameManager->GetActiveGame(); bool bDungeonSiege(false); if( localPlayer ) { if( pWorld ) bDungeonSiege = pWorld->IsDungeonSiege(); } SGameAvatarEx* pAvatar(NULL); pAvatar = (SGameAvatarEx*)( pGame->GetGameObject(Handle) ); if( pAvatar ) { rType = pAvatar->GetObjType(); if( rType == TS_ENTER::GAME_PLAYER ) { if( pAvatar->IsLocalPlayer() ) return LocalPlayer; //현재 캐릭터가 자기자신인지 if( m_PartyMgr.IsExistMember( Handle ) ) return Party; //현재 캐릭터가 파티원인지 if( bDungeonSiege && m_GuildMgr.IsExistMember(Handle) ) return Guild; //현재 던전시즈 중이면서 길드원인지 } else if( rType == TS_ENTER::GAME_NPC ) { return NPC; } else if( rType == TS_ENTER::GAME_SUMMON ) { if( m_CreatureSlotMgr.IsExistSummonedCreature( Handle ) ) return Creature; //소환한 크리처인지 AR_HANDLE MasterHandle(NULL); MasterHandle = pAvatar->GetMaster(); if( m_PartyMgr.IsExistMember( MasterHandle ) ) return PartyCreature; //파티원의 크리처인지 if( bDungeonSiege && m_GuildMgr.IsExistMember(MasterHandle) ) return GuildCreature; //현재 던전시즈 중이면서 길드원 크리처 인지 } } } return enemy; } bool SUIDisplayInfo::ShowMobHPMP( AR_HANDLE hTarget ) { if( m_pGameManager == NULL || g_pCurrentGameSystem == NULL ) return true; SGameWorld* pWorld = (SGameWorld*)m_pGameManager->GetActiveGame(); if( pWorld == NULL ) return true; if( pWorld->IsDungeonSiege() == false ) return true; SGameAvatarEx* pLocalPlayer = g_pCurrentGameSystem->GetLocalPlayer(); if( pLocalPlayer == NULL ) return true; if( pLocalPlayer->GetStatus() & TS_ENTER::PlayerInfo::FLAG_GM ) return true; //GM이면 걍 보이기 SGameAvatarEx* pTarget = (SGameAvatarEx*)pWorld->GetGameObject( hTarget ); if( pTarget ) { if( pTarget->GetObjType() == TS_ENTER::GAME_MOB ) { bool bPlayerGuard = ( pLocalPlayer->GetStatus() & TS_ENTER::PlayerInfo::FLAG_DUNGEON_ORIGINAL_OWNER ) ? true : false; bool bTargetOwner = ( pTarget->GetStatus() & TS_ENTER::PlayerInfo::FLAG_DUNGEON_ORIGINAL_OWNER ) ? true : false; bool bTargetSieger = ( pTarget->GetStatus() & TS_ENTER::PlayerInfo::FLAG_DUNGEON_ORIGINAL_SIEGER ) ? true : false; if( bPlayerGuard ) //내가 주인이고 { if( bTargetOwner ) return true; //HP MP 보이기 if( bTargetSieger ) return false; //HP MP 숨기기 } else //내가 던전 주인이 아니고 { if( bTargetOwner ) //타겟이 상대편 소유주라면 return false; //HP MP 숨기기 if( bTargetSieger ) return true; //HP MP 보이기 } } } return true; } //TODO : int64 까지 들어옮... 수정 요망 float SUIDisplayInfo::GetPercent( int nCur, int nMax ) { if( nMax == 0 ) return 0.f; if( nCur >= nMax ) return 100.f; float fPer = static_cast(nCur)/static_cast(nMax)*100.f; fPer = min( fPer, 100.f ); return fPer; } void SUIDisplayInfo::GetPercentValue( int nCurValue, int nMaxValue, int* pOutExp, int* pOutRest ) { float fPer = GetPercent(nCurValue, nMaxValue); int nExp = static_cast(fPer); int nRest = static_cast(fPer*10)%10; nExp = min( nExp, 100 ); nExp = max( nExp, 0 ); nRest = min( nRest, 9 ); nRest = max( nRest, 0 ); *pOutExp = nExp; *pOutRest = nRest; } ////////////////////////////////////////////////////////////////////////// // 캐쉬아이템 창고 void SUIDisplayInfo::RequestTakeOutCashItem( unsigned int ItemUID, count_t count ) { SMSG_TAKEOUT_COMMERCIAL_ITEM msg; msg.commercial_item_uid = ItemUID; msg.count = count.getAmount(); m_pGameManager->ProcMsgAtStatic( &msg ); } ////////////////////////////////////////////////////////////////////////// // 창고 void SUIDisplayInfo::RequestStorageItem( AR_HANDLE hItem, count_t nValue, int nMode ) { SMSG_CHANGE_STORAGE msg; msg.hItem = hItem; msg.nCount = nValue; msg.nMode = nMode; m_pGameManager->ProcMsgAtStatic( &msg ); } //servantes 2010.10.15 void SUIDisplayInfo::ChangeStorageItem( AR_HANDLE hItem, bool bToStorage, count_t nItemCount ) //servantes 2010.10.15 { m_StorageMgr.SetDragItem(NULL); SInventorySlot* pSlot = NULL; if( bToStorage ) pSlot = m_InventoryMgr.GetItemInfo( hItem ); else pSlot = m_StorageMgr.GetItemInfo( hItem ); if( pSlot == NULL ) return; if( bToStorage ) { m_StorageMgr.SetDragItem(hItem); m_StorageMgr.SetMode(TS_CS_STORAGE::INVENTORY_TO_STORAGE); if( GetItemDB().IsJoin(pSlot->GetItemCode(), IsInstanceUnstackable( pSlot )) && pSlot->GetItemCount() > 1 ) m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORAGE, pSlot->GetItemCount(), SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); else { RequestStorageItem( hItem, count_t( 1 ), TS_CS_STORAGE::INVENTORY_TO_STORAGE ); if( ItemBase::WEAR_NONE != GetItemCurrentWearState( hItem ) ) UseOrEquipItem( hItem ); } } else { m_StorageMgr.SetDragItem(hItem); m_StorageMgr.SetMode(TS_CS_STORAGE::STORAGE_TO_INVENTORY); //servantes 2010.10.15 bool bJoin = GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable( pSlot ) ); count_t _Cnt = pSlot->GetItemCount(); if( bJoin && _Cnt > 0 ) // 일반 아이템일 경우 { count_t tCnt = count_t(0); if(nItemCount != 0) tCnt = nItemCount; else tCnt = pSlot->GetItemCount(); if(tCnt == 1) { RequestStorageItem( hItem, count_t( 1 ), TS_CS_STORAGE::STORAGE_TO_INVENTORY ); } else { if(m_bControlPush == true && nItemCount == 10 ) { RequestStorageItem( hItem, nItemCount, TS_CS_STORAGE::STORAGE_TO_INVENTORY ); } else if (m_bAltPush == true && nItemCount >= 1) { RequestStorageItem(hItem, nItemCount, TS_CS_STORAGE::STORAGE_TO_INVENTORY); } else { m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTNUMBER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORAGE, tCnt, SIMSG_UI_REQ_INPUTNUMBER::TYPE_NUMBER ) ); } } } else // 장비 품복 { RequestStorageItem( hItem, count_t( 1 ), TS_CS_STORAGE::STORAGE_TO_INVENTORY ); } } } ////////////////////////////////////////////////////////////////////////// // RAID void SUIDisplayInfo::RequestJoinRaidGuildInvite( bool bAccpet ) { SMSG_CHATTING_REQUEST msgChatReq; if( m_RaidMgr.GetPartyID() == 0 ) return; if( !bAccpet ) return; msgChatReq.strText = CStringUtil::StringFormat( "/rp_gjoin %d %d", m_RaidMgr.GetPartyID(), m_RaidMgr.GetPartyPassWord() ); m_pGameManager->ProcMsgAtStatic( &msgChatReq ); } void SUIDisplayInfo::RequestJoinRaidMercenaryInvite( bool bAccpet ) { SMSG_CHATTING_REQUEST msgChatReq; if( m_RaidMgr.GetMercenaryPartyID() == 0 ) return; if( !bAccpet ) return; msgChatReq.strText = CStringUtil::StringFormat( "/rp_mjoin %d %d", m_RaidMgr.GetMercenaryPartyID(), m_RaidMgr.GetMercenaryPartyPassWord() ); m_pGameManager->ProcMsgAtStatic( &msgChatReq ); } ////////////////////////////////////////////////////////////////////////// // 파티 void SUIDisplayInfo::RequestJoinInvitedParty( bool bAccpet ) { RequestJoinParty(bAccpet, "/pjoin"); } void SUIDisplayInfo::RequestJoinParty(bool accept, char const* token) { SMSG_CHATTING_REQUEST msgChatReq; if( m_PartyMgr.GetPartyID() == -1 ) return; msgChatReq.strText = accept ? CStringUtil::StringFormat( "%s %d %d", token, m_PartyMgr.GetPartyID(), m_PartyMgr.GetPartyPass() ) : CStringUtil::StringFormat( "%s %d", token, m_PartyMgr.GetPartyID() ); m_pGameManager->ProcMsgAtStatic( &msgChatReq ); } void SUIDisplayInfo::RequestArenaOpponentJoinInvitedParty(bool accept) { RequestJoinParty(accept, "/bp_ojoin"); } void SUIDisplayInfo::RequestArenaMemberJoinInvitedParty(bool accept) { RequestJoinParty(accept, "/bp_mjoin"); } void SUIDisplayInfo::RequestJoinInvitedGuild( bool bAccpet ) { SMSG_CHATTING_REQUEST msgChatReq; if( m_GuildMgr.GetGuildID() == -1 ) return; msgChatReq.strText = bAccpet ? CStringUtil::StringFormat( "/gjoin %d %d", m_GuildMgr.GetGuildID(), m_GuildMgr.GetGuildPass() ) : CStringUtil::StringFormat( "/gjoin %d", m_GuildMgr.GetGuildID() ); m_pGameManager->ProcMsgAtStatic( &msgChatReq ); } void SUIDisplayInfo::RequestDestroyParty( bool bAccept, bool bKick ) { if( GetGameOption().GetMessengerType() == 0 ) return; if( GetGameOption().GetMessengerType() == 1 ) return; if( !bAccept ) return; SMSG_CHATTING_REQUEST msg; msg.type = CHAT_NORMAL; if( GetGameOption().GetMessengerType() == 0/*TAB_PARTY*/ ) { if( bKick ) { msg.strText = "/pkick "; //스트링이 아니고 명령어 임. msg.strText += m_PartyMgr.GetSelectMember(); } else if( m_PartyMgr.IsExist() && m_PartyMgr.IsLeader() ) msg.strText = "/pdestroy"; //스트링이 아니고 명령어 임. else msg.strText = "/pleave"; //스트링이 아니고 명령어 임. } else if( GetGameOption().GetMessengerType() == 1/*TAB_GUILD*/ ) { if( bKick ) { msg.strText = "/gkick "; //스트링이 아니고 명령어 임. msg.strText += m_GuildMgr.GetSelectMember(); } else if( m_GuildMgr.IsExist() && m_GuildMgr.IsLeader() ) msg.strText = "/gdestroy"; //스트링이 아니고 명령어 임. else msg.strText = "/gleave"; //스트링이 아니고 명령어 임. } m_pGameManager->ProcMsgAtStatic( &msg ); } ////////////////////////////////////////////////////////////////////////// // 스킬 void SUIDisplayInfo::UseSkill( int nSkillID, int nLevel, bool bPlayer, AR_HANDLE hTarget ) { // AziaMafia FixSkill /* static float last_time = 0.0f; float cur_time(GetArTime()); float elapsed = cur_time - last_time; _oprint("ACTION: %d %f\n",nSkillID,elapsed); if (elapsed<20) return; // 스킬 사용 최소 0.2초 체크 추가가 필요할 것 같습니다. last_time = cur_time; */ if( bPlayer ) { // Skill - 4001: Cannot summon more than two if( nSkillID == 4001 ) if( m_CreatureSlotMgr.GetSummonedCreatureCount() > SCreatureSlotMgr::MAX_SUMMON_SLOT ) return; int nCooldown = ENV().GetInt("skill_cooldown_env", 80); if( m_SkillSlotMgr.IsExistSkill( nSkillID ) && ( m_SkillSlotMgr.GetLastTimeUsed() + nCooldown <= GetArTime() ) ) { m_SkillSlotMgr.SetLastTimeUsed(GetArTime()); _oprint("if( m_SkillSlotMgr.IsExistSkill( nSkillID ) )\n"); /// 2010.10.13 - prodongi SIMSG_UI_ACT_USESKILL msg; msg.nSkillID = nSkillID; msg.nLevel = nLevel; msg.summon_card_handle = m_CreatureSlotMgr.GetSelectedCreatureCard(); msg.caster_handle = m_PlayerInfoMgr.GetPlayerHandle(); bool regionTarget = false; SkillBaseEx* skillBase = GetSkillDB().GetSkillData(nSkillID); if (272 == skillBase->effect_type || 271 == skillBase->effect_type || 303 == skillBase->effect_type || 153 == skillBase->effect_type ) // 153 non-targeted charge { if (SkillBase::SKILL_TARGET_POSITION == skillBase->getTargetType()) { regionTarget = true; } } if (regionTarget) { msg.m_isRegionTarget = true; SGameWorld* gameWorld = dynamicCast(m_pGameManager->GetActiveGame()); gameWorld->activeRegionSkillTargetFx(msg); //if ( 153 == skillBase->effect_type ) gameWorld->activeReginSkillScaleFx( msg ); } else { msg.m_isRegionTarget = false; m_pGameManager->ProcMsgAtStatic(&msg); } } } else { // 소환된 크리처일 경우 //if( hTarget == NULL || m_CreatureSlotMgr.GetSelectSummonCreature() != hTarget ) return; if( hTarget == NULL || !m_CreatureSlotMgr.IsExistSummonedCreature(hTarget) ) { //_oprint("소환되지 않은 유닛의 스킬임.\n"); return; } if( m_CreatureSkillSlotMgr.IsExistSkill( nSkillID, hTarget ) ) { SIMSG_UI_ACT_USESKILL msg; msg.nSkillID = nSkillID; msg.nLevel = nLevel; msg.caster_handle = hTarget; m_pGameManager->ProcMsgAtStatic(&msg); } } } bool SUIDisplayInfo::UseSkillByToggle( int nSkillID, int nLevel, bool bPlayer, AR_HANDLE hTarget ) { // Let’s apply it only to creatures (players too, if needed later). //if( hTarget == NULL || m_CreatureSlotMgr.GetSelectSummonCreature() != hTarget ) return false; if( hTarget == NULL || !m_CreatureSlotMgr.IsExistSummonedCreature(hTarget) ) return false; if( m_CreatureSkillSlotMgr.IsExistSkill( nSkillID, hTarget ) ) { SIMSG_UI_ACT_USESKILL_BY_TOGGLE msg; msg.nSkillID = nSkillID; msg.nLevel = nLevel; msg.caster_handle = hTarget; m_pGameManager->ProcMsgAtStatic(&msg); return msg.bSucceed; } return false; } bool SUIDisplayInfo::CheckDamegeAggro( SkillBaseEx* s_data ) { int SkillTipe = s_data->GetEffectType(); if( SkillTipe == SkillBase::EF_ADD_HP || SkillTipe == SkillBase::EF_ADD_MP || SkillTipe == SkillBase::EF_ADD_SP || SkillTipe == SkillBase::EF_ADD_HP_MP || SkillTipe == SkillBase::EF_ADD_HP_MP_BY_SUMMON_DAMAGE || SkillTipe == SkillBase::EF_ADD_HP_MP_BY_SUMMON_DEAD || SkillTipe == SkillBase::EF_CORPSE_ABSORB || SkillTipe == SkillBase::EF_ADD_HP_MP_BY_STEAL_SUMMON_HP_MP ) return false; return true; } void SUIDisplayInfo::GetMp( std::string& str , SkillBaseEx* s_data, int nUseLevel ) { str = CStringUtil::StringFormat( "%d", s_data->GetCostMP(nUseLevel) ); } void SUIDisplayInfo::GetHp( std::string& str , SkillBaseEx* s_data, int nUseLevel ) { str = CStringUtil::StringFormat( "%d", s_data->GetCostHP(nUseLevel) ); } void SUIDisplayInfo::GetCastTime( std::string& str , SkillBaseEx* s_data, int nUseLevel ) { //시간을 시간, 분, 초로 나눠서 출력 float ar_CastTime = s_data->GetCastDelay(nUseLevel); if( ar_CastTime > 0 ) str = GetTimeString( ar_CastTime/100.0f ); } void SUIDisplayInfo::GetAggro( std::string& str, std::string& strtype , SkillBaseEx* s_data, int nUseLevel ) { int nHate = s_data->GetHate(nUseLevel); if( nHate ) str = CStringUtil::StringFormat( "%d", nHate ); else { str = CStringUtil::StringFormat( "%d", nHate ); if( CheckDamegeAggro( s_data ) ) strtype = S(7035); else strtype = S(7036); } } void SUIDisplayInfo::GetCritical( std::string& str, SkillBaseEx* s_data, int nUseLevel ) { int nCritical = s_data->GetCriticalBonus(nUseLevel); if( nCritical ) str = CStringUtil::StringFormat( "%d", nCritical ); } void SUIDisplayInfo::GetDecreaseMpCard( std::string& str , SkillBaseEx* s_data, int nEnhance ) { int mp( s_data->GetCostMPByEnhance(nEnhance) ); if( mp ) str = CStringUtil::StringFormat( "(%d)", mp ); } void SUIDisplayInfo::GetDecreaseCastingCard( std::string& str , SkillBaseEx* s_data, int nEnhance, int nUseLevel ) { float ar_CastTime = s_data->GetCastDelay(nUseLevel); float casting( s_data->GetCastDelayByEnhance(nEnhance) ); if( casting ) str = "("+GetTimeString( ar_CastTime/100*casting )+")"; } void SUIDisplayInfo::GetDecreaseCoolTimeCard( std::string& str , SkillBaseEx* s_data, int nEnhance ) { long ar_CoolTime( s_data->GetCoolTime() ); /// 2011.04.27 AR_TIME -> long - prodongi float cooltime( s_data->GetCoolTimeByEnhance(nEnhance) ); if( cooltime ) str = "("+GetTimeString( ar_CoolTime/100*cooltime )+")"; } void SUIDisplayInfo::GetHitBonusCard( std::string& str , SkillBaseEx* s_data, int nEnhance ) { int hitbonus( s_data->GetHitBonusByEnhance(nEnhance) ); if( hitbonus ) str = CStringUtil::StringFormat( "(+%d)", hitbonus ); } void SUIDisplayInfo::GetAddAggroCard( std::string& str , SkillBaseEx* s_data, int nEnhance ) { int aggro( s_data->GetHateByEnhance(nEnhance) ); if( aggro ) str = CStringUtil::StringFormat( "(+%d)", aggro ); } //스킬 상세 툴팁정보 만드는 함수 -N4- std::string SUIDisplayInfo::GetSkillTooltipText( int nSkillID, int nUseLevel, bool bDetail, bool bNext, bool bUseCreatureAttribute ) { SkillBaseEx* skillData = GetSkillDB().GetSkillData( nSkillID ); if( skillData == NULL ) return std::string( "" ); // sonador 10.4.1 스킬 툴팁 리뉴얼 rp::CSkillEx skillEx( skillData ); skillEx.level( nUseLevel ); //스킬에 카드로 업글을 한것이면 카드를 몇까지 업글했는지 얻어온다 if( !skillEx->IsPassive() ) { AR_HANDLE hCard = m_SkillSlotMgr.GetSkillCard( nSkillID ); if( hCard ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hCard ); skillEx.enhance( pSlot->GetEnhance() ); } } if( bUseCreatureAttribute ) { const SCreatureSlot* CreatureSlot = m_CreatureSlotMgr.GetCreatureSlot( m_CreatureSlotMgr.GetSelectedCreature() ); if( CreatureSlot ) { const SCreatureStat* CreatureStat = CreatureSlot->GetCreatureStat( SCreatureSlot::TYPE_SELF ); const SCreatureStat* CreatureItemStat = CreatureSlot->GetCreatureStat( SCreatureSlot::TYPE_ITEM ); if( CreatureStat && CreatureItemStat ) { skillEx.userAttribute( CreatureStat->GetAttribute(), CreatureItemStat->GetAttribute() ); skillEx.setMaxMP(CreatureSlot->getMaxMP()); /// 2011.05.27 - prodongi skillEx.setCurMP(CreatureSlot->getMP()); } } } else { skillEx.userAttribute( m_PlayerInfoMgr.GetPlayerInfo().GetAttribute(), m_PlayerInfoMgr.GetPlayerInfo().GetItemAttribute() ); skillEx.setMaxMP(m_PlayerInfoMgr.GetMaxMP()); /// 2011.05.27 - prodongi skillEx.setCurMP(m_PlayerInfoMgr.GetMP()); } std::string tooltip = GetStringDB().GetString( skillEx->nTooltip_id ); // make skill tooltip string which use current level if( bDetail ) tooltip += "#@skill_pattern_ability@##@skill_grant_ability@#"; // 2010.05.17 - prodongi if (bDetail) tooltip += "#@skill_passive_ability@#"; m_pSkillTooltipComposer->compose( skillEx, tooltip ); if ( g_GMDEV ) tooltip += CStringUtil::StringFormat("
[ %d ]
",nSkillID).c_str(); // add skill tooltip string which use next level if( bDetail && bNext && this->GetAbleUpMaxLevel( m_PlayerInfoMgr.GetPlayerInfo(), nSkillID, nUseLevel ) > nUseLevel ) { /// 2011.04.22 - prodongi if (!isLastBR(tooltip.c_str())) { tooltip += "
"; } skillEx.level( nUseLevel + 1 ); std::string nextTip = "#@skill_pattern_ability@##@skill_grant_ability@#"; nextTip += "#@skill_passive_ability@#"; /// 2011.04.27 빠져 있어서 추가함 - prodongi m_pSkillTooltipComposer->compose( skillEx, nextTip ); if( !nextTip.empty() ) { tooltip += S( 1623 ); /// 2011.04.27 - prodongi if (!isFirstBR(nextTip.c_str())) { tooltip += "
"; } tooltip += nextTip; } /// 2011.04.22 - prodongi if (!isLastBR(tooltip.c_str())) { tooltip += "
"; } } return tooltip; } void SUIDisplayInfo::GetNextSkillMp( std::string& strMp, std::string& strEnhance, SkillBaseEx* s_data, int nUseLevel ) { //캐스팅과 엠소모는 다음 스킬레벨에서 변화하지 않아도 출력해야 하기 때문에 체크를 안한다 int nextMp(0); nextMp = s_data->GetCostMP(nUseLevel+1); strMp = CStringUtil::StringFormat( "MP %d", nextMp ); if( !strEnhance.empty() ) strMp += (" <#17f39c>"+strEnhance+"<#ffeab1>"); } void SUIDisplayInfo::GetNextSkillCasting( std::string& strCast, std::string& strEnhance, SkillBaseEx* s_data, int nUseLevel ) { float ar_NextCastTime(0.f); ar_NextCastTime= s_data->GetCastDelay(nUseLevel+1); if( ar_NextCastTime > 0.f ) { strCast = GetTimeString( ar_NextCastTime/100.0f ); if( !strEnhance.empty() ) strCast += (" <#17f39c>"+strEnhance+"<#ffeab1>"); } } void SUIDisplayInfo::GetNextSkillAggro( std::string& strAggro, std::string& strEnhance, SkillBaseEx* s_data, int nUseLevel ) { int Aggro(0); int nextAggro(0); Aggro = s_data->GetHate(nUseLevel); nextAggro = s_data->GetHate(nUseLevel+1); if( Aggro != nextAggro ) { if( nextAggro ) { strAggro += SR(7027, "#@aggro_point@#", nextAggro); if( !strEnhance.empty() ) strAggro += (" <#17f39c>"+strEnhance+"<#ffeab1>"); } else { std::string strNextAggro; if( CheckDamegeAggro( s_data ) ) { strNextAggro = S(7035); strNextAggro += " "; strNextAggro += ConvertNumString(nextAggro); } else { strNextAggro = S(7036); strNextAggro += " "; } strAggro += SR(7027, "#@aggro_point@#", strNextAggro.c_str()); strAggro += "%"; if( !strEnhance.empty() ) strAggro += (" <#17f39c>"+strEnhance+"%<#ffeab1>"); } } } void SUIDisplayInfo::GetNextSkillCri( std::string& strCri, std::string& strEnhance, SkillBaseEx* s_data, int nUseLevel ) { int Cri(0); int nextCri(0); Cri = s_data->GetCriticalBonus(nUseLevel); nextCri = s_data->GetCriticalBonus(nUseLevel+1); if( Cri != nextCri ) { strCri += SR(7028, "#@cri_per@#", nextCri); strCri += "
"; if( !strEnhance.empty() ) strCri += (" <#17f39c>"+strEnhance+"<#ffeab1>"); } } int SUIDisplayInfo::GetAbleUpMaxLevel( SPlayerInfo& pPlayerInfo, int nSkillID, int nUseLevel ) { int maxLv( 0 ); int JobID( 0 ); JobID = pPlayerInfo.GetJobID(); //현재 직업의 아이디 const JobInfoEx* pJobDB = GetJobDB().GetJobData( JobID ); if( pJobDB == NULL ) { return maxLv; } maxLv = GetSkillTreeDB().GetSkillMaxLevel( pJobDB->skill_tree_id, nSkillID ); //현재 직업에 스킬이 있으면 maxLv을 얻어온다 if( maxLv == 0 ) //현재 직업스킬이 아니면 { for( int i(0); i<3; ++i ) { JobID = pPlayerInfo.GetOldJobID( i ); pJobDB = GetJobDB().GetJobData( JobID ); if( pJobDB != NULL ) { maxLv = GetSkillTreeDB().GetSkillMaxLevel( pJobDB->skill_tree_id, nSkillID ); //과거 직업에서 maxLv를 얻어온다 if( maxLv > 0 ) break; } } } if( JobID == 0 ) //크리처이니 캐릭터의 잡아이디가 0이다 { AR_HANDLE hCreature = m_CreatureSlotMgr.GetSelectedCreature(); if( hCreature ) { int i = m_CreatureSlotMgr.GetEquipedCardIndexByCreature( hCreature ); const SCreatureInfo* pInfo = m_CreatureSlotMgr.GetCreatureInfo( m_CreatureSlotMgr.GetEquipedCreature(i) ); if( pInfo ) { std::vector vIDList; GetCreatureDB().GetEvolveID( pInfo->GetID(), vIDList ); //진화전의 크리처 아이디도 얻어온다 maxLv = 0; const std::vector< SkillTreeEx >* pSkillTreeList; for( int i(0); iskill_tree_id ); ++i ) { if( pSummonDB->skill_tree_id[i] == 0 ) continue; pSkillTreeList = GetSkillTreeDB().GetSkillTreeData( pSummonDB->skill_tree_id[i] ); if( !pSkillTreeList ) continue; SkillTreeEx skillTree; std::vector< SkillTreeEx >::const_iterator it = pSkillTreeList->begin(); while( it != pSkillTreeList->end() ) { skillTree = *it; if( skillTree.skill_id == nSkillID && skillTree.jop_lv <= pInfo->GetLevel() ) { if( skillTree.max_skill_lv > nUseLevel ) //여기 걸리면 다음스킬을 찍어줘야하는 것이니 break; { maxLv = skillTree.max_skill_lv; break; } } ++it; } if( maxLv ) break; } if( maxLv ) break; } vIDList.clear(); } } } return maxLv; } std::string SUIDisplayInfo::GetTimeString( float f_Time, int cnt/*1*/, bool bCut/*false*/ ) const { std::string strTime, strTemp; if( f_Time == 0.0f ) return strTime; if( f_Time < 0 ) { f_Time *= -1; strTime = "-"; } if( f_Time >= 86400 ) { int day = f_Time/86400; strTemp += CStringUtil::StringFormat( "%d%s", day, S(7026) ); f_Time -= 86400*day; } if( !(bCut && !strTemp.empty()) && f_Time >= 3600 ) { if( !strTemp.empty() ) strTemp += " "; int hour = f_Time/3600; strTemp += CStringUtil::StringFormat( "%d%s", hour, S(7023) ); f_Time -= 3600*hour; } if( !(bCut && !strTemp.empty()) && f_Time >= 60 ) { if( !strTemp.empty() ) strTemp += " "; int min = f_Time/60; strTemp += CStringUtil::StringFormat( "%d%s", min, S(7024) ); f_Time -= 60*min; } if( f_Time == 0.0f ) //시간이나 분은 있지만 초는 0일때의 예외처리부분 { if( strTime == "-" ) strTime.clear(); strTime += strTemp; return strTime; } if( !strTemp.empty() ) strTemp += " "; strTime += strTemp; if( !(bCut && !strTemp.empty()) ) { if( cnt == 0 ) { f_Time += 0.5f; return strTime += CStringUtil::StringFormat( "%d%s", (int)f_Time, S(7025) ); } int n_Time = f_Time; if( f_Time-n_Time > 0 ) //소숫점 자리가 있는지 체크하는 부분 { // int i(1); int sq(10); //지금은 소숫점 한자리뿐이니까 아래 주석처리 // for( i; iIsPassive() ) { AR_HANDLE hCard = m_SkillSlotMgr.GetSkillCard( nSkillID ); if( hCard ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hCard ); if( pSlot ) { return GetSkillTooltipText( nSkillID, nUseLevel ); } } } return GetSkillTooltipText( nSkillID, nUseLevel ); } */ std::string SUIDisplayInfo::GetSkillTreeToolTipText( const SkillTreeEx* pSkillTree , const bool bBaseLvCompare ) { std::string strToolTip( "" ); // 스킬 조건 bool bResult = false; strToolTip += S(6299); //"
"; strToolTip += S(6298); //"[ 필요조건 ]"; int nSkillID( NULL ); if( true == pSkillTree->bIsRandomSkill && // 랜덤 스킬이고 NULL != pSkillTree->nChangedSkillID ) // 바뀐 스킬 아이디가 있다면 { nSkillID = pSkillTree->nChangedSkillID; } else nSkillID = pSkillTree->skill_id; if( NULL == nSkillID ) { SDEBUGLOG( "[SUICreatureSkillFundWnd] 스킬 ID가 유효하지 않습니다. - 스킬트리 ID [ %d ]", pSkillTree->skill_tree_id ); assert( NULL ); return strToolTip; } // { [sonador] if( bBaseLvCompare ) { SkillBaseEx* skillData = GetSkillDB().GetSkillData( nSkillID ); if( skillData && m_CreatureSkillSlotMgr.GetUseSkillLevel( nSkillID, m_CreatureSlotMgr.GetSelectedCreature() ) < ( pSkillTree->min_skill_lv - 1 ) ) { strToolTip += SR( 448, "#@skill_name@#", GetStringDB().GetString( skillData->GetNameID() ), "#@skill_level@#", pSkillTree->min_skill_lv - 1 ); bResult = true; } } // } for( int i = 0; i < 3; i++ ) { if( pSkillTree->need_skill_id[i] == 0 ) continue; else { SkillBaseEx* skillData = GetSkillDB().GetSkillData( pSkillTree->need_skill_id[i] ); if( skillData == NULL ) continue; if( m_SkillSlotMgr.GetBaseSkillLevel(pSkillTree->need_skill_id[i]) >= pSkillTree->need_skill_lv[i] ) // 조건 수락 { bResult = true; strToolTip += SR( 447, "#@skill_name@#", GetStringDB().GetString(skillData->GetNameID()), "#@skill_level@#", pSkillTree->need_skill_lv[i] ); strToolTip += GetStringDB().GetString(9501); continue; } bResult = true; strToolTip += SR( 448, "#@skill_name@#", GetStringDB().GetString(skillData->GetNameID()), "#@skill_level@#", pSkillTree->need_skill_lv[i] ); strToolTip += GetStringDB().GetString(9501); } } if( !bResult ) return "err"; return strToolTip; } ////////////////////////////////////////////////////////////////////////// // 조작명령 void SUIDisplayInfo::UseMotion( int nPos ) { if( !m_MotionMgr.IsEnableMotion(nPos) ) return; if( nPos == ID_BOOTH ) { // 노점 /* if( m_PlayerInfoMgr.GetPlayerInfo().GetLevel() < 10 ) { // 10렙 이하는 노점 KIN 메세지 AddSystemMessage( GetStringDB().GetString( 901 ), GetStringDB().GetGroupID( 901 ) ); // You must be Lv 10 or higher to open a store. } else { m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORE_HOST, true ) );*/ m_MotionMgr.UseMotion(nPos); // } } else if( nPos == ID_TRADE ) // 트레이드 { if( !m_PlayerInfoMgr.IsTargetPlayer( m_PlayerInfoMgr.GetPlayerHandle() ) ) { SMSG_TRADE* pMsg = new SMSG_TRADE; pMsg->target_player = m_PlayerInfoMgr.GetTarget(); pMsg->mode = TS_TRADE::REQUEST_TRADE; pMsg->rq_mode = true; m_pGameManager->PostMsgAtDynamic( pMsg ); } else // 타겟 지정해달라 메시지 SetSysMsg( SYS_MSG_TRADE_NOT_TRADETARGET ); } else if( nPos == ID_PARTY_CREATE ) //파티 생성 { m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY_CREATE, true ) ); } else if( nPos == ID_PARTY_INVITE ) //파티 초대 { //타겟이 있으므로 파티 초대 메세지 보낸다. if( m_PlayerInfoMgr.GetTarget() ) { SMSG_PARTY_COMMAND* pMsg = new SMSG_PARTY_COMMAND; pMsg->mode = SMSG_PARTY_COMMAND::PARTY_INVITE; m_pGameManager->PostMsgAtDynamic( pMsg ); } else { //이름 입력 창 뜬다. m_pGameManager->PostMsgAtDynamic( new SMSG_SEND_DATA( 0, "req_invite" ) ); m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTTEXT( SIMSG_UI_REQ_INPUTTEXT::USAGE_PARTY, SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY_MENU, S(6786), 6583, 1901 ) ); // [sonador][7.0.6] Mantis 0002624 } } //emotion else if( nPos == ID_HI ) AddCommandMessage( "/hi" ); else if( nPos == ID_BOW ) AddCommandMessage( "/greeting" ); else if( nPos == ID_HAPPY ) AddCommandMessage( "/laugh" ); else if( nPos == ID_SORROW ) AddCommandMessage( "/sadness" ); else if( nPos == ID_YES ) AddCommandMessage( "/yes" ); else if( nPos == ID_NO ) AddCommandMessage( "/no" ); else if( nPos == ID_BORING ) AddCommandMessage( "/boring" ); else if( nPos == ID_APOLOGIZE) AddCommandMessage( "/apology" ); else if( nPos == ID_CHEER ) AddCommandMessage( "/cheers" ); else if( nPos == ID_POUT ) AddCommandMessage( "/pish" ); else if( nPos == ID_DANCE ) AddCommandMessage( "/dance" ); else if( nPos == ID_CLAP ) AddCommandMessage( "/clap" ); else if( nPos == ID_ANGRY ) AddCommandMessage( "/rage" ); else if( nPos == ID_PROVOKE ) AddCommandMessage( "/makeangry" ); // AziaMafia ADD EMOTE else if (nPos == ID_TP) AddCommandMessage("/tp 0"); else if (nPos == ID_LOOT) AddCommandMessage("/loot"); else if (nPos == ID_TAME) AddCommandMessage("/tame"); else if (nPos == ID_BUFF) AddCommandMessage("/buff"); else if (nPos == ID_BUFFGUILD) AddCommandMessage("/gbuff 100"); else if (nPos == ID_TPTAMINGZONE) AddCommandMessage("/tp 5"); else if (nPos == ID_ATRADE) AddCommandMessage("/dontknow"); else { if( nPos == ID_COMBINE ) // 조합 m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE, true ) ); if ( nPos == ID_ATTACK || nPos == ID_CREATURE_ATTACK || nPos == ID_CREATURE_ALLATTACK ) // 일반공격시 자동타겟 { SGameWorld* gameWorld = dynamicCast(m_pGameManager->GetActiveGame()); SGameAvatarEx* pTarget; pTarget = g_pCurrentGameSystem->GetTarget(); // 현재 타겟을 얻어옵니다. if( GetGameOption().IsAutoTarget() && ( !pTarget || pTarget->IsDead() || !gameWorld->IsAttack( pTarget ) ) ) // 현재 타겟이 없거나, 타겟이 죽었거나, 공격할 수 없는 타겟이면 { // 타겟을 다시 지정합니다. pTarget = gameWorld->GetCommandSystem()->GetNextTarget( 360, gameWorld->GetResetTargetList() ); // 360은 c_nTARGET_MAX_LEN 대신 넣었습니다. if( pTarget ) g_pCurrentGameSystem->SetTarget( pTarget ); } } m_MotionMgr.UseMotion(nPos); } } ////////////////////////////////////////////////////////////////////////// // 트레이드 void SUIDisplayInfo::JoinTrade( bool bAccept ) { SMSG_TRADE* pMsg = new SMSG_TRADE; if( bAccept ) // 수락 { pMsg->mode = TS_TRADE::ACCEPT_TRADE; pMsg->target_player = m_PlayerInfoMgr.GetTradeTarget(); pMsg->rq_mode = true; pMsg->bLocalPlyaer = true; //자신이 수락 했을 경우 m_pGameManager->PostMsgAtDynamic( pMsg ); } else // 거절 { pMsg->mode = TS_TRADE::REJECT_TRADE; pMsg->target_player = m_PlayerInfoMgr.GetTradeTarget(); pMsg->rq_mode = true; pMsg->bLocalPlyaer = true; //자신이 거절 했을 경우 m_pGameManager->PostMsgAtDynamic( pMsg ); } } void SUIDisplayInfo::SetFreeze( bool bAccept ) { if( bAccept ) { SMSG_TRADE TradeMsg; TradeMsg.mode = TS_TRADE::FREEZE_TRADE; TradeMsg.rq_mode = true; TradeMsg.target_player = m_PlayerInfoMgr.GetTradeTarget(); m_pGameManager->ProcMsgAtStatic( &TradeMsg ); } } ItemBase::ItemWearType SUIDisplayInfo::GetItemCurrentWearState( const AR_HANDLE hItem ) const { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( hItem ); if( pSlot == NULL ) return ItemBase::WEAR_NONE; return ItemBase::ItemWearType(pSlot->GetPosition()); } // 2010.08.17 - prodongi //void SUIDisplayInfo::ReqBeltItem( bool bPutOn, AR_HANDLE hItem ) void SUIDisplayInfo::ReqBeltItem( bool bPutOn, AR_HANDLE hItem, int putSlot ) { if( !hItem ) return; /// 2011.05.16 - prodongi if( bPutOn && IsStoreItem( hItem ) ) //노점을 열고 등록중인데 등록한 물건을 사용하려고 하면 예외처리 { //S(902) 노점 개설 중에는 아이템을 장착/사용 할 수 없습니다. AddSystemMessage( S(902), 99 ); // You may not equip/use an item while your store is open return; } SIMSG_UI_ACT_INVENTORY invMsg; invMsg.m_nHandle = hItem; if( bPutOn ) invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_BELT_PUTON; else invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_BELT_PUTOFF; // 2010.08.17 - prodongi if (bPutOn && -1 == putSlot) invMsg.m_putBeltSlot = findEmptyBeltSlot(hItem); else invMsg.m_putBeltSlot = putSlot; m_pGameManager->ProcMsgAtStatic( &invMsg ); } bool SUIDisplayInfo::IsStoreItem( AR_HANDLE hItem ) { int StoreItemCount = SStoreMgr::GetInstance().GetListCount(); for( int i(0); iProcMsgAtStatic( &invMsg ); } //2012. 2. 20 - marine 거래, 노점, 상점, 경매장 이 열려있는 경우에 아이템 사용 금지 // 이 창들이 열려있는지 확인 bool SUIDisplayInfo::IsBlockedUsingItem() { return m_pGameManager->GetGameInterface()->IsAgainstUiOpen(); } void SUIDisplayInfo::UseOrEquipItem( AR_HANDLE hItem, AR_HANDLE hCreature, bool bSkillUnbind, bool bPosion ) { if( !hItem ) return; if( IsBlockedUsingItem() ) return; if( IsStoreItem( hItem ) ) //노점을 열고 등록중인데 등록한 물건을 사용하려고 하면 예외처리 { //S(902) 노점 개설 중에는 아이템을 장착/사용 할 수 없습니다. AddSystemMessage( S(902), 99); // You may not equip/use an item while your store is open return; } SIMSG_UI_ACT_INVENTORY invMsg; invMsg.m_nHandle = hItem; if( bSkillUnbind ) { invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_SKILLCARD_UNBIND; invMsg.m_TargetHandle = m_PlayerInfoMgr.GetPlayerHandle(); // 나만 가능 } else if( hCreature ) { invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_CREATURE_USE; invMsg.m_TargetHandle = hCreature; //선택된 크리쳐만 가능 } else { invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_USE; if( bPosion ) //물약 일 경우는 타겟이나, 나에게 사용. { invMsg.m_TargetHandle = m_PlayerInfoMgr.GetTarget() ? m_PlayerInfoMgr.GetTarget() : 0;//m_PlayerInfoMgr.GetPlayerHandle(); //타겟이 있으면, 타겟 설정, 없으면 로컬 플레이어 설정 // 현재 선택 된 타겟이 없다면 파티 핸들 삭제. kappamind, 2010.01.14 if( !m_PartyMgr.GetSelectMemberHandle() ) m_hPartyHandle = 0; //시야에 멀리 있는 파티원에게 아이템 사용 가능 if( invMsg.m_TargetHandle == 0 && m_hPartyHandle > 0 ) { invMsg.m_ItemUseTargetHandle = m_hPartyHandle; } } else invMsg.m_TargetHandle = 0;//m_PlayerInfoMgr.GetPlayerHandle(); //아닌거 모두 다 나한테 사용. } m_pGameManager->ProcMsgAtStatic( &invMsg ); } void SUIDisplayInfo::DiscardItem( AR_HANDLE hItem, count_t nCount/* = 1*/ ) { if( NULL != hItem ) { SIMSG_UI_ACT_INVENTORY invMsg; invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_DISCARD; invMsg.m_nHandle = hItem; invMsg.m_nCnt = nCount; m_pGameManager->ProcMsgAtStatic( &invMsg ); } } extern const char* g_szEmoticonFilter[]; std::string SUIDisplayInfo::GetItemName( AR_HANDLE handle ) const { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( handle ); if( pSlot ) return GetItemName(pSlot->GetItemCode(), true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag()); return ""; } // sonador 7.0.23 Mantis 0002812: [경매장] 불필요한 대장장이 Lv 표시 제거 요청 // sonador 7.0.28 카오스 스톤 Lv 표시 활성화 bool SUIDisplayInfo::IsEnhanceableItem( int itemID, const ItemBase* itemInfo ) { if( !itemInfo ) return false; if( ( itemInfo->WearType != ItemBase::WEAR_NONE || ( itemInfo->WearType == ItemBase::WEAR_NONE && itemID == 804000 ) ) && ( itemInfo->nGroup != ItemBase::GROUP_FACE && itemInfo->nGroup != ItemBase::GROUP_DECO ) ) return true; return false; } //------------------------------------------------------------------------------------------------------------ // 아이템 이름 얻기 //------------------------------------------------------------------------------------------------------------ std::string SUIDisplayInfo::GetItemName( int nItemID, bool bSysMsg, unsigned char byEnhance /* = 0 */, unsigned char byLevel /* = 1 */, XFlag xFlag /* = XFlag() */, bool bUseRank /* = false */, AR_HANDLE hItemHandle /* = 0 */, bool isQuestRewardItem /* = false */, TS_ITEM_BASE_INFO::LPRANDOM_OPTION const pRandomOption, /* = false */ int nAdditionalItemEffect /* = 0 */) const // Fraun Sky Accessories 7/12/2025 { std::string strItemName( "" ); // Fraun Sky Accessories 7/17/2025 (temporarily if here to change item name to + accordingly to sky item enhance) if (nAdditionalItemEffect > 0) { std::string itemAdditionalPlus = ""; static std::map> nSkyItemEffects; if (nSkyItemEffects.empty()) { nSkyItemEffects[110000] = std::pair(1, 70); // Strength nSkyItemEffects[110010] = std::pair(2, 70); // Strength nSkyItemEffects[110020] = std::pair(3, 70); // Strength nSkyItemEffects[110030] = std::pair(4, 70); // Strength nSkyItemEffects[110040] = std::pair(5, 70); // Strength nSkyItemEffects[110050] = std::pair(6, 70); // Strength nSkyItemEffects[110060] = std::pair(7, 70); // Strength nSkyItemEffects[110070] = std::pair(8, 70); // Strength nSkyItemEffects[110080] = std::pair(9, 70); // Strength nSkyItemEffects[110001] = std::pair(1, 71); // Vitality nSkyItemEffects[110011] = std::pair(2, 71); // Vitality nSkyItemEffects[110021] = std::pair(3, 71); // Vitality nSkyItemEffects[110031] = std::pair(4, 71); // Vitality nSkyItemEffects[110041] = std::pair(5, 71); // Vitality nSkyItemEffects[110051] = std::pair(6, 71); // Vitality nSkyItemEffects[110061] = std::pair(7, 71); // Vitality nSkyItemEffects[110071] = std::pair(8, 71); // Vitality nSkyItemEffects[110081] = std::pair(9, 71); // Vitality nSkyItemEffects[110002] = std::pair(1, 73); // Agility nSkyItemEffects[110012] = std::pair(2, 73); // Agility nSkyItemEffects[110022] = std::pair(3, 73); // Agility nSkyItemEffects[110032] = std::pair(4, 73); // Agility nSkyItemEffects[110042] = std::pair(5, 73); // Agility nSkyItemEffects[110052] = std::pair(6, 73); // Agility nSkyItemEffects[110062] = std::pair(7, 73); // Agility nSkyItemEffects[110072] = std::pair(8, 73); // Agility nSkyItemEffects[110082] = std::pair(9, 73); // Agility nSkyItemEffects[110003] = std::pair(1, 72); // Dexterity nSkyItemEffects[110013] = std::pair(2, 72); // Dexterity nSkyItemEffects[110023] = std::pair(3, 72); // Dexterity nSkyItemEffects[110033] = std::pair(4, 72); // Dexterity nSkyItemEffects[110043] = std::pair(5, 72); // Dexterity nSkyItemEffects[110053] = std::pair(6, 72); // Dexterity nSkyItemEffects[110063] = std::pair(7, 72); // Dexterity nSkyItemEffects[110073] = std::pair(8, 72); // Dexterity nSkyItemEffects[110083] = std::pair(9, 72); // Dexterity nSkyItemEffects[110004] = std::pair(1, 74); // Intelligence nSkyItemEffects[110014] = std::pair(2, 74); // Intelligence nSkyItemEffects[110024] = std::pair(3, 74); // Intelligence nSkyItemEffects[110034] = std::pair(4, 74); // Intelligence nSkyItemEffects[110044] = std::pair(5, 74); // Intelligence nSkyItemEffects[110054] = std::pair(6, 74); // Intelligence nSkyItemEffects[110064] = std::pair(7, 74); // Intelligence nSkyItemEffects[110074] = std::pair(8, 74); // Intelligence nSkyItemEffects[110084] = std::pair(9, 74); // Intelligence nSkyItemEffects[110005] = std::pair(1, 75); // Wisdom nSkyItemEffects[110015] = std::pair(2, 75); // Wisdom nSkyItemEffects[110025] = std::pair(3, 75); // Wisdom nSkyItemEffects[110035] = std::pair(4, 75); // Wisdom nSkyItemEffects[110045] = std::pair(5, 75); // Wisdom nSkyItemEffects[110055] = std::pair(6, 75); // Wisdom nSkyItemEffects[110065] = std::pair(7, 75); // Wisdom nSkyItemEffects[110075] = std::pair(8, 75); // Wisdom nSkyItemEffects[110085] = std::pair(9, 75); // Wisdom } std::map>::iterator skyIt = nSkyItemEffects.find(nAdditionalItemEffect); if (skyIt != nSkyItemEffects.end()) { itemAdditionalPlus += "[+"; itemAdditionalPlus += std::to_string(static_cast(skyIt->second.first)); itemAdditionalPlus += " "; itemAdditionalPlus += S(skyIt->second.second); itemAdditionalPlus += "] "; } strItemName += itemAdditionalPlus; } const ItemBaseEx_info* pItemBase( GetItemDB().GetItemData( nItemID ) ); if( NULL == pItemBase ) { SLOG( "[DisplayInfo] Cannot find item information" ); assert( pItemBase ); strItemName = "Unknown Name"; return strItemName; } // 랜덤 옵션 if( pItemBase->CheckFlag( ItemBase::FLAG_RANDOMIZABLE ) ) { if( pRandomOption && false == pRandomOption->IsHaveData() ) { strItemName.append( S( 690000047 ) /*[미확인]*/ ); strItemName.append( " " ); } } strItemName.append( GetStringDB().GetString( pItemBase->nNameId ) ); //804000->카오스 스톤, 미 장착아이템중 유일하게 레벨을 표시해야 하는 아이템, 따라서 그냥 카오스 스톤만 예외 처리를 한 것 if( GetItemDB().GetWearType( nItemID ) != ItemBase::WEAR_BAG_SLOT ) { if( IsEnhanceableItem( nItemID, pItemBase ) ) // sonador 3.7.1 - 가면&꾸미기 아이탬 강화레벨 표시 삭제 { if( pItemBase->nGroup == ItemBase::GROUP_SKILLCARD ) { if( 0 < byEnhance ) { if( bSysMsg ) strItemName = CStringUtil::StringFormat( "+%d ", byEnhance ) + strItemName; else strItemName = CStringUtil::StringFormat( "<#17f39c>+%d<#ffffff> ", byEnhance ) + strItemName; } } else { if( 0 < byEnhance ) strItemName = CStringUtil::StringFormat( "+%d ", byEnhance ) + strItemName; // enhance if( 0 < byLevel ) { strItemName += " "; if( GetItemDB().GetWearType( nItemID ) == ItemBase::WEAR_ARMULET && xFlag.IsOn( ItemInstance::ITEM_FLAG_EMPTY ) ) strItemName += S(93); else strItemName += CStringUtil::StringFormat( "%s%d", S( 9501 ), byLevel ); } } if( bUseRank ) { if( pItemBase->nGroup == ItemBase::GROUP_WEAPON || pItemBase->nGroup == ItemBase::GROUP_ARMOR || pItemBase->nGroup == ItemBase::GROUP_SHIELD || pItemBase->nGroup == ItemBase::GROUP_HELM || pItemBase->nGroup == ItemBase::GROUP_GLOVE || pItemBase->nGroup == ItemBase::GROUP_BOOTS || pItemBase->nGroup == ItemBase::GROUP_BELT || pItemBase->nGroup == ItemBase::GROUP_MANTLE || pItemBase->nGroup == ItemBase::GROUP_ACCESSORY ) { if( pItemBase->nRank >= 1 && pItemBase->nRank < 8 ) { std::string strRank = g_szEmoticonFilter[pItemBase->nRank-1]; strItemName = strRank + strItemName; } } } } } if( ItemBase::GROUP_SUMMONCARD == pItemBase->nGroup ) // 크리쳐 카드 { if( xFlag.IsOn( ItemInstance::ITEM_FLAG_SUMMON ) ) // 테이밍 되어 있는 경우 strItemName = "<#FFFF00>" + strItemName + "<#FFFFFF>"; else if (!isQuestRewardItem) // 2010.10.18 퀘스트 보상아이템은 테임이 안된 상태라도 "비어 있음" 문구 출력 안되도록 - prodongi strItemName += S( 23 /* 비어 있음*/ ); else __noop; } if( ItemBase::GROUP_PETCAGE == pItemBase->nGroup ) { if( xFlag.IsOn( ItemInstance::ITEM_FLAG_CAGE_HAS_PET ) ) { SGame* pGame = m_pGameManager->GetActiveGame(); DATA_PET* pPetData = pGame->IsLocalPetCage( hItemHandle ); if( pPetData ) { strItemName += " - '"; strItemName += pPetData->name; strItemName += "'"; } } } if( xFlag.IsOn( ItemInstance::ITEM_FLAG_FAILED ) ) // 강화 실패 작 { strItemName += " "; strItemName += S( 13 ); } return strItemName; } //------------------------------------------------------------------------------------------------------------------------------------ // 아이템 툴팁 텍스트 얻기 //------------------------------------------------------------------------------------------------------------------------------------ std::string SUIDisplayInfo::GetItemTooltipText( SInventorySlot* pItemSlot, bool bDetail, AR_HANDLE creatureHandle, bool isRClick ) { unsigned int nEndurancePer; // 헌터홀릭 포인트 카드일 경우 // 내구도를 포인트 점수로 처리. // 따라서 내구도를 percentage 로 나타내면 안된다. if( pItemSlot->GetItemCode() == 806808 ) { nEndurancePer = pItemSlot->GetEndurance(); } else { int nResult = pItemSlot->GetCrrEndurancePer(nEndurancePer); if( nResult != SInventorySlot::ENDURANCE_SUCCESS ) nEndurancePer = nResult; } // 사용자(플레이어)가 착용 중인 아이템인지 검사 // 2010.07.22 플레이어가 착용했을때와 크리쳐가 착용했을때를 구별- prodongi int hasEquipped = 0; if (pItemSlot->IsEquipItem() && !pItemSlot->IsStorageItem()) { if (!pItemSlot->IsSummonEquip()) hasEquipped = 1; else hasEquipped = 2; } return GetItemTooltipText( pItemSlot->GetItemCode(), bDetail, pItemSlot->GetEnhance(), pItemSlot->GetLevel(), pItemSlot->GetXFlag(), pItemSlot->GetItem()->remain_time, pItemSlot->GetItem()->socket, nEndurancePer, pItemSlot->GetHandle(), hasEquipped, pItemSlot->GetItem()->elemental_effect_type, pItemSlot->GetItem()->elemental_effect_remain_time, pItemSlot->GetItem()->elemental_effect_attack_point, pItemSlot->GetItem()->elemental_effect_magic_point, false, pItemSlot->GetItem()->ethereal_durability, pItemSlot->GetItem()->endurance, creatureHandle, pItemSlot->GetSummonID(), false, isRClick, pItemSlot->GetItemAppearance(), pItemSlot->GetAwakening(), pItemSlot->GetRandomOption(), pItemSlot->GetItem()->enhance_chance, pItemSlot->GetAdditionalItemEffect() // Fraun Sky Accessories 7/12/2025 ); } //------------------------------------------------------------------------------------------------------------------------------------ // 아이템 툴팁 텍스트 얻기 //------------------------------------------------------------------------------------------------------------------------------------ std::string SUIDisplayInfo::GetItemTooltipText( TS_ITEM_BASE_INFO* pItemBaseInfo, bool bDetail, bool bShop ) { unsigned int nEndurancePer; int nResult = SInventorySlot::GetCrrEndurancePer( pItemBaseInfo, nEndurancePer ); if( nResult != SInventorySlot::ENDURANCE_SUCCESS ) nEndurancePer = nResult; XFlag< int > xFlag; xFlag.CopyFrom( &pItemBaseInfo->Flag ); const ItemBaseEx_info* pIBInfo = GetItemDB( ).GetItemData( pItemBaseInfo->Code ); // 2010.06.10 상점아이템인지 아닌지에 따라서 내구도 참조를 틀리게 해줘야 된다 - prodongi int ethereal_durability = (bShop) ? pIBInfo->nEthereal_durability : pItemBaseInfo->ethereal_durability; int endurance = (bShop) ? pIBInfo->nEndurance : pItemBaseInfo->endurance; // tooltip 수정 // 2010.03.16: hunee return GetItemTooltipText( pItemBaseInfo->Code, bDetail, pItemBaseInfo->enhance, pItemBaseInfo->level, xFlag, pItemBaseInfo->remain_time, pItemBaseInfo->socket, nEndurancePer, 0, 0, pItemBaseInfo->elemental_effect_type, pItemBaseInfo->elemental_effect_remain_time, pItemBaseInfo->elemental_effect_attack_point, pItemBaseInfo->elemental_effect_magic_point, bShop, ethereal_durability, endurance, -1, pItemBaseInfo->summon_id, false, false, pItemBaseInfo->appearance_code, &pItemBaseInfo->awakenoption, &pItemBaseInfo->random_option, pItemBaseInfo->enhance_chance, pItemBaseInfo->nAdditionalItemEffect // Fraun Sky Accessories 7/12/2025 ); } //------------------------------------------------------------------------------------------------------------------------------------ // 아이템 툴팁 텍스트 얻기 //------------------------------------------------------------------------------------------------------------------------------------ std::string SUIDisplayInfo::GetItemTooltipText( int nItemID, bool bDetail, unsigned char byEnhance, /* = 0, */ unsigned char byLevel, /* = 1, */ XFlag xFlag, /* = XFlag() */ int nRemainTime, /* = 0, */ int* pLevel, /* = NULL, */ int Endurance, /* = 0, */ AR_HANDLE hItemHandle, /* = 0, */ int hasEquipped, /* = 0, */ char elemental_effect_type, /* = 0, */ int elemental_effect_remain_time, /* = 0, */ int elemental_effect_attack_point, /* = 0, */ int elemental_effect_magic_point, /* = 0, */ bool bShop, /* = false, */ int ethereal, /* = -1, */ int soulpw, /* = -1 */ AR_HANDLE creatureHandle, /* = 0, */ int nSummonID, /* = 0, */ bool isQuestRewardItem, /* = false, */ bool isRClick, /* = false, */ int nAppearanceItemID, /* = 0, */ TS_ITEM_BASE_INFO::AwakenOption* const pAwakenOption, /* = NULL */ TS_ITEM_BASE_INFO::LPRANDOM_OPTION const pRandomOption, /* = NULL */ short nEnhance_chance, /* = 0 */ int nAdditionalItemEffect /* = 0 */ // Fraun Sky Accessories 7/12/2025 ) const { const ItemBaseEx_info* pItemBase( GetItemDB().GetItemData( nItemID ) ); if( NULL == pItemBase ) return "Error_Item_ID"; string strTooltip( "" ); string strItemName( "" ); string strLevelLimit( "" ); string strAwakeningTooltip( "" ); bool bNextSTr(false); bool bAwakeningItem( false ); // 각성 아이템 인가? bool bIsRandomOptionItem( false ); // 랜덤 옵션 아이템 인가? bool bIsIdentifiedRandomOptionItem( false ); // 랜덤 옵션 아이템이라면 확인 되었는가? // 각성 체크 if( pAwakenOption ) { if( pAwakenOption->nValue[0] ) bAwakeningItem = true; } // 랜덤 옵션 체크 if( pItemBase->CheckFlag( ItemBase::FLAG_RANDOMIZABLE ) ) { bIsRandomOptionItem = true; if( pRandomOption && pRandomOption->IsHaveData() ) bIsIdentifiedRandomOptionItem = true; } #pragma region rnSUMMONCARD if( ItemBase::GROUP_SUMMONCARD == pItemBase->nGroup ) // 크리쳐 카드 { int nCreatureNameID = GetCreatureDB().GetTextID( nSummonID ); if( xFlag.IsOn( ItemInstance::ITEM_FLAG_SUMMON ) ) // 테이밍 되어 있는 경우 { if( pLevel ) { if ( g_GMDEV ) strTooltip = CStringUtil::StringFormat("[ summon : %d ]
",nSummonID).c_str(); strTooltip += ""; //휘귀도에 따른 랭크아이콘 switch( GetCreatureDB().GetRate( nSummonID ) ) { case SummonBase::RATE_BASIC: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet+0]; break; case SummonBase::RATE_NORMAL_BASIC: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet+1]; break; case SummonBase::RATE_SPECIAL_BASIC: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet+2]; break; case SummonBase::RATE_NORMAL_RARE: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet+3]; break; case SummonBase::RATE_SPECIAL_RARE: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet+4]; break; case SummonBase::RATE_UNIQUE: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet+5]; break; // AziaMAfia Pet Rarity case SummonBase::RATE_VERACRUZ: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet + 6]; break; case SummonBase::RATE_PHANTOM: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet + 7]; break; case SummonBase::RATE_AURA: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet + 8]; break; case SummonBase::RATE_SHINNY: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet + 9]; break; case SummonBase::RATE_GALAXY: strTooltip += g_szEmoticonFilter[c_nCreatureRankOffSet + 10]; break; } //오버 브리드 계산 //50, 70, 100 : 진화 레벨 상수 int nOverBreed = 0; if( pLevel[0+1] > SCreatureDB::EVOLUTION_LV2 ) nOverBreed = pLevel[0+1] - SCreatureDB::EVOLUTION_LV2; if( pLevel[1+1] > SCreatureDB::EVOLUTION_LV3 ) nOverBreed += pLevel[1+1] - SCreatureDB::EVOLUTION_LV3; if( nOverBreed ) strTooltip += CStringUtil::StringFormat( "<#FFFF00> +%d <#FFFFFF>", nOverBreed ); else strTooltip += " "; //기본 툴팁 strTooltip += GetItemName( nItemID, false, byEnhance, byLevel, xFlag ); const _SUMMON_INFO_FILE* pSummonInfo = GetCreatureDB().GetCreatureData( nSummonID ); if( pSummonInfo == NULL ) { char szErrorSummonIDMsg[64] = ""; s_sprintf( szErrorSummonIDMsg, _countof( szErrorSummonIDMsg ), "error_summon_id(%d)", nSummonID ); return szErrorSummonIDMsg; } //레벨 계산 if( pLevel[2+1] ) //2에 진화 레벨 { //'Lv'을 String DB 9501로 참조하도록 한다 2009.09.25. sfreer strTooltip += CStringUtil::StringFormat( " <#FFFF00>%s%d<#FFFFFF>", GetStringDB().GetString(9501), pLevel[2+1] ); const _SUMMON_INFO_FILE* pEvolveSummonInfo = GetCreatureDB().GetCreatureData( pSummonInfo->nEvolve_target ); if( pEvolveSummonInfo ) { pEvolveSummonInfo = GetCreatureDB().GetCreatureData( pEvolveSummonInfo->nEvolve_target ); if( pEvolveSummonInfo ) nCreatureNameID = pEvolveSummonInfo->name_id; } } else if( pLevel[1+1] ) //1에 성장 레벨 { //'Lv'을 String DB 9501로 참조하도록 한다 2009.09.25. sfreer strTooltip += CStringUtil::StringFormat( " <#FFFF00>%s%d<#FFFFFF>", GetStringDB().GetString(9501), pLevel[1+1] ); const _SUMMON_INFO_FILE* pEvolveSummonInfo = GetCreatureDB().GetCreatureData( pSummonInfo->nEvolve_target ); if( pEvolveSummonInfo ) nCreatureNameID = pEvolveSummonInfo->name_id; } else if( pLevel[0+1] ) //0에 기본 레벨 //'Lv'을 String DB 9501로 참조하도록 한다 2009.09.25. sfreer strTooltip += CStringUtil::StringFormat( " <#FFFF00>%s%d<#FFFFFF>", GetStringDB().GetString(9501), pLevel[0+1] ); if( bDetail ) { //무엇이 봉인된 카드 // 2010.06.24 - prodongi if (JOKER_CARD_ID == nItemID) { strTooltip += GetStringDB().GetString(pItemBase->nToolTipID); } else { strTooltip += "
"; strTooltip += SStringDB::ParseString( GetStringDB().GetString( 25 ), "#@creature_name@#", GetStringDB().GetString( nCreatureNameID ) ); if( pLevel[0+1] >= 60 || pLevel[1+1] >= 115 || pLevel[2+1] >= 150 ) strTooltip += "
"; } } } else { strTooltip = GetItemName( nItemID, false, byEnhance, byLevel, xFlag ); if( byLevel > 0 ) strTooltip += CStringUtil::StringFormat( " <#FFFF00>Lv%d<#FFFFFF>", byLevel ); strTooltip += "
"; strTooltip += SStringDB::ParseString( GetStringDB().GetString( 25 ), "#@creature_name@#", GetStringDB().GetString( nCreatureNameID ) ); } } else { if( !bDetail ) strTooltip = CStringUtil::StringFormat( "<#fbe6ad>%s<#ffffff>", GetItemName( nItemID, false ).c_str() ); else // 크리처 테이밍 할 수 있는 카드 strTooltip = SStringDB::ParseString( GetStringDB().GetString( GetItemDB().GetToolTipID( nItemID ) ) ); } if( nSummonID ) { strTooltip += "
"; strTooltip += GetStringDB().GetString( 26 ); int nRateStringID = (-1); switch( GetCreatureDB().GetRate( nSummonID ) ) { case SummonBase::RATE_BASIC: nRateStringID = 27; break; case SummonBase::RATE_NORMAL_BASIC: nRateStringID = 28; break; case SummonBase::RATE_SPECIAL_BASIC: nRateStringID = 29; break; case SummonBase::RATE_NORMAL_RARE: nRateStringID = 30; break; case SummonBase::RATE_SPECIAL_RARE: nRateStringID = 31; break; case SummonBase::RATE_UNIQUE: nRateStringID = 32; break; // AziaMafia Pet Rarity case SummonBase::RATE_VERACRUZ: nRateStringID = 2110000005; break; case SummonBase::RATE_PHANTOM: nRateStringID = 2110000006; break; case SummonBase::RATE_AURA: nRateStringID = 2110000007; break; case SummonBase::RATE_SHINNY: nRateStringID = 2110000008; break; case SummonBase::RATE_GALAXY: nRateStringID = 2110000009; break; } if( (-1) != nRateStringID ) strTooltip += GetStringDB().GetString( nRateStringID ); } if( xFlag.IsOn( ItemInstance::ITEM_FLAG_SUMMON ) && pLevel ) { if( pLevel[2+1] || pLevel[1+1] || pLevel[0+1] ) { //성장 상태 if( !bDetail ) strTooltip += ""; strTooltip += "
"; strTooltip += GetStringDB().GetString( 34 ); if( pLevel[2+1] ) //2에 진화 레벨 strTooltip += GetStringDB().GetString( 37 ); else if( pLevel[1+1] ) //1에 성장 레벨 strTooltip += GetStringDB().GetString( 36 ); else if( pLevel[0+1] ) //0에 기본 레벨 strTooltip += GetStringDB().GetString( 35 ); } else if( ItemBase::GROUP_SUMMONCARD == pItemBase->nGroup && pLevel[0+1] == 0 ) //Lv가 0이어도 테이밍된것이면 기본형 { strTooltip += "
"; strTooltip += GetStringDB().GetString( 34 ); strTooltip += GetStringDB().GetString( 35 ); } } // 2010.05.06 강화단계 - prodongi strTooltip += "
"; strTooltip += CStringUtil::StringFormat("%s : %d", S(6998), byEnhance); // 2010.05.14 강화 내구도 - prodongi if (byEnhance) { float maxDurability = (float)GetCreatureEnhanceDB().getCardDurability(byEnhance); float durability = ethereal; int dur = (int)((ethereal/maxDurability) * 100.0f); strTooltip += "
"; strTooltip += CStringUtil::StringFormat("%s : %d", S(7815), dur); } if( bDetail ) { // 아이템 이름 /// 2010.10.10 - prodongi strItemName = CStringUtil::StringFormat( "<#fbe6ad>%s<#ffffff>", GetItemName( nItemID, false, 0, 0, XFlag(), false, 0, isQuestRewardItem ).c_str() ); CStringUtil::ReplacePhrase( strTooltip, std::string( c_szItemTooltip_Name ), strItemName.c_str() ); } } #pragma endregion rnSUMMONCARD #pragma region rnSKILLCARD else if( ItemBase::GROUP_SKILLCARD == pItemBase->nGroup ) // 강화스킬카드 툴팁 { if( !bDetail ) strTooltip = CStringUtil::StringFormat( "%s", GetItemName( nItemID, false, byEnhance, byLevel, xFlag ).c_str() ); else strTooltip = GetCardSkillTooltip( nItemID, pItemBase->nSkillID, true, byEnhance, byLevel, xFlag ); } #pragma endregion rnSKILLCARD #pragma region rnRIDING else if( ItemBase::GROUP_RIDING == pItemBase->nGroup ) { strItemName = CStringUtil::StringFormat( "<#fbe6ad>%s<#ffffff>", GetItemName( nItemID, false, byEnhance, 0, xFlag, true ).c_str() ); if( !bDetail ) { strTooltip = strItemName; } else { strTooltip = GetStringDB().GetString( pItemBase->nToolTipID ); CStringUtil::ReplacePhrase( strTooltip, std::string( c_szItemTooltip_Name ), strItemName.c_str() ); } } #pragma endregion rnRIDING #pragma region rnNORMAL else // 일반 아이템 { if( xFlag.IsOn( ItemInstance::ITEM_FLAG_FAILED ) ) { strItemName = "<#ff0000>"; } else { if( 20 < byEnhance ) { strItemName = "<#FF8000>"; } else { strItemName = "<#fbe6ad>"; } } strItemName += CStringUtil::StringFormat( "%s<#ffffff>", GetItemName( nItemID, false, byEnhance, byLevel, xFlag, true, hItemHandle, false, pRandomOption, nAdditionalItemEffect).c_str() ); // Fraun Sky Accessories 7/17/2025 if( xFlag.IsOn( ItemInstance::ITEM_FLAG_FAILED ) ) { strItemName += "
"; strItemName += GetStringDB().GetString(14); } if( !bDetail ) { strTooltip = strItemName; } else { // 2012. 7. 30 - marine 형상변환 아이템의 경우 변환된 외형의 아이템이 무엇인지 표기를 해준다. std::string strAppearanceName = ""; if(nAppearanceItemID) { std::string appearanceName; std::string appearanceAll; appearanceName = GetItemName(nAppearanceItemID, false); appearanceAll = S(690000030); //#@lookchange@#로 형상 변환 CStringUtil::ReplacePhrase(appearanceAll, "#@lookchange@#", appearanceName); strAppearanceName += "
"; strAppearanceName += appearanceAll; } strTooltip = m_pAutoToolTip->CreateItemTooltipString( pItemBase, g_pCurrentGameSystem->GetLocalPlayer()->GetRace(), g_pCurrentGameSystem->GetLocalPlayer()->GetJobID(), strAppearanceName, bAwakeningItem, bIsRandomOptionItem, bIsIdentifiedRandomOptionItem, nAdditionalItemEffect); // Fraun Sky Accessories 7/12/2025 if ( g_GMDEV ) strItemName = strItemName + CStringUtil::StringFormat("
[ %d ]",nItemID).c_str(); CStringUtil::ReplacePhrase( strTooltip, std::string( c_szItemTooltip_Name ), strItemName.c_str() ); // [ 아이템 이름 ] ReplaceLimitLevelToolTip( strTooltip, pItemBase, g_pCurrentGameSystem->GetLocalPlayer()->GetLevel() ); // [ 제한 레벨 ] ReplaceRecommandLevelToolTip( strTooltip, pItemBase, byLevel ); // [ 권장 레벨 ] ReplaceJopDepthToolTip( strTooltip, pItemBase, g_pCurrentGameSystem->GetLocalPlayer()->GetJobID() ); // [ 착용가능 직업 ] // 성능 수치 string strOption( "" ); string strTempOption( "" ); string strKey( "" ); for( int nOption( 0 ); nOption < ItemBase::MAX_OPTION_NUMBER; ++nOption ) { strTempOption = "#@bitset_text@#"; int nType( 0 ); double dVar1( 0.0 ), dVar2( 0.0 ); // 기본 성능 if( GetItemDB().GetBaseVar( nItemID, nOption, nType, dVar1, dVar2 ) ) { float fPenaltyPercentage = BuildBaseTooltipValue( pItemBase, strTooltip, nType, dVar1, dVar2, byEnhance, byLevel, elemental_effect_attack_point, elemental_effect_magic_point, m_PlayerInfoMgr.GetPlayerInfo().GetLevel() ); } // 추가 성능 if( GetItemDB().GetOptionVar( nItemID, nOption, nType, dVar1, dVar2 ) ) { strKey = BuildOptionTooltipValue( strTempOption, nType, dVar1, dVar2, byEnhance, pLevel ); } if( !strKey.empty() ) { CStringUtil::ReplacePhrase( strTooltip, strKey.c_str(), strTempOption.c_str() ); } else { if( !strTempOption.empty() && strTempOption != "#@bitset_text@#" ) { if( !strOption.empty() ) strOption += "
"; strOption += strTempOption; } } } CStringUtil::ReplacePhrase( strTooltip, "#@bitset_text@#", strOption.c_str() ); if( bIsRandomOptionItem && // 랜덤 옵션 아이템이고 false == bIsIdentifiedRandomOptionItem ) // 미확인 된 아이템이라면, { return strTooltip; // 여기까지의 정보만 출력한다. } if( !bAwakeningItem && pItemBase->CheckFlag( ItemBase::FLAG_ENHANCE ) == false ) // 각성되지 않은 아이템이고 조합 불가 아이템이 아니라면 { if( pItemBase->nGroup == ItemBase::GROUP_WEAPON || pItemBase->nGroup == ItemBase::GROUP_SHIELD ) { strTooltip += "
<#00AEEF><$2110000107:><#ffffff>"; // "
<#00AEEF><$1251:각성가능> = <$10705001:각성가능><#ffffff>" } if (pItemBase->nClass == ItemBase::CLASS_EARRING || pItemBase->nClass == ItemBase::CLASS_RING || pItemBase->nClass == ItemBase::CLASS_ARMULET ) { strTooltip += "
<#00AEEF><$2110000108:><#ffffff>"; //
<#00AEEF><$1251:각성가능> = <$10705003:각성가능><#ffffff> } if (pItemBase->nGroup == ItemBase::GROUP_ARMOR || pItemBase->nGroup == ItemBase::GROUP_HELM || pItemBase->nGroup == ItemBase::GROUP_GLOVE || pItemBase->nGroup == ItemBase::GROUP_BOOTS || pItemBase->nClass == ItemBase::CLASS_BELT) { strTooltip += "
<#00AEEF><$2110000109:><#ffffff>"; //
<#00AEEF><$1251:각성가능> = <$10705010:각성가능><#ffffff> } } // Fraun Sky Accessories 7/12/2025 ReplaceAdditionalItemEffectOptionTooltip( strTooltip, pItemBase, nAdditionalItemEffect, m_pAutoToolTip); ReplaceAwakenOptionToolTip( strTooltip, pItemBase, pAwakenOption, ethereal, bAwakeningItem, m_pAutoToolTip ); // [ 각성 ] ReplaceRandomOptionTooltip( strTooltip, pItemBase, pRandomOption, ethereal, bIsRandomOptionItem, bIsIdentifiedRandomOptionItem ); // [ 랜덤 옵션 ] CStringUtil::ReplacePhrase( strTooltip, c_szItemTooltip_Endurance, CStringUtil::StringFormat( "%d", Endurance ) ); // [ 내구도 ] // 아이템 특수 성능 툴팁, kappamind if( pItemBase->nEffectId ) { ReplaceEffectOptionTooltip( strTooltip, pItemBase, pItemBase->nEffectId, ethereal, true ); } int TypeID = IsEnhanceAddCapability(nItemID); if( TypeID ) { int nAddPoint(0); nAddPoint = GetItemAddPoint( pItemBase, TypeID, byEnhance ); if( nAddPoint ) { BuildEnhanceAddCapability( strTooltip, TypeID, nAddPoint, byEnhance ); } else { CStringUtil::ReplacePhrase( strTooltip, "#@add_ability@#", "" ); } } else CStringUtil::ReplacePhrase( strTooltip, "#@add_ability@#", "" ); std::string NextLevelTooltip; std::string NextEnhanceTooltip; std::string NextEnhanceAbilityTooltip; NextEnhanceAbilityTooltip = GetGenaralItemEnhanceAbilityTooltip(nItemID, byLevel, byEnhance, TypeID, elemental_effect_attack_point, elemental_effect_magic_point ); NextLevelTooltip = GetGenaralItemDetailTooltip(nItemID, byLevel, byEnhance, false, elemental_effect_attack_point, elemental_effect_magic_point); // AziaMafia Tooltip Fix / Opti /* if( !NextLevelTooltip.empty() ) { strTooltip += S(8000); strTooltip += NextLevelTooltip; } if(byEnhance) { NextEnhanceTooltip = GetGenaralItemDetailTooltip(nItemID, byLevel, byEnhance, true, elemental_effect_attack_point, elemental_effect_magic_point); if( !NextEnhanceTooltip.empty() ) { if( !NextLevelTooltip.empty() ) { int pos(-1); pos = strTooltip.rfind("
"); if( pos != -1 ) strTooltip.erase(pos, strTooltip.size()-1); } strTooltip += S(8001); strTooltip += NextEnhanceTooltip; if( !NextEnhanceAbilityTooltip.empty() ) strTooltip += NextEnhanceAbilityTooltip; } } */ if( bDetail && nItemID == 910009 && pLevel ) //귀환의 깃털 현재 예외처리 나중에 DB에 아이템 타입등으로 확인하게 수정할것 꼭 ~~~~~~~~~~~~~~!!!!!!!! { //int nX = pLevel[0]; //int nY = pLevel[1]; //int nLayer = pLevel[2]; int nLocationID = pLevel[3]; // 2010.08.05 - prodongi //int nTextID = GetWorldLocationDB().GetWLTextID( nLocationID ); int nTextID = GetWorldLocationDB().GetWLTextID( nLocationID, false ); if( nTextID > 0 ) { std::string strWorldLocationName = GetStringDB().GetString( nTextID ); CStringUtil::ReplacePhrase( strTooltip, "#@location_name@#", strWorldLocationName.c_str() ); } } if( !NextEnhanceAbilityTooltip.empty() || !NextLevelTooltip.empty() ||!NextEnhanceTooltip.empty() ) bNextSTr = true; } } #pragma endregion rnNORMAL if( ItemBase::GROUP_WEAPON == pItemBase->nGroup || ItemBase::GROUP_ARMOR == pItemBase->nGroup || ItemBase::GROUP_SHIELD == pItemBase->nGroup || ItemBase::GROUP_HELM == pItemBase->nGroup || ItemBase::GROUP_GLOVE == pItemBase->nGroup || ItemBase::GROUP_BOOTS == pItemBase->nGroup || // AziaMafia Fix Jewel ItemBase::GROUP_MANTLE == pItemBase->nGroup || ItemBase::GROUP_FACE == pItemBase->nGroup || ItemBase::GROUP_DECO == pItemBase->nGroup ) { if( bDetail ) { string strOptionVale( "" ); JewelTooltip( nItemID, pLevel, strOptionVale, Endurance, bShop, pRandomOption ); if( !strOptionVale.empty() ) { strTooltip += "
"; if( !bNextSTr ) strTooltip += "
"; strTooltip += strOptionVale; } } } // #2.1.2.6.1 if(( pItemBase->set_id ) && (bDetail)) { // // 현재 착용된 세트 아이템들의 조합를 만족하는 효과에 대해 툴팁을 만든다. // SSetItemEffectResourceDB::FoundResult sie_found; GetSetItemEffectResourceDB().Find( pItemBase->set_id, sie_found ); if( !sie_found.empty() ) { // // 현재 착용하고 있는 아이템중 툴팁을 표시할 아이템과 // 세트 아이디가 동일한 아이템의 세트 파트 아이디의 논리합을 구하자 // typedef std::vector< SInventorySlot* > EquippedItemContainer; EquippedItemContainer equippedItems; // 2010.07.22 - prodongi //m_InventoryMgr.GetEquipItemList( equippedItems ); if (1 == hasEquipped) m_InventoryMgr.GetEquipItemList( equippedItems ); else if (2 == hasEquipped) m_InventoryMgr.getCreatureEquipItemList(equippedItems, creatureHandle); std::vector vSetItemData; // 7랭크 셋트 아이템은 예외 처리 // 그외에 세트 아이템 목록을 저장한다. if( pItemBase->nRank != 7 ) { vSetItemData = GetItemDB().GetSetItemData( pItemBase->set_id ); } std::string setEquippedItems = ""; int setItemList[8] = { 4, 1, 8, 16, 32, 64, 512, 2048 }; int setItemCompositionFlag = 0; // 2010.07.22 - prodongi //if (bPlayerHasEquiped) // 착용한 아이템에 대한 상세설명일 경우 효과 플래그 체크 if (0 != hasEquipped) { for( EquippedItemContainer::iterator i = equippedItems.begin(); i != equippedItems.end(); ++i ) { const ItemBaseEx_info* info = GetItemDB().GetItemData( (*i)->GetItemCode() ); if( !info ) continue; if( info->set_id == pItemBase->set_id ) setItemCompositionFlag |= info->set_part_flag; } } // // 세트 이름 처리 // CStringUtil::ReplacePhrase( strTooltip, "#@setitem_name@#", GetStringDB().GetString( ( *sie_found.begin() )->text_id ) ); bool setItemEquipCheck = false; int stringId; if (0 != setItemCompositionFlag) { // 7랭크 예외 처리 if( pItemBase->nRank == 7 ) { // 셋트 아이템 목록중 착용 한 아이템과 착용 안한 아이템 색 구분 for( int n = 0; n < 8; ++n ) { for( EquippedItemContainer::iterator i = equippedItems.begin(); i != equippedItems.end(); ++i ) { const ItemBaseEx_info* info = GetItemDB().GetItemData( (*i)->GetItemCode() ); if( info ) { if ( info->set_id == pItemBase->set_id && (info->set_part_flag & setItemCompositionFlag)) { if( info->set_part_flag == setItemList[n] ) setItemEquipCheck = true; } else if( !setItemEquipCheck ) setItemEquipCheck = false; } } // 착용한 아이템의 스트링 아이디 얻어오기 ( 7랭크만 예외 처리 ) stringId = CheckEquippedItems( setItemList[n], pItemBase->set_id ); /// 2010.10.27 세트 아이템의 부위들이 어떻게 구성되어있는지 알 수 가 없기 때문에 0이면 해당되지 않는 부위라고 생각한다 - prodongi if (0 == stringId) { continue; } // 착용한 아이템은 활성화 if( setItemEquipCheck ) { setEquippedItems += "<#00ff00>"; setEquippedItems += "
"; setEquippedItems += GetStringDB().GetString( stringId ); } else { setEquippedItems += "<#808080>"; setEquippedItems += "
"; setEquippedItems += GetStringDB().GetString( stringId ); } setItemEquipCheck = false; } } // 7랭크를 제외한 세트 아이템 else { for( int n = 0; n < vSetItemData.size(); ++n ) { for( EquippedItemContainer::iterator i = equippedItems.begin(); i != equippedItems.end(); ++i ) { const ItemBaseEx_info* info = GetItemDB().GetItemData( (*i)->GetItemCode() ); if( info && info->set_id == vSetItemData[n]->set_id ) { if ( info->set_id == pItemBase->set_id && (info->set_part_flag & setItemCompositionFlag)) { if( info->set_part_flag == vSetItemData[n]->set_part_flag ) setItemEquipCheck = true; } else if( !setItemEquipCheck ) setItemEquipCheck = false; } } // 착용중이면 활성화 if( setItemEquipCheck ) { setEquippedItems += "<#00ff00>"; setEquippedItems += "
"; setEquippedItems += GetStringDB().GetString( vSetItemData[n]->nNameId ); } // 비활성화 else { setEquippedItems += "<#808080>"; setEquippedItems += "
"; setEquippedItems += GetStringDB().GetString( vSetItemData[n]->nNameId ); } setItemEquipCheck = false; } } } equippedItems.clear(); vSetItemData.clear(); // 세트 효과 처리 std::string setFxTooltip; int setEffectId = 0; bool SetItemAll; bool bItemEffect = true; for( SSetItemEffectResourceDB::FoundResult::iterator i = sie_found.begin(); i != sie_found.end(); ++i ) { const SetItemEffectResource* setFx = (*i); std::string fxTooltip; if ((NULL != setFx) && (true == setFx->isPartOfSetItemComposition( setItemCompositionFlag ))) { // 활성화된 세트아이템 효과 처리 fxTooltip = "<#00ff00>"; SetItemAll = true; } else { // 비활성화된 세트아이템 효과 처리 fxTooltip = "<#808080>"; SetItemAll = false; } fxTooltip += GetStringDB().GetString( setFx->tooltip_id ); // 성능 수치 std::string strOption; std::string strTempOption; std::string strAddEffect; std::string stdTempEffect; std::string strKey; for( int nOption( 0 ); nOption < ItemBase::MAX_OPTION_NUMBER; ++nOption ) { strTempOption = "#@bitset_text@#"; int nType; double dVar1, dVar2; // 기본 성능 nType = setFx->base_type[ nOption ]; dVar1 = setFx->base_var1[ nOption ]; dVar2 = setFx->base_var2[ nOption ]; float fPenaltyPercentage = BuildBaseTooltipValue( pItemBase, fxTooltip, nType, dVar1, dVar2, 0, byLevel, elemental_effect_attack_point, elemental_effect_magic_point, m_PlayerInfoMgr.GetPlayerInfo().GetLevel() ); // 추가 성능 nType = setFx->opt_type[ nOption ]; dVar1 = setFx->opt_var1[ nOption ]; dVar2 = setFx->opt_var2[ nOption ]; strKey = BuildOptionTooltipValue( strTempOption, nType, dVar1, dVar2, 0 ); if( !strKey.empty() ) { CStringUtil::ReplacePhrase( fxTooltip, strKey.c_str(), strTempOption.c_str() ); } else { if( ( !strTempOption.empty() && strTempOption != "#@bitset_text@#" ) || setFx->nEffectId ) { if( !strOption.empty() && bItemEffect ) strOption += "
"; // 셋트 아이템 특수 성능 툴팁 if( setFx->nEffectId ) { setEffectId = setFx->nEffectId; SItemEffectResourceDB::FoundResult ie_found; GetItemEffectResourceDB().Find( setFx->nEffectId, ie_found ); SItemEffectResourceDB::FoundResult::iterator iter; for( iter = ie_found.begin(); iter != ie_found.end(); ++iter ) { if(ie_found.size() > 0) { if( SetItemAll ) strAddEffect += "<#D600EA>"; // 셋트 아이템이 다 모였으면 활성화 else strAddEffect += "<#808080>"; // 셋트 아이템이 다 안모였으면 비활성화 if( bItemEffect ) strAddEffect += CStringUtil::StringFormat( "%s<#ffffff>", GetStringDB().GetString( (*iter)->tooltip_id ) ); else strAddEffect = ""; } else { _oprint("[%d] 세트아이디 정보를 읽지 못했습니다.\n",setEffectId); } } bItemEffect = false; } if( strcmp( strTempOption.c_str(), "#@bitset_text@#" ) ) strOption += strTempOption; if( !bItemEffect && stdTempEffect.empty() ) stdTempEffect += strAddEffect; } } } CStringUtil::ReplacePhrase( fxTooltip, "#@bitset_text@#", strOption.c_str() ); if( strOption.empty() ) fxTooltip = ""; fxTooltip += stdTempEffect; setFxTooltip += fxTooltip; } /// 2010.10.27 흰색이 없는 경우가 생김 - prodongi setFxTooltip += "<#FFFFFF>"; setFxTooltip += "
"; setEquippedItems += "<#FFFFFF>"; CStringUtil::ReplacePhrase( strTooltip, "#@setitem_part@#", setEquippedItems ); CStringUtil::ReplacePhrase( strTooltip, "#@setitem_fx@#", setFxTooltip ); } } if( nRemainTime > 0 ) //대여 아이템 { strTooltip += "
"; int nOur = (nRemainTime/60)/60; int nMin = (nRemainTime/60)%60; strTooltip += SStringDB::ParseString( GetStringDB().GetString( 87 ), "#@time@#", SStringDB::ToString( nOur ).c_str(), "#@min@#", SStringDB::ToString( nMin ).c_str() ); } if ( elemental_effect_type != 0 ) { strTooltip += "

"; switch ( elemental_effect_type ) { case 1 : strTooltip += "#@fx_fire@# "; break; case 2 : strTooltip += "#@fx_water@# "; break; case 3 : strTooltip += "#@fx_wind@# "; break; case 4 : strTooltip += "#@fx_earth@# "; break; case 5 : strTooltip += "#@fx_light@# "; break; case 6 : strTooltip += "#@fx_dark@# "; break; case 7 : strTooltip += "#@fx_fire2@# "; break; case 8 : strTooltip += "#@fx_water2@# "; break; case 9 : strTooltip += "#@fx_wind2@# "; break; case 10 : strTooltip += "#@fx_earth2@# "; break; case 11 : strTooltip += "#@fx_light2@# "; break; case 12 : strTooltip += "#@fx_dark2@# "; break; } if (elemental_effect_remain_time >= 0) { int nOur = (elemental_effect_remain_time/60)/60; int nMin = (elemental_effect_remain_time/60)%60; strTooltip += SStringDB::ParseString( GetStringDB().GetString( 87 ), "#@time@#", SStringDB::ToString( nOur ).c_str(), "#@min@#", SStringDB::ToString( nMin ).c_str() ); } /// 영구 아이템 else { strTooltip += S(690000031); } if ( bDetail ) { if ( elemental_effect_attack_point > 0 ) strTooltip += CStringUtil::StringFormat( "
<#FFF020><$690000033:부여석으로 인한 추가 물리 피해> +%d<#FFFFFF>", elemental_effect_attack_point ); if ( elemental_effect_magic_point > 0 ) strTooltip += CStringUtil::StringFormat( "
<#FFF020><$690000034:부여석으로 인한 추가 마법 피해> +%d<#FFFFFF>", elemental_effect_magic_point ); } } //내구도 관련 정보 추가 2010.01.15 sfreer /*#ifdef _DEV if(ethereal>=0) { size_t nCurrentPos = 0; size_t nFindPos = strTooltip.find( "#@Ethereal_Durability@#", 0 ); if( nFindPos == std::string::npos ) { _oprint("문제잇음"); strTooltip +="
강제출력
Ethereal_Durability:#@Ethereal_Durability@#
Ethereal_Durability_test:#@Ethereal_Durability_test@#
Soulstone_Durability_test:#@Soulstone_Durability_test@#
"; } else { _oprint("문제없음"); } } #endif*/ int nMaxDurability = pItemBase->nEthereal_durability; if (m_InventoryMgr.IsExistItem( hItemHandle )) nMaxDurability = m_InventoryMgr.GetItemInfo( hItemHandle )->getMaxEtherealDurability(); else if (m_StorageMgr.IsExistItem( hItemHandle )) nMaxDurability = m_StorageMgr.GetItemInfo( hItemHandle )->getMaxEtherealDurability(); /// 2010.11.10 원래 내구도는 상급 아이템만 출력되고, 상급 아이템은 상점에서 팔지 않고 있었다, /// 그런데 보스카드는 상급 아이템인데 아이템 상점에서 팔고 /// 나중에 다른 상급 아이템도 상점에서 팔 수 있을 것 같기 때문에 상점에서 파는 내구도 있는 아이템은 현재 내구도를 모두 max로 설정 - prodongi if (bShop) { std::string maxEtherealDurability = SStringDB::ToString( int(ceil((double)nMaxDurability /10000))); // 내구도 CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability@#", maxEtherealDurability.c_str() ); // 내구도 MAX CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability_Max@#", maxEtherealDurability.c_str() ); maxEtherealDurability = SStringDB::ToString( int(pItemBase->nEthereal_durability) ); // 내구도 세부 값 CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability_test@#", maxEtherealDurability.c_str() ); // 내구도 세부 값 MAX CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability_test_Max@#", maxEtherealDurability.c_str() ); } else { // 내구도 if(ethereal>=0) CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability@#", SStringDB::ToString( int(ceil((double)ethereal/10000)) ).c_str() ); else CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability@#", "0" ); // 내구도 MAX CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability_Max@#", SStringDB::ToString( int(ceil((double)nMaxDurability /10000)) ).c_str() ); // 내구도 세부 값 if(ethereal>=0) CStringUtil::ReplacePhrase( strTooltip,"#@Ethereal_Durability_test@#" , SStringDB::ToString( ethereal ).c_str() ); else CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability_test@#", "0" ); // 내구도 세부 값 MAX CStringUtil::ReplacePhrase( strTooltip, "#@Ethereal_Durability_test_Max@#", SStringDB::ToString( int(nMaxDurability) ).c_str() ); } // 영혼력 세부 값 if(soulpw>=0) CStringUtil::ReplacePhrase( strTooltip, "#@Soulstone_Durability_test@#", SStringDB::ToString( soulpw ).c_str() ); else CStringUtil::ReplacePhrase( strTooltip, "#@Soulstone_Durability_test@#", "0" ); // 영혼력 세부 값 MAX CStringUtil::ReplacePhrase( strTooltip, "#@Soulstone_Durability_test_Max@#", SStringDB::ToString( int(pItemBase->nEndurance) ).c_str() ); // 현재 0으로 나오고있음. db_item.rdb 확인필요. // 2010.06.21 남은 회복량 - prodongi CStringUtil::ReplacePhrase(strTooltip, "#@Recovery_Endurance@#", SStringDB::ToString(soulpw).c_str()); // 2010.06.21 남은 맥스 회복량 - prodongi CStringUtil::ReplacePhrase(strTooltip, " #@Recovery_Endurance_Max@#", SStringDB::ToString(int(pItemBase->nEndurance)).c_str()); /// 2011.03.28 - prodongi if (isRClick) { if( ItemBase::GROUP_SUMMONCARD == pItemBase->nGroup ) { strTooltip += "

<#b92c36>"; strTooltip += S(1153); } } if ( nEnhance_chance ) { strTooltip += CStringUtil::StringFormat( "
<#FFF020><$7000:추가 강화 성공 확률> : +%d.%d%%<#FFFFFF>", nEnhance_chance/10,nEnhance_chance%10 ); } nsl::uni::proc_korean_postfix( strTooltip ); return strTooltip; } void SUIDisplayInfo::SetComparableEquipItemSubTooltip( KUIControl* pIcon, SInventorySlot* pItem ) { if( pItem->IsEquipItem() == false ) { SetComparableEquipItemSubTooltip( pIcon, pItem->GetItemCode() ); } } void SUIDisplayInfo::SetComparableEquipItemSubTooltip( KUIControl* pIcon, int nItemID ) { SInventorySlot* pEquipSlot = m_InventoryMgr.GetComparableEquipItemInfo( nItemID, false ); if( pEquipSlot != NULL ) { rp::KLazyItemTooltip* pSubItemTooltip = new rp::KLazyItemTooltip( *this, pEquipSlot, true ); pIcon->AddLazySubTooltip( pSubItemTooltip ); } pEquipSlot = m_InventoryMgr.GetComparableEquipItemInfo( nItemID, true ); if( pEquipSlot != NULL ) { rp::KLazyItemTooltip* pSubItemTooltip = new rp::KLazyItemTooltip( *this, pEquipSlot, true ); pIcon->AddLazySubTooltip( pSubItemTooltip ); } } int SUIDisplayInfo::CheckEquippedItems( int SetPartId, int SetId ) const { int StringId = 0; if( SetId == 1111 ) { switch( SetPartId ) { case 1: StringId = 9602; break; case 4: StringId = 9601; break; case 8: StringId = 9603; break; case 16: StringId = 9604; break; case 32: StringId = 9605; break; } } else if( SetId == 1112 ) { switch( SetPartId ) { case 1: StringId = 9607; break; case 4: StringId = 9606; break; case 8: StringId = 9608; break; case 16: StringId = 9609; break; case 32: StringId = 9610; break; } } else if( SetId == 1113 ) { switch( SetPartId ) { case 1: StringId = 9612; break; case 4: StringId = 9611; break; case 8: StringId = 9613; break; case 16: StringId = 9614; break; case 32: StringId = 9615; break; } } /// 2010.10.27 - prodongi else if (SetId == 1117) { switch( SetPartId ) { case 4: StringId = 10271704; break; case 16: StringId = 10303705; break; case 32: StringId = 10314709; break; } } else if (SetId == 1118) { switch( SetPartId ) { case 4: StringId = 10272704; break; case 16: StringId = 10303706; break; case 32: StringId = 10314710; break; } } else if (SetId == 1119) { switch( SetPartId ) { case 4: StringId = 10273704; break; case 16: StringId = 10303707; break; case 32: StringId = 10314711; break; } } else if (SetId == 1120) { switch( SetPartId ) { case 4: StringId = 10274704; break; case 16: StringId = 10303708; break; case 32: StringId = 10314712; break; } } /// 2011.03.10 - prodongi else if (SetId == 1121) { switch (SetPartId) { case 4: StringId = 10261701; break; case 8: StringId = 10322701; break; case 16: StringId = 10323701; break; case 32: StringId = 10324701; break; } } else if (SetId == 1122) { switch (SetPartId) { case 4: StringId = 10262701; break; case 8: StringId = 10322702; break; case 16: StringId = 10323702; break; case 32: StringId = 10324702; break; } } else if (SetId == 1123) { switch (SetPartId) { case 4: StringId = 10263701; break; case 8: StringId = 10322703; break; case 16: StringId = 10323703; break; case 32: StringId = 10324703; break; } } else if (SetId == 1124) { switch (SetPartId) { case 4: StringId = 10264701; break; case 8: StringId = 10322704; break; case 16: StringId = 10323704; break; case 32: StringId = 10324704; break; } } /// 2011.12.06 - prodongi else if (SetId == 1125) { switch (SetPartId) { case 64: StringId = 10305746; break; case 512: StringId = 437101; break; case 2048: StringId = 10427201; break; } } else if (SetId == 1126) { switch (SetPartId) { case 64: StringId = 10305752; break; case 512: StringId = 437102; break; case 2048: StringId = 10427202; break; } } else if (SetId == 1127) { switch (SetPartId) { case 64: StringId = 305758; break; case 512: StringId = 10437103; break; case 2048: StringId = 10427203; break; } } else if (SetId == 1128) { switch (SetPartId) { case 64: StringId = 305764; break; case 512: StringId = 10437104; break; case 2048: StringId = 10427204; break; } } else if (SetId == 1129) { switch (SetPartId) { case 64: StringId = 305770; break; case 512: StringId = 437105; break; case 2048: StringId = 10427205; break; } } else if (SetId == 1130) { switch (SetPartId) { case 64: StringId = 305776; break; case 512: StringId = 437106; break; case 2048: StringId = 10427206; break; } } else if (SetId == 1131) { switch (SetPartId) { case 64: StringId = 10305782; break; case 512: StringId = 437107; break; case 2048: StringId = 10427207; break; } } else if (SetId == 1132) { switch (SetPartId) { case 64: StringId = 10305788; break; case 512: StringId = 437108; break; case 2048: StringId = 10427208; break; } } else if (SetId == 1133) { switch (SetPartId) { case 64: StringId = 10305794; break; case 512: StringId = 10437109; break; case 2048: StringId = 10427209; break; } } else if (SetId == 1134) { switch (SetPartId) { case 64: StringId = 10305800; break; case 512: StringId = 10437110; break; case 2048: StringId = 10427210; break; } } else if ( SetId == 1135 || SetId == 1136 ) { switch ( SetPartId ) { case 4: StringId = 9619; break; case 8: StringId = 9616; break; case 16: StringId = 9617; break; case 32: StringId = 9618; break; } } return StringId; } void SUIDisplayInfo::JewelTooltip( int nItemID, int* pLevel, std::string& strOptionVale, int Endurance, bool bShop, TS_ITEM_BASE_INFO::LPRANDOM_OPTION const pRandomOption ) const { const ItemBaseEx_info* pItemBaseInfo = GetItemDB().GetItemData( nItemID ); if( pItemBaseInfo == NULL ) return; int nSlotCnt( pItemBaseInfo->socket ); if( pRandomOption ) { int nAddJewelSocketCount( pRandomOption->GetAddJewelSocketCount() ); nSlotCnt += nAddJewelSocketCount; } bool bEndurance( m_InventoryMgr.IsEndurance(Endurance) ); if (!bShop) { if( bEndurance ) { if( Endurance == 0 ) strOptionVale += "<#EE0000>"; strOptionVale += SR(6491, "#@per@#", Endurance); strOptionVale += "

<#FFFFFF>"; } } int nJewelID(0); std::string strSoketIcon; std::vector vecJewelStr; for( int i(0); i", strSoketIcon.c_str() ); int nType; double dVar1, dVar2; std::vector vecStr; for( int nOption( 0 ); nOption < ItemBase::MAX_OPTION_NUMBER; ++nOption ) { std::string strtemp = "#@bitset_text@#"; if( GetItemDB().GetOptionVar( nJewelID, nOption, nType, dVar1, dVar2 ) ) { BuildOptionTooltipValue( strtemp, nType, dVar1, dVar2, 0 ); } // 2010.09.20 - prodongi //if( strtemp != "#@bitset_text@#" ) if( strtemp != "#@bitset_text@#" && !strtemp.empty() ) vecStr.push_back(strtemp); } for( int i(0); i0 ) strJewel += " / "; strJewel += vecStr[i]; } if( !vecStr.empty() ) vecJewelStr.push_back(strJewel); vecStr.clear(); } } for( int i(0); i0 ) strOptionVale += "
"; strOptionVale += vecJewelStr[i]; } vecJewelStr.clear(); } void SUIDisplayInfo::GetSoketTag( int nItemID, std::string& strTag ) const { strTag = GetItemDB().GetIconName(nItemID); int nCutSize( ::strlen("icon_soulstone_") ); if( strTag.size() > nCutSize ) { strTag.erase(0, nCutSize); strTag.insert(0, "#@"); strTag += "@#"; } } int SUIDisplayInfo::IsEnhanceAddCapability( int nItemID ) const { const ItemBaseEx_info * pItem = GetItemDB().GetItemData( nItemID ); const std::vector< ItemEnhanceEffectBase >& enhance_list = GetItemDB().Find( pItem->nEnhanceID ); auto pos = enhance_list.begin(); auto end = enhance_list.end(); int nTypeID = 0; for( ; pos != end; ++pos ) { const ItemEnhanceEffectBase& ee = (*pos); nTypeID = ee.effect_id; for( int i = 0; i < ItemBase::MAX_OPTION_NUMBER; ++i ) { if( ee.effect_id == pItem->nBaseType[i] || ee.effect_id == pItem->nOptType[i] ) { nTypeID = 0; break; } } if( nTypeID != 0 ) return nTypeID; } return nTypeID; } std::string SUIDisplayInfo::GetItemKeywordDetailTooltip( int nType )// const { switch( nType ) { default: return std::string( "" ); case ITEM_EFFECT_PASSIVE::ATTACK_POINT: return S(8002); case ITEM_EFFECT_PASSIVE::MAGIC_POINT: return S(8003); case ITEM_EFFECT_PASSIVE::ACCURACY: return S(8004); case ITEM_EFFECT_PASSIVE::ATTACK_SPEED: return S(8005); case ITEM_EFFECT_PASSIVE::DEFENCE: return S(8006); case ITEM_EFFECT_PASSIVE::MAGIC_DEFENCE: return S(8007); case ITEM_EFFECT_PASSIVE::AVOID: return S(8008); case ITEM_EFFECT_PASSIVE::MOVE_SPEED: return S(8009); case ITEM_EFFECT_PASSIVE::BLOCK_CHANGE: return S(8010); case ITEM_EFFECT_PASSIVE::CARRY_WEIGHT: return S(8011); case ITEM_EFFECT_PASSIVE::BLOCK_DEFENCE: return S(8012); // case ITEM_EFFECT_PASSIVE::CASTING_SPEED: return S(-301);std::string( "#@M_speed@#" ); // case ITEM_EFFECT_PASSIVE::MAGIC_ACCURACY: return S(-302);std::string( "#@M_hit@#" ); // case ITEM_EFFECT_PASSIVE::MAGIC_AVOID: return S(-303);std::string( "#@M_avoid@#" ); // case ITEM_EFFECT_PASSIVE::COOLTIME_SPEED: return S(-304);std::string( "#@Skill_recasting@#" ); case ITEM_EFFECT_PASSIVE::BELT_SLOT: return S(8017); case ITEM_EFFECT_PASSIVE::MAX_HP: return S(8018); case ITEM_EFFECT_PASSIVE::MAX_MP: return S(8019); case ITEM_EFFECT_PASSIVE::MP_REGEN_POINT: return S(8020); // case ITEM_EFFECT_CHARM::INC_MAX_STAMINA: return S(8021);std::string( "#@MaxStamina@#" ); case ITEM_EFFECT_PASSIVE::ADD_STATE_BY_EQUIP_ITEM: return std::string("ADD_STATE_BY_EQUIP_ITEM"); } } std::string SUIDisplayInfo::GetGenaralItemDetailTooltip( int nItemID, unsigned char byLevel, int byEnhance, bool bEnhance, int elemental_effect_attack_point, int elemental_effect_magic_point ) const { const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( nItemID ); if( !pItemBase ) return ""; std::string NextTooltip; for( int nOption( 0 ); nOption < ItemBase::MAX_OPTION_NUMBER; ++nOption ) { int nType(0); double fVar1(0.f), fVar2(0.f); std::string strNext; if( GetItemDB().GetBaseVar( nItemID, nOption, nType, fVar1, fVar2 ) ) { strNext = GetItemKeywordDetailTooltip( nType ); if( !bEnhance && ( (pItemBase->nRank == 1 && byLevel < 5) || (pItemBase->nRank > 1 && byLevel < 10) ) ) { int nValue(0); int nNextValue(0); nValue = int( fVar1 + (fVar2 * double(byLevel - 1)) ); nNextValue = int( fVar1 + (fVar2 * double(byLevel)) ); if( nValue != nNextValue ){ BuildBaseTooltipValue( pItemBase, strNext, nType, fVar1, fVar2, byEnhance, byLevel+1, elemental_effect_attack_point, elemental_effect_magic_point, m_PlayerInfoMgr.GetPlayerInfo().GetLevel() ); NextTooltip += strNext; } } if( bEnhance && byEnhance < ItemBase::MAX_ENHANCE_NUMBER ) { int nAddPoint(0); int nNextAddPoint(0); nAddPoint = GetItemAddPoint( pItemBase, nType, byEnhance ); nNextAddPoint = GetItemAddPoint( pItemBase, nType, byEnhance+1 ); if( nAddPoint != nNextAddPoint ){ BuildBaseTooltipValue( pItemBase, strNext, nType, fVar1, fVar2, byEnhance+1, byLevel, 0, 0, m_PlayerInfoMgr.GetPlayerInfo().GetLevel() ); NextTooltip += strNext; } } } } return NextTooltip; } std::string SUIDisplayInfo::GetGenaralItemEnhanceAbilityTooltip( int nItemID, unsigned char byLevel, int byEnhance, int nAbilityType, int elemental_effect_attack_point, int elemental_effect_magic_point ) const { std::string strNext; const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( nItemID ); if( !pItemBase ) return strNext; if( nAbilityType ) { int nAddPoint(0); int nNextAddPoint(0); nAddPoint = GetItemAddPoint( pItemBase, nAbilityType, byEnhance ); nNextAddPoint = GetItemAddPoint( pItemBase, nAbilityType, byEnhance+1 ); if( nAddPoint != nNextAddPoint ){ strNext = "#@add_ability@#"; BuildEnhanceAddCapability( strNext, nAbilityType, nNextAddPoint, byEnhance+1 ); } } return strNext; } // 2010.07.14 - prodongi money_t SUIDisplayInfo::GetItemSellPrice( int nItemID, unsigned char byLevel, const bool ethereal_durability_exhausted ) //money_t SUIDisplayInfo::GetItemSellPrice( int nItemID, unsigned char byLevel ) { const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( nItemID ); // sonador 3.4.4 환금성 아이템 거래 관련 수정 money_t Price( 0 ); if( pItemBase ) { float fDefaultPrice = float( GameRule::GetItemSellPrice( pItemBase->nPrice, pItemBase->nRank, int(byLevel), pItemBase->nType == ItemBase::TYPE_ARMOR ) ); if( nItemID >= 602700 && nItemID < 602800 ) { Price = money_t( fDefaultPrice * c_fItemSellOrigRatio ); } else { Price = money_t( fDefaultPrice * c_fItemSellRatio ); } } return Price / money_t((ethereal_durability_exhausted) ? 20 : 1); } void SUIDisplayInfo::LoadClientInfo( const std::string& rInfoString ) { m_dwLastClientInfoSaveTime = m_dwCurTime; // 이 시점부터 client info를 저장할 수 있게 된다. m_strPreviousClientInfo = rInfoString; STRING_VECTOR TextLines; CStringUtil::GetTextLinesFromString( rInfoString, TextLines, c_szClientInfoLinefeed ); // 퀵슬롯,키맵핑,채팅모드(엔터채팅,일반채팅) 정보 읽기 bool bEnterChat = true; int nVersion = 0; ClearQuickSlotsAll(); GetGameKeymapping().Clear(); SAFE_DELETE(m_pBackupedQuickSlot); for( size_t n = 0; n < TextLines.size(); ++n ) { //SGameWorldKeymapping *test = &(GetGameKeymapping()); const std::string& rLine = TextLines[n]; std::string strContent; // quick slot if( CStringUtil::GetContentString( rLine, c_szQuickSlotInfoHeaderNew, strContent ) ) LoadQuickSlotUnit( strContent ); if( CStringUtil::GetContentString( rLine, c_szQuickSlotInfoHeaderOld, strContent ) ) LoadQuickSlotUnitOld( strContent ); if( CStringUtil::GetContentString( rLine, c_szKeymappingHeader, strContent ) ) LoadKeymappingInfo( GetGameKeymapping(), strContent ); //엔터채팅여부. sfreer 2009.03.18 if( CStringUtil::GetContentString( rLine, c_szEnterchatHeader, strContent ) ) { if(atoi(strContent.c_str()) == 0) //엔터채팅임. bEnterChat = false; } //버전체크할것. sfreer 2009.11.30 if( CStringUtil::GetContentString( rLine, c_szClientDataVersionHeader, strContent ) ) { nVersion = atoi(strContent.c_str()); } } SaveClientInfo(); if( nVersion == KEYMAP_VERSION::BEGINER ) // 신규 유저, 키맵핑을 한번도 바꾸지 않은 유저. { GetGameKeymapping().Clear(); } else { if( nVersion != c_iClinetDataVersion ) // 버전이 달라졌다면 바뀐 키들 셋팅 { const _OPT_DATA& data = GetGameOption().GetOptData(); if(data.nEnterChat) // 기존 라펠즈 키맵핑인 경우.. 기존 라펠즈처럼 키맵핑을 다시 설정 GetGameKeymapping().SetPrevRappelzDefaultKeymapping(); else GetGameKeymapping().newKeySetting(nVersion); } } if(!bEnterChat) { SGameWorldKeymapping PrevRappelzDefKeymapping; PrevRappelzDefKeymapping.SetPrevRappelzDefaultKeymapping(); if(GetGameKeymapping() != PrevRappelzDefKeymapping) { bEnterChat = true; } } GetGameKeymapping().EnterChat(bEnterChat); } void SUIDisplayInfo::LoadCurrentKeyInfo( const std::string& rInfoString ) { m_dwLastClientInfoSaveTime = m_dwCurTime; // 이 시점부터 client info를 저장할 수 있게 된다. m_strPreviousCurrentKeyInfo = rInfoString; STRING_VECTOR TextLines; CStringUtil::GetTextLinesFromString( rInfoString, TextLines, c_szClientInfoLinefeed ); // 퀵슬롯,키맵핑,채팅모드(엔터채팅,일반채팅) 정보 읽기 bool bEnterChat = true; int nVersion = 0; for( size_t n = 0; n < TextLines.size(); ++n ) { //SGameWorldKeymapping *test = &(GetGameKeymapping()); const std::string& rLine = TextLines[n]; std::string strContent; if( CStringUtil::GetContentString( rLine, c_szKeymappingHeader, strContent ) ) LoadKeymappingInfo( GetGameKeymapping(), strContent ); //엔터채팅여부. sfreer 2009.03.18 if( CStringUtil::GetContentString( rLine, c_szEnterchatHeader, strContent ) ) { if(atoi(strContent.c_str()) == 0) //엔터채팅임. bEnterChat = false; } //버전체크할것. sfreer 2009.11.30 if( CStringUtil::GetContentString( rLine, c_szClientDataVersionHeader, strContent ) ) { nVersion = atoi(strContent.c_str()); } } if( nVersion != c_iClinetDataVersion ) { bEnterChat = GetGameKeymapping().IsEnterChat(); } //만약 키맵핑 설정이 없다면.. if(GetGameKeymapping().IsEmpty()) GetGameKeymapping().SetDefaultKeymapping(); if(!bEnterChat) { SGameWorldKeymapping PrevRappelzDefKeymapping; PrevRappelzDefKeymapping.SetPrevRappelzDefaultKeymapping(); if(GetGameKeymapping() != PrevRappelzDefKeymapping) { bEnterChat = true; } } GetGameKeymapping().EnterChat(bEnterChat); SaveKeymmapingInfo_current(); //변경된 키맵핑 관련 메시지 m_pGameManager->PostMsgAtDynamic( new SIMSG_SET_KEYMAPPING() ); _OPT_DATA data = GetGameOption().GetOptData(); data.nEnterChat = bEnterChat; GetGameOption().SetOptData(data); GetGameKeymapping().EnableMoveKey(bEnterChat); GetGameOption().Apply( SGAME_OPT_DATA::MODE_PLAY ); m_pGameManager->ApplyOption( SGAME_OPT_DATA::MODE_PLAY ); } void SUIDisplayInfo::SaveActiveClientInfos() { if( 0 != m_dwLastClientInfoSaveTime ) { m_dwLastClientInfoSaveTime = m_dwCurTime; SaveClientInfo(); SaveQuickSlots(); SaveKeymmapingInfo_current(); } } void SUIDisplayInfo::SaveClientInfo() { if( 0 != m_dwLastClientInfoSaveTime ) { m_dwLastClientInfoSaveTime = m_dwCurTime; std::string strSaveText; //savedata 의 버전을 저장 { std::string strtemp = c_szClientDataVersionHeader; strtemp += CStringUtil::StringFormat( "%d",c_iClinetDataVersion ); strtemp+=c_szClientInfoLinefeed; strSaveText+=strtemp; } if( m_strPreviousClientInfo != strSaveText ) { m_strPreviousClientInfo = strSaveText; m_pGameManager->ProcMsgAtStatic( &SIMSG_UI_SAVE_CLIENT_INFO( strSaveText ) ); _oprint( "Client info has been saved.\n" ); } else _oprint( "No need to save client info.\n" ); } } void SkillThread_Load( int nSkillID, bool bNotCacheDelete ) { //쓰레드 로딩 미리 걸어 놓는다. _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( nSkillID ); if( pSkillFX ) { SGamePreLoad gamepreload; gamepreload.RequestThreadLoading( pSkillFX, bNotCacheDelete ); } } void Skill_UnLoad( int nSkillID ) { _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( nSkillID ); if( pSkillFX ) { SGamePreLoad gamepreload; gamepreload.Unload( pSkillFX ); } } void SUIDisplayInfo::LoadQuickSlotUnitOld( const std::string& rQuickSlotInfoString ) // 2009년 3월 업데이트 이전 버전 호환을 위해서 존재합니다. 2009.03.24. sfreer { STRING_VECTOR QuickSlotInfo; CStringUtil::GetTextLinesFromString( rQuickSlotInfoString, QuickSlotInfo, c_szQuickSlotInfoDivision ); if( 3 < QuickSlotInfo.size() ) { int n = ::atoi( QuickSlotInfo[0].c_str() ) ; int nSlotIndex = ::atoi( QuickSlotInfo[1].c_str() ); int nType = ::atoi( QuickSlotInfo[2].c_str() ); // ctrl+shift -> alt 를 대체 if(n==1) n=4; if(n>1) n=n-1; /*enum QUICKSLOT_BTNSTATE { QUICKSLOT_DEFAULT = 0, QUICKSLOT_CS = 1, QUICKSLOT_CONTROL = 2, QUICKSLOT_SHIFT = 3, QUICKSLOT_ALT = 4, QUICKSLOT_BTN_MAXCOUNT = 5, };*/ nSlotIndex = (n*12)+nSlotIndex; if(0 <= nSlotIndex && nSlotIndex < c_nQuickSlotCount ) { switch( ::atoi( QuickSlotInfo[2].c_str() ) ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: if( 4 == QuickSlotInfo.size() ) { ItemInstance::ItemUID ItemUniqueID = ItemInstance::ItemUID( ::_atoi64( QuickSlotInfo[3].c_str() ) ); SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( ItemUniqueID ); if( pSlot ) { SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotItemInfo( pSlot->GetHandle(), pSlot->GetItemCode() ); } } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: if( 5 == QuickSlotInfo.size() ) { //user skill int nSkillID = ::atoi( QuickSlotInfo[3].c_str() ); int nLevel = ::atoi( QuickSlotInfo[4].c_str() ); nLevel = GetRightSkillLevel( nSkillID, nLevel ); if( nLevel != 0 && m_SkillSlotMgr.IsExistSkill( nSkillID ) ) { SkillThread_Load( nSkillID, true ); SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( m_PlayerInfoMgr.GetPlayerHandle(), nSkillID, nLevel ); } } else if( 6 == QuickSlotInfo.size() ) { //creature skill //char * strstoper; int nSkillID = ::atoi( QuickSlotInfo[3].c_str() ); int nLevel = ::atoi( QuickSlotInfo[4].c_str() ); //AR_HANDLE hCreatureUID = ::strtoul( QuickSlotInfo[5].c_str(), &strstoper, 10 ); AR_HANDLE hCreatureUID = ::atoi( QuickSlotInfo[5].c_str() ); SInventorySlot* pItemSlot = m_InventoryMgr.GetItemInfoCreatureUID( hCreatureUID ); if( pItemSlot ) { AR_HANDLE hCard = pItemSlot->GetItem()->handle; //크리처 아이템 핸들 AR_HANDLE hCreature = m_CreatureSlotMgr.GetEquipedCreature( hCard ); SkillThread_Load( nSkillID, true ); SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( hCreature, nSkillID, nLevel, false); } } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: if( 4 == QuickSlotInfo.size() ) { int nMotionID = ::atoi( QuickSlotInfo[3].c_str() ); MOTION_ACTION nMotionCmd; switch( nMotionID ) { case ID_ATTACK : nMotionCmd = MOTION_ATTACK; break; case ID_STANDUP : nMotionCmd = MOTION_STANDUP; break; case ID_PICKUP : nMotionCmd = MOTION_PICKUP; break; case ID_ASSIST : nMotionCmd = MOTION_ASSIST; break; case ID_TRADE : nMotionCmd = MOTION_TRADE; break; case ID_CREATURE_ATTACK : nMotionCmd = CREATURE_ATTACK; break; case ID_CREATURE_ALLATTACK : nMotionCmd = CREATURE_ALLATTACK; break; case ID_CREATURE_BACKDOWN : nMotionCmd = CREATURE_BACKDOWN; break; case ID_PKMODE : nMotionCmd = MOTION_PKMODE; break; case ID_COMBINE : nMotionCmd = MOTION_COMBINE; break; case ID_BOOTH : nMotionCmd = MOTION_BOOTH; break; case ID_MOUNT : nMotionCmd = MOTION_MOUNT; break; case ID_HI : nMotionCmd = MOTION_HI; break; case ID_BOW : nMotionCmd = MOTION_BOW; break; case ID_HAPPY : nMotionCmd = MOTION_HAPPY; break; case ID_SORROW : nMotionCmd = MOTION_SORROW; break; case ID_YES : nMotionCmd = MOTION_YES; break; case ID_NO : nMotionCmd = MOTION_NO; break; case ID_BORING : nMotionCmd = MOTION_BORING; break; case ID_APOLOGIZE : nMotionCmd = MOTION_APOLOGIZE; break; case ID_CHEER : nMotionCmd = MOTION_CHEER; break; case ID_POUT : nMotionCmd = MOTION_POUT; break; case ID_DANCE : nMotionCmd = MOTION_DANCE; break; case ID_CLAP : nMotionCmd = MOTION_CLAP; break; case ID_ANGRY : nMotionCmd = MOTION_ANGRY; break; case ID_PROVOKE : nMotionCmd = MOTION_PROVOKE; break; case ID_PICKUP_CARD : nMotionCmd = MOTION_PICKUP_CARD; break; case ID_PARTY_CREATE : nMotionCmd = MOTION_PARTY_CREATE; break; case ID_PARTY_INVITE : nMotionCmd = MOTION_PARTY_INVITE; break; // AziaMafia ADD EMOTE case ID_TP :nMotionCmd = MOTION_YES; break; case ID_LOOT :nMotionCmd = MOTION_YES; break; case ID_TAME :nMotionCmd = MOTION_YES; break; case ID_BUFF :nMotionCmd = MOTION_YES; break; case ID_BUFFGUILD :nMotionCmd = MOTION_YES; break; case ID_TPTAMINGZONE :nMotionCmd = MOTION_YES; break; case ID_ATRADE :nMotionCmd = MOTION_YES; break; default : return; } SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotMotionInfo( nMotionID, nMotionCmd ); } break; } } } } void SUIDisplayInfo::LoadQuickSlotUnit( const std::string& rQuickSlotInfoString ) { STRING_VECTOR QuickSlotInfo; CStringUtil::GetTextLinesFromString( rQuickSlotInfoString, QuickSlotInfo, c_szQuickSlotInfoDivision ); if( 2 < QuickSlotInfo.size() ) { int nSlotIndex = ::atoi( QuickSlotInfo[0].c_str() ); int nType = ::atoi( QuickSlotInfo[1].c_str() ); if(0 <= nSlotIndex && nSlotIndex < c_nQuickSlotCount ) { switch( ::atoi( QuickSlotInfo[1].c_str() ) ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: if( 3 == QuickSlotInfo.size() ) { ItemInstance::ItemUID ItemUniqueID = ItemInstance::ItemUID( ::_atoi64( QuickSlotInfo[2].c_str() ) ); SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( ItemUniqueID ); if( pSlot ) { SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotItemInfo( pSlot->GetHandle(), pSlot->GetItemCode() ); } } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: if( 4 == QuickSlotInfo.size() ) { //user skill int nSkillID = ::atoi( QuickSlotInfo[2].c_str() ); int nLevel = ::atoi( QuickSlotInfo[3].c_str() ); nLevel = GetRightSkillLevel( nSkillID, nLevel ); if( nLevel != 0 && m_SkillSlotMgr.IsExistSkill( nSkillID ) ) { SkillThread_Load( nSkillID, true ); SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( m_PlayerInfoMgr.GetPlayerHandle(), nSkillID, nLevel ); } } else if( 5 == QuickSlotInfo.size() ) { //creature skill int nSkillID = ::atoi( QuickSlotInfo[2].c_str() ); int nLevel = ::atoi( QuickSlotInfo[3].c_str() ); AR_HANDLE hCreatureUID = ::atoi( QuickSlotInfo[4].c_str() ); SInventorySlot* pItemSlot = m_InventoryMgr.GetItemInfoCreatureUID( hCreatureUID ); if( pItemSlot ) { AR_HANDLE hCard = pItemSlot->GetItem()->handle; //크리처 아이템 핸들 AR_HANDLE hCreature = m_CreatureSlotMgr.GetEquipedCreature( hCard ); SkillThread_Load( nSkillID, true ); SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( hCreature, nSkillID, nLevel, false); } } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: if( 3 == QuickSlotInfo.size() ) { int nMotionID = ::atoi( QuickSlotInfo[2].c_str() ); MOTION_ACTION nMotionCmd; switch( nMotionID ) { case ID_ATTACK : nMotionCmd = MOTION_ATTACK; break; case ID_STANDUP : nMotionCmd = MOTION_STANDUP; break; case ID_PICKUP : nMotionCmd = MOTION_PICKUP; break; case ID_ASSIST : nMotionCmd = MOTION_ASSIST; break; case ID_TRADE : nMotionCmd = MOTION_TRADE; break; case ID_CREATURE_ATTACK : nMotionCmd = CREATURE_ATTACK; break; case ID_CREATURE_ALLATTACK : nMotionCmd = CREATURE_ALLATTACK; break; case ID_CREATURE_BACKDOWN : nMotionCmd = CREATURE_BACKDOWN; break; case ID_PKMODE : nMotionCmd = MOTION_PKMODE; break; case ID_COMBINE : nMotionCmd = MOTION_COMBINE; break; case ID_BOOTH : nMotionCmd = MOTION_BOOTH; break; case ID_MOUNT : nMotionCmd = MOTION_MOUNT; break; case ID_HI : nMotionCmd = MOTION_HI; break; case ID_BOW : nMotionCmd = MOTION_BOW; break; case ID_HAPPY : nMotionCmd = MOTION_HAPPY; break; case ID_SORROW : nMotionCmd = MOTION_SORROW; break; case ID_YES : nMotionCmd = MOTION_YES; break; case ID_NO : nMotionCmd = MOTION_NO; break; case ID_BORING : nMotionCmd = MOTION_BORING; break; case ID_APOLOGIZE : nMotionCmd = MOTION_APOLOGIZE; break; case ID_CHEER : nMotionCmd = MOTION_CHEER; break; case ID_POUT : nMotionCmd = MOTION_POUT; break; case ID_DANCE : nMotionCmd = MOTION_DANCE; break; case ID_CLAP : nMotionCmd = MOTION_CLAP; break; case ID_ANGRY : nMotionCmd = MOTION_ANGRY; break; case ID_PROVOKE : nMotionCmd = MOTION_PROVOKE; break; case ID_PICKUP_CARD : nMotionCmd = MOTION_PICKUP_CARD; break; case ID_PARTY_CREATE : nMotionCmd = MOTION_PARTY_CREATE; break; case ID_PARTY_INVITE : nMotionCmd = MOTION_PARTY_INVITE; break; // AziaMafia ADD EMOTE case ID_TP: nMotionCmd = MOTION_YES; break; case ID_LOOT: nMotionCmd = MOTION_YES; break; case ID_TAME: nMotionCmd = MOTION_YES; break; case ID_BUFF: nMotionCmd = MOTION_YES; break; case ID_BUFFGUILD: nMotionCmd = MOTION_YES; break; case ID_TPTAMINGZONE: nMotionCmd = MOTION_YES; break; case ID_ATRADE: nMotionCmd = MOTION_YES; break; default : return; } SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotMotionInfo( nMotionID, nMotionCmd ); } break; //2012. 3. 26 - marine case SUIQuickSlotInfo::QSLOTTYPE_EMPTYITEM: if( 3 == QuickSlotInfo.size() ) { int itemCode = ::atoi( QuickSlotInfo[2].c_str() ); stEmptyItemSet itemset( itemCode, int(QS_WAITING), nSlotIndex ); m_ExistEmptyItem.pushEmptyItem(itemset); } break; } } } } int SUIDisplayInfo::GetRightSkillLevel( int nSkillId, int nSkillLv ) { /*const std::vector& vecSkillList = m_SkillSlotMgr.GetSkillList(); std::vector::const_iterator iter = vecSkillList.begin(); for( ; iter != vecSkillList.end(); ++iter ) { SMSG_SKILL_LIST::SkillInfo SkillInfo = (*iter)->GetSkill(); if( SkillInfo.skill_id == nSkillId ) { int lv = SkillInfo.base_skill_level + (*iter)->GetAddedLevel(); if( lv >= nSkillLv ) return nSkillLv; else return lv; } } return 0;*/ return nSkillLv; } void SUIDisplayInfo::LoadKeymappingInfo( SGameWorldKeymapping &table, const std::string & rKeymappingInfoString ) { STRING_VECTOR kminfo; CStringUtil::GetTextLinesFromString( rKeymappingInfoString, kminfo, c_szKeymappingDivision ); if(kminfo.size() == 5) { int id = ::atoi( kminfo[0].c_str() ); int alt = ::atoi( kminfo[1].c_str() ); int shift = ::atoi( kminfo[2].c_str() ); int ctrl = ::atoi( kminfo[3].c_str() ); int key = ::atoi( kminfo[4].c_str() ); table.SetKeymapping(id, KEYEX(alt!=0,shift!=0,ctrl!=0,key),true); // C4800워닝 } } void SUIDisplayInfo::SaveKeymappingInfo( SGameWorldKeymapping &table, std::string & rSaveString, const char* szKeymappingHeader, const char* szEnterchatHeader ) { for(int j=0;jGetGameInterface()->GetUIWindow( TOGGLE_WINDOW::UIWINDOW_SYSTEM ); if( pSystemWnd ) pSystemWnd->EnableButton( "button_user_open", false ); } else { // 옵션(키설정)부 "저장정보 불러오기" 활성 SUISystemWnd* pSystemWnd = ( SUISystemWnd* )m_pGameManager->GetGameInterface()->GetUIWindow( TOGGLE_WINDOW::UIWINDOW_SYSTEM ); if( pSystemWnd ) pSystemWnd->EnableButton( "button_user_open", true ); #endif } //변경된 키맵핑 관련 메시지 m_pGameManager->PostMsgAtDynamic( new SIMSG_SET_KEYMAPPING() ); } void SUIDisplayInfo::SaveKeymmapingInfo_current() { if( 0 != m_dwLastClientInfoSaveTime ) { m_dwLastClientInfoSaveTime = m_dwCurTime; std::string strSaveText; // 키맵핑정보 SaveKeymappingInfo( GetGameKeymapping(), strSaveText, c_szKeymappingHeader, c_szEnterchatHeader ); //savedata 의 버전을 저장 { std::string strtemp = c_szClientDataVersionHeader; strtemp += CStringUtil::StringFormat( "%d",c_iClinetDataVersion ); strtemp+=c_szClientInfoLinefeed; strSaveText+=strtemp; } if( m_strPreviousCurrentKeyInfo != strSaveText ) { m_strPreviousCurrentKeyInfo = strSaveText; m_pGameManager->ProcMsgAtStatic( &SIMSG_UI_SAVE_CURRENT_KEY( strSaveText ) ); _oprint( "current key 저장되었습니다.\n" ); } else _oprint( "current key 저장 불필요.\n" ); } } void SUIDisplayInfo::SaveKeymappingInfo_saved() { if( 0 != m_dwLastClientInfoSaveTime ) { m_dwLastClientInfoSaveTime = m_dwCurTime; std::string strSaveText; // 키맵핑정보 if( GetGameSavedKeymapping().IsEmpty() == false ) { SaveKeymappingInfo( GetGameSavedKeymapping(), strSaveText, c_szKeymapping2Header, c_szEnterchat2Header ); } //savedata 의 버전을 저장 { std::string strtemp = c_szClientDataVersionHeader; strtemp += CStringUtil::StringFormat( "%d", c_iClinetDataVersion ); strtemp += c_szClientInfoLinefeed; strSaveText += strtemp; } if( m_strPreviousSavedKeyInfo != strSaveText ) { m_strPreviousSavedKeyInfo = strSaveText; m_pGameManager->ProcMsgAtStatic( &SIMSG_UI_SAVE_SAVED_KEY( strSaveText ) ); _oprint( "Client User Info has been saved.\n" ); } else _oprint( "Client User Info saving not necessary.\n\n" ); } } void SUIDisplayInfo::LoadQuickSlotInfo( const std::string& rInfoString ) { m_dwLastClientInfoSaveTime = m_dwCurTime; // 이 시점부터 client info를 저장할 수 있게 된다. m_strPreviousQuickSlotInfo = rInfoString; STRING_VECTOR TextLines; CStringUtil::GetTextLinesFromString( rInfoString, TextLines, c_szClientInfoLinefeed ); // 퀵슬롯 정보 읽기 int nVersion = 0; for( size_t n = 0; n < TextLines.size(); ++n ) { const std::string& rLine = TextLines[n]; std::string strContent; // quick slot if( CStringUtil::GetContentString( rLine, c_szQuickSlotInfoHeaderNew, strContent ) ) LoadQuickSlotUnit( strContent ); if( CStringUtil::GetContentString( rLine, c_szQuickSlotInfoHeaderOld, strContent ) ) LoadQuickSlotUnitOld( strContent ); //버전체크할것. sfreer 2009.11.30 if( CStringUtil::GetContentString( rLine, c_szClientDataVersionHeader, strContent ) ) { nVersion = atoi(strContent.c_str()); } } SaveQuickSlots(); RefreshAllQuickSlots(); } void SUIDisplayInfo::SaveQuickSlots() { if( 0 != m_dwLastClientInfoSaveTime ) { m_dwLastClientInfoSaveTime = m_dwCurTime; std::string strSaveText; // 여기서 퀵슬롯 정보 저장 SaveQuickSlotInfo( strSaveText ); //savedata 의 버전을 저장 { std::string strtemp = c_szClientDataVersionHeader; strtemp += CStringUtil::StringFormat( "%d",c_iClinetDataVersion ); strtemp+=c_szClientInfoLinefeed; strSaveText+=strtemp; } if( m_strPreviousQuickSlotInfo != strSaveText ) { m_strPreviousQuickSlotInfo = strSaveText; m_pGameManager->ProcMsgAtStatic( &SIMSG_UI_SAVE_QUICK_SLOT( strSaveText ) ); _oprint( "quick slot 저장되었습니다.\n" ); } else _oprint( "quick slot 저장 불필요.\n" ); } } void SUIDisplayInfo::SaveQuickSlotInfo( std::string& rSaveString ) { std::string strQuickSlotHeader; for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { SUIQuickSlotInfo* pSlot = m_pQuickSlots[ nSlot ]; if( NULL != pSlot ) { strQuickSlotHeader = c_szQuickSlotInfoHeaderNew; strQuickSlotHeader += CStringUtil::StringFormat( "%d%s%d", nSlot, c_szQuickSlotInfoDivision, int(pSlot->m_type) ); strQuickSlotHeader += c_szQuickSlotInfoDivision; QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo = pSlot->DisplayInfo; switch( pSlot->m_type ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: { const SUIQuickSlotItemInfo* pItemSlot = (SUIQuickSlotItemInfo*)pSlot; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pItemSlot->m_hItem ); if( pSlot ) { rSaveString += strQuickSlotHeader; rSaveString += CStringUtil::StringFormat( "%I64d", pSlot->GetUID() ); rSaveString += c_szClientInfoLinefeed; } } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: { const SUIQuickSlotSkillInfo* pSkillSlot = (SUIQuickSlotSkillInfo*)pSlot; rSaveString += strQuickSlotHeader; if(m_PlayerInfoMgr.GetPlayerHandle() == pSkillSlot->m_hTarget) { //User Skill rSaveString += CStringUtil::StringFormat( "%d%s%d", pSkillSlot->m_nSkillID, c_szQuickSlotInfoDivision, pSkillSlot->m_nSkillLevel ); } else { //Creature Skill AR_HANDLE hCreature = 0; for(int i=0;i<6;i++) { if( m_CreatureSlotMgr.GetEquipedCreature(i) == pSkillSlot->m_hTarget) hCreature = pSkillSlot->m_hTarget; } if(hCreature) { const AR_HANDLE hCard = m_CreatureSlotMgr.GetEquipedCreatureCard( hCreature ); SInventorySlot* pItemSlot = m_InventoryMgr.GetItemInfo( hCard ); rSaveString += CStringUtil::StringFormat( "%d%s%d%s%d", pSkillSlot->m_nSkillID, c_szQuickSlotInfoDivision, pSkillSlot->m_nSkillLevel, c_szQuickSlotInfoDivision, pItemSlot->GetItem()->socket[0] ); } else { //_oprint("OMG!!\n"); } } rSaveString += c_szClientInfoLinefeed; } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: { const SUIQuickSlotMotionInfo* pMotionSlot = (SUIQuickSlotMotionInfo*)pSlot; rSaveString += strQuickSlotHeader; rSaveString += CStringUtil::StringFormat( "%d", pMotionSlot->m_nMotionID ); rSaveString += c_szClientInfoLinefeed; } break; //2012. 3. 28 - marine 아이템 코드만 저장.. case SUIQuickSlotInfo::QSLOTTYPE_EMPTYITEM: { const SUIQuickSlotEmptyItemInfo* pItemSlot = (SUIQuickSlotEmptyItemInfo*)pSlot; if(pItemSlot) { rSaveString += strQuickSlotHeader; rSaveString += CStringUtil::StringFormat( "%d", pItemSlot->iItemCode ); // 빈아이템이니까 아이템 코드로 분류.. rSaveString += c_szClientInfoLinefeed; } } break; } } } } void SUIDisplayInfo::RefreshItemWeight() { m_PlayerInfoMgr.GetPlayerInfo().SetInvenWeight( 0.0f ); float fInvenWeight = 0.0f; std::vector vecInvenList; /// 2010.11.24 - prodongi m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList, m_CreatureSlotMgr ); //m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList ); for( std::vector::iterator it = vecInvenList.begin(); it != vecInvenList.end(); it++ ) { SInventorySlot* pSlot = (*it); if( !pSlot->IsStorageItem() && !pSlot->IsEquipItem() ) { float fWeight = GetItemDB().GetWeight( pSlot->GetItemCode() ); if( GetItemDB().IsJoin( pSlot->GetItemCode(), IsInstanceUnstackable( pSlot ) ) ) fWeight *= pSlot->GetItemCount().getAmount(); fInvenWeight += fWeight; m_PlayerInfoMgr.GetPlayerInfo().SetInvenWeight(fInvenWeight); } } vecInvenList.clear(); } std::string SUIDisplayInfo::GetItemTooltipKeyword( int nType ) { switch( nType ) { default: return std::string( "" ); case ITEM_EFFECT_PASSIVE::ATTACK_POINT: return std::string( "#@atk@#" ); case ITEM_EFFECT_PASSIVE::MAGIC_POINT: return std::string( "#@matk@#" ); case ITEM_EFFECT_PASSIVE::ACCURACY: return std::string( "#@hit@#" ); case ITEM_EFFECT_PASSIVE::ATTACK_SPEED: return std::string( "#@a_speed@#" ); case ITEM_EFFECT_PASSIVE::DEFENCE: return std::string( "#@def@#" ); case ITEM_EFFECT_PASSIVE::MAGIC_DEFENCE: return std::string( "#@mdef@#" ); case ITEM_EFFECT_PASSIVE::AVOID: return std::string( "#@avoid@#" ); case ITEM_EFFECT_PASSIVE::MOVE_SPEED: return std::string( "#@mov_speed@#" ); case ITEM_EFFECT_PASSIVE::BLOCK_CHANGE: return std::string( "#@block chance@#" ); case ITEM_EFFECT_PASSIVE::CARRY_WEIGHT: return std::string( "#@maxWT@#" ); case ITEM_EFFECT_PASSIVE::BLOCK_DEFENCE: return std::string( "#@block defence@#" ); case ITEM_EFFECT_PASSIVE::CASTING_SPEED: return std::string( "#@M_speed@#" ); case ITEM_EFFECT_PASSIVE::MAGIC_ACCURACY: return std::string( "#@M_hit@#" ); case ITEM_EFFECT_PASSIVE::MAGIC_AVOID: return std::string( "#@M_avoid@#" ); case ITEM_EFFECT_PASSIVE::COOLTIME_SPEED: return std::string( "#@Skill_recasting@#" ); case ITEM_EFFECT_PASSIVE::BELT_SLOT: return std::string( "#@Belt_Slot@#" ); case ITEM_EFFECT_PASSIVE::MAX_CHAOS: return std::string( "#@Belt_Slot@#" ); case ITEM_EFFECT_PASSIVE::MAX_HP: return std::string( "#@MaxHP@#" ); case ITEM_EFFECT_PASSIVE::MAX_MP: return std::string( "#@MaxMP@#" ); case ITEM_EFFECT_PASSIVE::MP_REGEN_POINT: return std::string( "#@MP_regen@#" ); case ITEM_EFFECT_PASSIVE::PBLOCK_CHANCE: return std::string("#@Pblock_chance@#" ); case ITEM_EFFECT_PASSIVE::ADEF_IGNORE: return std::string("#@ADef_ignore@#" ); case ITEM_EFFECT_PASSIVE::MDEF_IGNORE: return std::string("#@MDef_ignore@#" ); case ITEM_EFFECT_PASSIVE::ADEM_PENETRATION: return std::string("#@ADem_penetration@#" ); case ITEM_EFFECT_PASSIVE::MDEM_PENETRATION: return std::string("#@MDem_Penetration@#" ); case ITEM_EFFECT_PASSIVE::INC_PARAMETER_A: return std::string( "INC_PARAMETER_A" ); case ITEM_EFFECT_PASSIVE::INC_PARAMETER_B: return std::string( "INC_PARAMETER_B" ); case ITEM_EFFECT_PASSIVE::AMP_PARAMETER_A: return std::string( "AMP_PARAMETER_A" ); case ITEM_EFFECT_PASSIVE::AMP_PARAMETER_B: return std::string( "AMP_PARAMETER_B" ); case ITEM_EFFECT_PASSIVE::INC_SOCKET_COUNT_A: return std::string( "INC_SOCKET_COUNT_A" ); case ITEM_EFFECT_PASSIVE::INC_SOCKET_COUNT_B: return std::string( "INC_SOCKET_COUNT_B" ); case ITEM_EFFECT_CHARM::INC_MAX_STAMINA: return std::string( "#@MaxStamina@#" ); case ITEM_EFFECT_PASSIVE::INC_SKILL: return std::string("INC_SKILL"); case ITEM_EFFECT_PASSIVE::ADD_STATE_BY_EQUIP_ITEM: return std::string("ADD_STATE_BY_EQUIP_ITEM"); case ITEM_EFFECT_PASSIVE::INC_ALL_DAMAGE: return std::string("INC_ALL_DAMAGE"); case ITEM_EFFECT_PASSIVE::REDUC_ALL_DAMAGE: return std::string("REDUC_ALL_DAMAGE"); } } //fVar1 -> 순수 아이템의 값 //fVar2 -> 레벨업/인첸업 등으로 1렙당 상승하는 값 float SUIDisplayInfo::BuildBaseTooltipValue( const ItemBaseEx_info * pItemBase, std::string& rTooltip, int nType, double fVar1, double fVar2, unsigned char byEnhance, unsigned char byLevel, int elemental_effect_attack_point, int elemental_effect_magic_point, int nPlayerLevel ) { float fPenaltyPercentage( 0.f ); std::string strKeyword = GetItemTooltipKeyword( nType ); if( !strKeyword.empty() ) { float nValue = fVar1 + (fVar2 * double(byLevel - 1)); int nPenaltyValue = GameRule::GetItemValue( nValue, 1.0f, int(fVar1), nPlayerLevel, pItemBase->nMinLevel, pItemBase->nRank, int(byLevel), pItemBase->nMinLevel ); int nAddPoint = GetItemAddPoint( pItemBase, nType, byEnhance ); int nMinusPoint = (nPenaltyValue < nValue) ? (nPenaltyValue - nValue) : 0; if ( nType == ITEM_EFFECT_PASSIVE::ATTACK_POINT && elemental_effect_attack_point > 0 ) nValue += elemental_effect_attack_point; if ( nType == ITEM_EFFECT_PASSIVE::MAGIC_POINT && elemental_effect_magic_point > 0 ) nValue += elemental_effect_magic_point; std::string strValue = CStringUtil::StringFormat( "%d", (int)(nValue) ); if( 0 < nAddPoint ) { // Weapon attack power = base damage + master upgrade + enchant upgrade strValue = CStringUtil::StringFormat( "%d <#00FF00>(+%d)<#FFFFFF>", (int)(nValue+nAddPoint), nAddPoint ).c_str(); } if( 0 > nMinusPoint ) { if( 0 < nAddPoint ) { // Weapon attack power = base damage + master upgrade + enchant upgrade strValue = CStringUtil::StringFormat( "<#FF8000>%d<#FFFFFF> / ", (int)(nValue+nMinusPoint+nAddPoint) ).c_str(); //패널티+Add strValue += CStringUtil::StringFormat( "%d <#00FF00>(+%d)<#FFFFFF>", (int)(nValue+nAddPoint), nAddPoint ).c_str(); } else { strValue = CStringUtil::StringFormat( "<#FF8000>%d<#FFFFFF> / ", (int)(nValue+nMinusPoint) ).c_str(); //패널티 strValue += CStringUtil::StringFormat( "%d", (int)(nValue)).c_str(); } fPenaltyPercentage = float(nMinusPoint) / float(nValue) * 100.f; } CStringUtil::ReplacePhrase( rTooltip, strKeyword, strValue ); } return fPenaltyPercentage; } void SUIDisplayInfo::BuildEnhanceAddCapability( std::string& rTooltip, int nType, float fVar, unsigned char byEnhance ) { std::string strValue; strValue = CStringUtil::StringFormat( "<#00FF00>(+%d)<#FFFFFF>", (int)fVar ); std::string strAddOption; strAddOption = GetItemKeywordDetailTooltip(nType); std::string strKeyword; strKeyword = GetItemTooltipKeyword( nType ); if( !strKeyword.empty() ) //strKeyword가 empty라면 문제가 생겨서 추가했음 by metarrgear CStringUtil::ReplacePhrase( strAddOption, strKeyword, strValue ); CStringUtil::ReplacePhrase( rTooltip, "#@add_ability@#", strAddOption ); } std::string SUIDisplayInfo::BuildOptionTooltipValue( std::string& rTooltip, int nType, double fVar1, double fVar2, unsigned char byEnhance, int* pLevel ) { std::string strTemp, strOption; std::string strKeyword = GetItemTooltipKeyword( nType ); if( !strKeyword.empty() ) { if( strKeyword == "INC_PARAMETER_A" ) { strTemp = GetItempBitsetAText( 7153, fVar1, fVar2, false, byEnhance ); if( !strTemp.empty() ) strOption += strTemp; } else if( strKeyword == "INC_PARAMETER_B" ) { strTemp = GetItempBitsetBText( 7153, fVar1, fVar2, false, byEnhance ); if( !strTemp.empty() ) strOption += strTemp; } else if( strKeyword == "AMP_PARAMETER_A" ) { fVar2 *= 100.0f; strTemp = GetItempBitsetAText( 7153, fVar1, fVar2, true, byEnhance ); if( !strTemp.empty() ) strOption += strTemp; } else if( strKeyword == "AMP_PARAMETER_B" ) { fVar2 *= 100.0f; strTemp = GetItempBitsetBText( 7153, fVar1, fVar2, true, byEnhance ); if( !strTemp.empty() ) strOption += strTemp; } // AziaMafia item effect tooltip else if (strKeyword == "ADD_STATE_BY_EQUIP_ITEM" ) { std::string strResult("<#FF9B0C>[skin] @name_creature@ Evo @evolution@ @stage@<#ffffff>"); std::string strValue = S(GetCreatureDB().GetTextID((int)fVar1)); std::string stage = S(6998); std::string Evo = CStringUtil::StringFormat("%d", GetCreatureDB().GetEvolutionForm((int)fVar1)).c_str(); CStringUtil::ReplacePhrase(strResult, "@name_creature@", strValue); CStringUtil::ReplacePhrase(strResult, "@evolution@", Evo ); if ((int)fVar2 == 1) CStringUtil::ReplacePhrase(strResult, "@stage@", " "); else CStringUtil::ReplacePhrase(strResult, "@stage@", stage ); CStringUtil::ReplacePhrase(rTooltip, "#@bitset_text@#", strResult); CStringUtil::ReplacePhrase(rTooltip, "ADD_STATE_BY_EQUIP_ITEM", strResult); return strKeyword.c_str(); } else if (strKeyword == "#@Belt_Slot@#") { int beltCount = 0; if (pLevel) { beltCount = pLevel[0] + 1; } else { beltCount = int(fVar1); } std::string strValue = CStringUtil::StringFormat( "%d", beltCount ); CStringUtil::ReplacePhrase( rTooltip, "#@bitset_text@#", strValue ); return strKeyword.c_str(); } else { std::string strValue = CStringUtil::StringFormat( "%d", int( fVar1 ) ); CStringUtil::ReplacePhrase( rTooltip, "#@bitset_text@#", strValue ); return strKeyword.c_str(); } CStringUtil::ReplacePhrase( rTooltip, "#@bitset_text@#", strOption ); return ""; } // 2010.09.03 - prodongi rTooltip.clear(); return ""; } std::string SUIDisplayInfo::GetItempBitsetAText( int strID, float fVar1, float fVar2, bool bAmplify, unsigned char byEnhance ) { return Get_A_BitSetText(strID, fVar1, fVar2, bAmplify); } std::string SUIDisplayInfo::GetItempBitsetBText( int strID, float fVar1, float fVar2, bool bAmplify, unsigned char byEnhance ) { return Get_B_BitSetText(strID, fVar1, fVar2, bAmplify); } ////////////////////////////////////////// bool SUIDisplayInfo::IsEmptyQuickSlot( /*QUICKSLOT_BTNSTATE State, */int nSlotIndex ) const { return (NULL == GetQuickSlot( /*State, */nSlotIndex )); } void SUIDisplayInfo::ClearSkillQuickSlots() { //for( int nBtn( 0 ); nBtn < QUICKSLOT_BTN_MAXCOUNT; ++nBtn ) //{ for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { SUIQuickSlotInfo* pSlot = m_pQuickSlots[ nSlot ]; if( NULL != pSlot ) { QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo = pSlot->DisplayInfo; if( pSlot->m_type == SUIQuickSlotInfo::QSLOTTYPE_SKILL ) SAFE_DELETE( m_pQuickSlots[ nSlot ] ); } } //} } // 2010.08.04 - prodongi void SUIDisplayInfo::ClearSkillQuickSlots(AR_HANDLE handle) { if (m_PlayerInfoMgr.IsLocalPlayer(handle)) { ClearSkillQuickSlots(); } else if (m_CreatureSlotMgr.IsEquipedCreature(handle)) { ClearCreatureSkillQuickSlots(handle); } } // 2010.08.04 - prodongi void SUIDisplayInfo::ClearCreatureSkillQuickSlots(AR_HANDLE handle) { for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { SUIQuickSlotInfo* pSlot = m_pQuickSlots[ nSlot ]; if(pSlot && pSlot->m_type == SUIQuickSlotInfo::QSLOTTYPE_SKILL) { SUIQuickSlotSkillInfo* sinfo = (SUIQuickSlotSkillInfo*)pSlot; if (handle == sinfo->m_hTarget) SAFE_DELETE(m_pQuickSlots[nSlot]); } } } void SUIDisplayInfo::ClearQuickSlotsAll() { m_ExistEmptyItem.vEmptyItems.clear(); // 로드 하기 전에 클리어 한다. //for( int nBtn( 0 ); nBtn < QUICKSLOT_BTN_MAXCOUNT; ++nBtn ) { for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { SAFE_DELETE( m_pQuickSlots[ nSlot ] ); } } } /// 2010.11.10 - prodongi //#ifdef _DEV //extern bool g_bDebugMode; //#endif //void SUIDisplayInfo::SetQuickSlot( QUICKSLOT_BTNSTATE State, int nSlotIndex, const SUIDragInfo* pDragInfo/* = NULL*/, AR_HANDLE hDelCreatureSlot ) void SUIDisplayInfo::SetQuickSlot( int nSlotIndex, const SUIDragInfo* pDragInfo/* = NULL*/, AR_HANDLE hDelCreatureSlot ) { if( 0 <= nSlotIndex && nSlotIndex < c_nQuickSlotCount ) { if( NULL != pDragInfo ) { switch( pDragInfo->m_type ) { ////////////추가 case SUIDragInfo::DRAGTYPE_EQUIPMENT: { SUIEquipmentDragInfo* pEquipmentDragInfo = (SUIEquipmentDragInfo*)pDragInfo; SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); SInventorySlot* pItem = m_InventoryMgr.GetItemInfo(pEquipmentDragInfo->m_hItem); const ItemBase* pItemBase = (ItemBase*)GetItemDB().GetItemData( pItem->GetItemCode() ); if( pItemBase->nClass!= ItemBase::CLASS_BOOSTER) return; AR_HANDLE target = m_PlayerInfoMgr.GetPlayerHandle(); int skill_id = pItemBase->dOptVar1[0]; int skill_level = pItem->GetLevel(); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( target, skill_id, skill_level, true ); RefreshQuickSlot( nSlotIndex ); } ///////////////////////////////// break; case SUIDragInfo::DRAGTYPE_INVENITEM: { SUIInvenItemDragInfo* pInvenItemDragInfo = (SUIInvenItemDragInfo*)pDragInfo; SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); SInventorySlot* pItem = m_InventoryMgr.GetItemInfo(pInvenItemDragInfo->m_hItem); // 추가 부스터는 장착아이템만 가능 const ItemBase* pItemBase = (ItemBase*)GetItemDB().GetItemData( pItem->GetItemCode() ); if( pItemBase->nClass== ItemBase::CLASS_BOOSTER) { // 장착여부 체크 AR_HANDLE target = m_PlayerInfoMgr.GetPlayerHandle(); // pItemBase->nOptType[0] = 5; -> 아이템사용으로 스킬호출 int skill_id = pItemBase->dOptVar1[0]; int skill_level = pItem->GetLevel(); if (skill_level==0) skill_level = 1; TS_ITEM_INFO* pitem_info = pItem->GetItem(); if (pitem_info==NULL) return; if (pitem_info->wear_position!=ItemBase::WEAR_BOOSTER) return; m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( target, skill_id, skill_level, true ); } else { /////////////////////////////////// m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotItemInfo( pInvenItemDragInfo->m_hItem, pItem->GetItemCode() ); EmptyItemCheckandDelete( nSlotIndex ); // 빈아이템이 있었다면 벡터에서 삭제되야 한다. } RefreshQuickSlot( nSlotIndex ); } break; case SUIDragInfo::DRAGTYPE_QUICKSLOT: { SUIQuickSlotDragInfo* pQuickSlotDragInfo = (SUIQuickSlotDragInfo*)pDragInfo; // 서로 다른 슬롯인 경우만 //여기 문제 있으니 주의바람. //if(/* pQuickSlotDragInfo->m_ButtonState != State ||*/ pQuickSlotDragInfo->m_nSlotIndex != nSlotIndex ) if( pQuickSlotDragInfo->m_nSlotIndex != nSlotIndex ) { const SUIQuickSlotInfo* pSrcSlot = GetQuickSlot( pQuickSlotDragInfo->m_nSlotIndex ); if( NULL != pSrcSlot ) { BackupAndDeleteQuickSlot(nSlotIndex); //SAFE_DELETE( m_pQuickSlots[ State ][ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = pSrcSlot->Duplicate(); // 슬롯을 duplicate한다. //int BackUpState(pQuickSlotDragInfo->m_ButtonState); int BackUpnSlotIndex(pQuickSlotDragInfo->m_nSlotIndex); SAFE_DELETE(m_pQuickSlots[ BackUpnSlotIndex ]); m_pQuickSlots[ BackUpnSlotIndex ] = GetQuickSlotData( m_pBackupedQuickSlot ); SAFE_DELETE(m_pBackupedQuickSlot); // 2012. 3. 28 - marine 빈아이템(수량이 0인 소모성 아이템)의 슬롯이 바뀌게 될때의 처리.. SetChangSlotIndex(BackUpnSlotIndex,nSlotIndex); RefreshQuickSlot( nSlotIndex ); RefreshQuickSlot( BackUpnSlotIndex ); } } } break; case SUIDragInfo::DRAGTYPE_SKILL: { SUISkillDragInfo* pSkillDragInfo = (SUISkillDragInfo*)pDragInfo; SkillBaseEx* s_data = GetSkillDB().GetSkillData( pSkillDragInfo->m_nSkillID ); if( s_data != NULL ) { if( s_data->IsPassive() ) //패시브는 등록 안 함 return; SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( pSkillDragInfo->m_hTarget, pSkillDragInfo->m_nSkillID, pSkillDragInfo->m_nLevel, pSkillDragInfo->m_bPlayer ); RefreshQuickSlot( nSlotIndex ); } } break; case SUIDragInfo::DRAGTYPE_MOTION: { SUIMotionDragInfo* pMotionDragInfo = (SUIMotionDragInfo*)pDragInfo; /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; //카드 줍기로 변환 if( g_bDebugMode && pMotionDragInfo->m_nMotionID == ID_PICKUP && pMotionDragInfo->m_nMotionCommandID == MOTION_PICKUP ) { pMotionDragInfo->m_nMotionID = ID_PICKUP_CARD; pMotionDragInfo->m_nMotionCommandID = MOTION_PICKUP_CARD; } } //#endif SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotMotionInfo( pMotionDragInfo->m_nMotionID, pMotionDragInfo->m_nMotionCommandID ); RefreshQuickSlot( nSlotIndex ); } break; case SUIDragInfo::DRAGTYPE_CREATURE_QUICKSLOT: { //이거추가함. 2009.03.19. 크리쳐퀵슬롯 -> 퀵슬롯 통합 과정중. //_oprint("유후~"); SUISkillDragInfo* pSkillDragInfo = (SUISkillDragInfo*)pDragInfo; SkillBaseEx* s_data = GetSkillDB().GetSkillData( pSkillDragInfo->m_nSkillID ); if( s_data != NULL ) { if( s_data->IsPassive() ) //패시브는 등록 안 함 return; SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); m_pQuickSlots[ nSlotIndex ] = new SUIQuickSlotSkillInfo( pSkillDragInfo->m_hTarget, pSkillDragInfo->m_nSkillID, pSkillDragInfo->m_nLevel, false ); RefreshQuickSlot( nSlotIndex ); } } break; } } else { if( m_pQuickSlots[ nSlotIndex ] ) { const SUIQuickSlotInfo* pQuickSlotInfo = m_pQuickSlots[ nSlotIndex ]; if( pQuickSlotInfo->m_type == SUIDragInfo::DRAGTYPE_SKILL ) { const SUIQuickSlotSkillInfo* pSkillSlotInfo = dynamicCast(pQuickSlotInfo); Skill_UnLoad( pSkillSlotInfo->m_nSkillID ); } if( pQuickSlotInfo->m_type == SUIQuickSlotInfo::QSLOTTYPE_EMPTYITEM ) // 2012. 3. 28 - marine 빈아이템 타입이면 관리벡터에서도 삭제 m_ExistEmptyItem.eraseEmptyItem(nSlotIndex); SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); PostQuickSlotUpdateMsg(); } } } } void SUIDisplayInfo::SetQuickSlotSkillLv( int nSkillID, int nSkillLv, bool bIsLvMax ) { SUIQuickSlotSkillInfo* SkillSlot(NULL); //for( int state(0); statem_type != SUIQuickSlotInfo::QSLOTTYPE_SKILL ) continue; SkillSlot = static_cast( m_pQuickSlots[index] ); if( SkillSlot->m_nSkillID != nSkillID ) continue; if( bIsLvMax && SkillSlot->m_nSkillLevel < nSkillLv-1 ) continue; SkillSlot->m_nSkillLevel = nSkillLv; SkillSlot->DisplayInfo.nCount = count_t( nSkillLv ); RefreshQuickSlot(index); } //} } //2012. 3. 29 - marinie //2012. 9. 14 - lenahyang //----------------------------------------------------------------------------------------------------------------- // 퀵 슬롯에 등록되어 있는 아이템이 인벤에 존재 하지 않을 때, 빈 아이템인지 다른 아이템을 등록해야 하는지 판단 // return : 바꿔야 함 (true) / 안 바꿔도 됨, 다른 아이템 정보 바꿔 줌(false) //----------------------------------------------------------------------------------------------------------------- bool SUIDisplayInfo::CheckIsChangeEmptyItem( SUIQuickSlotItemInfo*& pItemSlot, const int nSlotIndex ) { AR_HANDLE hItem( m_InventoryMgr.GetItemHandleForCode( pItemSlot->m_ItemCode ) ); if( hItem ) { pItemSlot->m_hItem = hItem; return false; } else { stEmptyItemSet stNewEmptyItemSet( pItemSlot->m_ItemCode ,static_cast(QS_WAITING), nSlotIndex ); m_ExistEmptyItem.pushEmptyItem( stNewEmptyItemSet ); return true; } return false; } void SUIDisplayInfo::EmptyItemCheckandDelete( int nSlotCount ) { std::vector::iterator it = m_ExistEmptyItem.vEmptyItems.begin(); std::vector::iterator it_e = m_ExistEmptyItem.vEmptyItems.end(); for( ; it != it_e ; ++it) { if( it->iSlotNum == nSlotCount ) { m_ExistEmptyItem.vEmptyItems.erase(it); break; } } } // 2012. 3. 28 - marine 바뀌는 슬롯이 빈 아이템인 경우를 체크해서 빈아이템 리스트의 슬롯 번호를 변경해준다. void SUIDisplayInfo::SetChangSlotIndex(int slot1, int slot2) { // bEmpty1,bEmpty2 의 값을 먼저 받고 슬롯번호를 변경해야함. bool bEmpty1 = m_ExistEmptyItem.IsEmptyItem(slot1); bool bEmpty2 = m_ExistEmptyItem.IsEmptyItem(slot2); if(bEmpty1 && bEmpty2) m_ExistEmptyItem.SwapSlotNum(slot1,slot2); else if(bEmpty1) m_ExistEmptyItem.ChangeSlotNum(slot1, slot2); else if(bEmpty2) m_ExistEmptyItem.ChangeSlotNum(slot2, slot1); } //2012. 3. 28 - marine void SUIDisplayInfo::stUsedItem::SwapSlotNum(int nSlot1, int nSlot2) { // iterater를 찾아두고 두개 모두 찾은 후에 슬롯번호를 바꿔야 문제가 없다. std::vector::iterator it = vEmptyItems.begin(); std::vector::iterator it_e = vEmptyItems.end(); std::vector::iterator it_1; std::vector::iterator it_2; for( ; it != it_e ; ++it ) { if( it->iSlotNum == nSlot1 ) it_1 = it; if( it->iSlotNum == nSlot2 ) it_2 = it; } it_1->iSlotNum = nSlot2; it_2->iSlotNum = nSlot1; } //2012. 3. 28 - marine void SUIDisplayInfo::stUsedItem::eraseEmptyItem( int nIndex ) { std::vector::iterator it = vEmptyItems.begin(); std::vector::iterator it_e = vEmptyItems.end(); for( ; it != it_e ; ++it) { if( it->iSlotNum == nIndex ) { vEmptyItems.erase(it); break; } } } //2012. 3. 28 - marine void SUIDisplayInfo::stUsedItem::ChangeSlotNum(int nBefore, int nNow) { std::vector::iterator it = vEmptyItems.begin(); std::vector::iterator it_e = vEmptyItems.end(); for( ; it != it_e ; ++it ) { if( it->iSlotNum == nBefore ) { it->iSlotNum = nNow; break; } } } bool SUIDisplayInfo::stUsedItem::IsEmptyItem(int iIndex) { std::vector::iterator it = vEmptyItems.begin(); std::vector::iterator it_e = vEmptyItems.end(); for( ; it != it_e ; ++it ) { if( it->iSlotNum == iIndex ) return true; } return false; } //2012. 3. 28 - marine 해당슬롯의 빈 아이템 셋을 리턴 const SUIDisplayInfo::stEmptyItemSet SUIDisplayInfo::GetEmptyItemSet( int nSlotCount ) { std::vector::iterator it = m_ExistEmptyItem.vEmptyItems.begin(); std::vector::iterator it_e = m_ExistEmptyItem.vEmptyItems.end(); for( ; it != it_e ; ++it ) { if( it->iSlotNum == nSlotCount ) return *it; } stEmptyItemSet ret; return ret; } //2012. 3. 28 - marine 빈아이템을 실제(원본) 아이템으로 교체 void SUIDisplayInfo::ChageToOrigianlItem(AR_HANDLE handle) { SInventorySlot *pSlot = m_InventoryMgr.GetUpdateItemInfo(handle); if(pSlot) { int nCode = pSlot->GetItemCode(); std::vector::iterator it = m_ExistEmptyItem.vEmptyItems.begin(); for( ; it != m_ExistEmptyItem.vEmptyItems.end() ; ) { if( it->iItem_Code == nCode && it->iItem_State == SUIDisplayInfo::QS_REGISTERD ) { // 2012. 4. 2 - marine 창고를 열 때는 마지막으로 없어진 아이템의 핸들이 살아있어서 실제 인벤토리에 아이템이 있는지 한번더 체크한다. AR_HANDLE temphandle = m_InventoryMgr.GetItemHandleForCode(nCode); if(temphandle) { SAFE_DELETE( m_pQuickSlots[ it->iSlotNum ] ); m_pQuickSlots[ it->iSlotNum ] = new SUIQuickSlotItemInfo( handle, pSlot->GetItemCode() ); RefreshQuickSlot( it->iSlotNum ); // 퀵슬롯 갱신 SaveQuickSlots(); // 저장 it = m_ExistEmptyItem.vEmptyItems.erase(it); } else ++it; } else ++it; } } } // 2012. 3. 28 - marine: Iterate through the empty item list, and if there is a vector in QS_WAITING state, // change it to QS_REGISTER and register a slot of empty item type in the quickslot. void SUIDisplayInfo::QuickslotEmptyItemProcess() { std::vector::iterator it = m_ExistEmptyItem.vEmptyItems.begin(); std::vector::iterator it_e = m_ExistEmptyItem.vEmptyItems.end(); bool b_RemainWaiting = false; // Check if there are any slots in the waiting state for( ; it != it_e ; ++it ) { if( it->iItem_State == QS_WAITING ) { if(m_InventoryMgr.GetItemHandleForCode( it->iItem_Code ) == 0) // Check if it has been removed from the inventory and replace it with an empty item { it->iItem_State = QS_REGISTERD; SAFE_DELETE( m_pQuickSlots[ it->iSlotNum ] ); m_pQuickSlots[ it->iSlotNum ] = new SUIQuickSlotEmptyItemInfo( it->iItem_Code ); RefreshQuickSlot( it->iSlotNum ); // 퀵슬롯 갱신 SaveQuickSlots(); // 저장 } else { b_RemainWaiting = true; DWORD time = GetSafeTickCount(); if( (time - it->dwTime) > QS_WAITING_TIME ) // QS_WAITING_TIME시간 동안 WAITING 시간이 유지 되면 리스트에서 삭제한다. { m_ExistEmptyItem.vEmptyItems.erase(it); break; } } } } m_ExistEmptyItem.setRemainWaiting(b_RemainWaiting); } void SUIDisplayInfo::UseQuickSlot( int nSlotIndex ) { const SUIQuickSlotInfo* pSlot = GetQuickSlot( nSlotIndex ); if( NULL != pSlot ) { _oprint("[void SUIDisplayInfo::UseQuickSlot( int nSlotIndex )] Time: %u; Last used time: %u\n", GetArTime(), pSlot->m_LastUsedTime); if (GetArTime() <= (pSlot->m_LastUsedTime + 1000)) return; // Fraun early return for cooldown; use skill only once per 1sec _oprint("[void SUIDisplayInfo::UseQuickSlot( int nSlotIndex )] Used!\n"); switch( pSlot->m_type ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: { const SUIQuickSlotItemInfo* pItemSlot = (SUIQuickSlotItemInfo*)pSlot; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pItemSlot->m_hItem ); if( pSlot ) { const ItemBase* pItem = (ItemBase*)GetItemDB().GetItemData( pSlot->GetItemCode() ); // { [sonador][7.7.13]염원의 깃털.퀵슬롯 사용시 오류 수정 if( pItem->nOptType[ 0 ] == 117 ) { UseItemByText( pSlot ); //텍스트로 사용하는 아이템 } else if( pItem->nOptType[ 0 ] == 119 ) // sonador #2.1.24 { SGuiObj changeNameWindow( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHANGE_NAME ); _CID( updateChangeNameWnd ); changeNameWindow->PerformKV( id_updateChangeNameWnd , KID( "current_name" ), m_PlayerInfoMgr.GetName() , KID( "item_handle" ), pSlot->GetHandle() , KID( "target_handle" ), m_PlayerInfoMgr.GetPlayerHandle() ); m_pGameManager->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHANGE_NAME, true, true ) ); } else if( pSlot->GetItemCode() == 920004 ) { ChangeCreatureName(); } else if( pSlot->GetItemCode() == 920010 ) { ChangePetName(); } else { if (checkUseEqualHairTypeItem(pItem)) return ; // 2010.08.06 - prodongi int msgId; if (!checkEnableUseItem(pItem, pSlot->GetItemCode(), this, msgId)) { SetSysMsg( msgId ); return ; } if( pItem->CheckFlag( ItemBase::ITEM_FLAG::FLAG_TARGET_USE ) ) UseOrEquipItem( pItemSlot->m_hItem, NULL, false, true ); else UseOrEquipItem( pItemSlot->m_hItem ); /// 2011.07.07 - prodongi m_pGameManager->PostMsgAtDynamic(new SIMSG_UI_OPEN_BADGE(pSlot->GetItemCode())); } } else { UseOrEquipItem( pItemSlot->m_hItem ); } } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: { const SUIQuickSlotSkillInfo* pSkillSlot = (SUIQuickSlotSkillInfo*)pSlot; if (pSkillSlot->m_bEnable) UseSkill( pSkillSlot->m_nSkillID, pSkillSlot->m_nSkillLevel, pSkillSlot->m_bPlayer, pSkillSlot->m_hTarget ); } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: { const SUIQuickSlotMotionInfo* pMotionSlot = (SUIQuickSlotMotionInfo*)pSlot; UseMotion( pMotionSlot->m_nMotionID ); } break; case SUIQuickSlotInfo::QSLOTTYPE_EMPTYITEM: { m_pGameManager->GetActiveGame()->AddChatMessage(S(2951)); // 2951: 보유하지 않는 아이템은 사용할 수 없습니다. } break; } } } const QUICKSLOT_DISPLAYINFO* SUIDisplayInfo::GetQuickSlotDisplayInfo( int nSlotIndex ) const { const SUIQuickSlotInfo* pSlot = GetQuickSlot( nSlotIndex ); return (NULL != pSlot) ? &(pSlot->DisplayInfo) : NULL; } //bool SUIDisplayInfo::CheckSkillInfo( QUICKSLOT_BTNSTATE State, int nSlotIndex, int nSkillID ) /*bool SUIDisplayInfo::CheckSkillInfo(AR_HANDLE caster, int nSlotIndex, int nSkillID ) { const SUIQuickSlotInfo* pSlot = GetQuickSlot( nSlotIndex ); if( NULL != pSlot && SUIQuickSlotInfo::QSLOTTYPE_SKILL == pSlot->m_type ) // skill인 경우만 { int nSlotSkillID = ((SUIQuickSlotSkillInfo*)pSlot)->m_nSkillID; if( nSlotSkillID == nSkillID ) return true; } return false; }*/ //bool SUIDisplayInfo::GetQuickSlotClockInfo( QUICKSLOT_BTNSTATE State, int nSlotIndex, DWORD& rCurrentTime, DWORD& rMaxTime ) bool SUIDisplayInfo::GetQuickSlotClockInfo( int nSlotIndex, DWORD& rCurrentTime, DWORD& rMaxTime ) { rCurrentTime = 0; rMaxTime = 0; const SUIQuickSlotInfo* pSlot = GetQuickSlot( nSlotIndex ); if( NULL != pSlot && SUIQuickSlotInfo::QSLOTTYPE_SKILL == pSlot->m_type ) // skill인 경우만 { int nSkillID = ((SUIQuickSlotSkillInfo*)pSlot)->m_nSkillID; if(((SUIQuickSlotSkillInfo*)pSlot)->m_bPlayer) { if( m_SkillSlotMgr.IsCastingSkill( nSkillID ) ) return false; if( m_SkillSlotMgr.IsFireSkill( nSkillID ) ) // 현재 사용중이면 시간값을 설정 { rCurrentTime = m_SkillSlotMgr.GetSkillCurTime(nSkillID); rMaxTime = m_SkillSlotMgr.GetSkillMaxTime(nSkillID); } } else { if( m_CreatureSkillSlotMgr.IsCastingSkill( nSkillID,((SUIQuickSlotSkillInfo*)pSlot)->m_hTarget ) ) return false; if( m_CreatureSkillSlotMgr.IsFireSkill( nSkillID,((SUIQuickSlotSkillInfo*)pSlot)->m_hTarget ) ) // 현재 사용중이면 시간값을 설정 { rCurrentTime = m_CreatureSkillSlotMgr.GetSkillCurTime(nSkillID,((SUIQuickSlotSkillInfo*)pSlot)->m_hTarget); rMaxTime = m_CreatureSkillSlotMgr.GetSkillMaxTime(nSkillID,((SUIQuickSlotSkillInfo*)pSlot)->m_hTarget); } } if( nSkillID == 6101 || nSkillID == 6102 ) { rCurrentTime = m_InventoryMgr.GetItemCurCoolTime( 38 ); rMaxTime = m_InventoryMgr.GetItemMaxCoolTime( 38 ); } } else if( NULL != pSlot && SUIQuickSlotInfo::QSLOTTYPE_ITEM == pSlot->m_type ) // Item인 경우만 { AR_HANDLE item_handle = ((SUIQuickSlotItemInfo*)pSlot)->m_hItem; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( item_handle ); if( pSlot ) { const ItemBaseEx_info * pItemInfo = GetItemDB().GetItemData( pSlot->GetItemCode() ); if( pItemInfo->nType == ItemBase::TYPE_USEABLE || pItemInfo->nType == ItemBase::TYPE_USE ) { pItemInfo->nCoolTimeGroup; //아이템 쿨타임 그룹 rCurrentTime = m_InventoryMgr.GetItemCurCoolTime( (pItemInfo->nCoolTimeGroup-1) ); rMaxTime = m_InventoryMgr.GetItemMaxCoolTime( (pItemInfo->nCoolTimeGroup-1) ); } } } else if( NULL != pSlot && SUIQuickSlotInfo::QSLOTTYPE_MOTION == pSlot->m_type ) // Motion인 경우만 { int nMotionTyep = ((SUIQuickSlotMotionInfo*)pSlot)->m_nMotionCommandID; if( nMotionTyep == MOTION_ATTACK ) //공격 모션만 적용할때 { if( m_MotionMgr.IsCastingMotion( MOTION_ATTACK ) ) return false; if( m_MotionMgr.IsShootingMotion( MOTION_ATTACK ) ) { rCurrentTime = m_MotionMgr.GetSkillCurTime( nMotionTyep ); rMaxTime = m_MotionMgr.GetSkillMaxTime( nMotionTyep ); } } } return true; } std::string SUIDisplayInfo::GetMotionAniName( int nID ) { std::string strAniName; switch( nID ) { case ID_ATTACK : strAniName = "icon_order_0001"; break;// 공격 case ID_STANDUP : strAniName = "icon_order_0002"; break;// 앉기 case ID_PICKUP : strAniName = "icon_order_0003"; break;// 줍기 case ID_ASSIST : strAniName = "icon_order_0004"; break;// 어시스트 case ID_TRADE : strAniName = "icon_order_0005"; break;// 트레이드 case ID_CREATURE_ATTACK : strAniName = "icon_order_0006"; break;// 크리처공격 case ID_CREATURE_ALLATTACK : strAniName = "icon_order_0007"; break;// 크리처합동공격 case ID_CREATURE_BACKDOWN : strAniName = "icon_order_0008"; break;// 따르기 case ID_PKMODE : strAniName = "icon_order_0009"; break;// PK Mode case ID_COMBINE : strAniName = "icon_order_0010"; break;// 조합 case ID_BOOTH : strAniName = "icon_order_0011"; break;// 노점 case ID_RUN : strAniName = "icon_order_0012"; break;// 걷기/뛰기 case ID_MOUNT : strAniName = "icon_order_0013"; break;// 크리처타기 case ID_HI : strAniName = "icon_emotion_0001"; break;// 인사 case ID_BOW : strAniName = "icon_emotion_0002"; break;// 격식인사 case ID_HAPPY : strAniName = "icon_emotion_0003"; break;// 기쁨 case ID_SORROW : strAniName = "icon_emotion_0004"; break;// 슬픔 case ID_YES : strAniName = "icon_emotion_0005"; break;// 긍정 case ID_NO : strAniName = "icon_emotion_0006"; break;// 부정 case ID_BORING : strAniName = "icon_emotion_0007"; break;// 지루 case ID_APOLOGIZE : strAniName = "icon_emotion_0008"; break;// 사과 case ID_CHEER : strAniName = "icon_emotion_0009"; break;// 파이팅 case ID_POUT : strAniName = "icon_emotion_0010"; break;// 토라짐 case ID_DANCE : strAniName = "icon_emotion_0011"; break;// 춤 case ID_CLAP : strAniName = "icon_emotion_0012"; break;// 박수 case ID_ANGRY : strAniName = "icon_emotion_0013"; break;// 화남 case ID_PROVOKE : strAniName = "icon_emotion_0014"; break;// 약올림 case ID_PARTY_CREATE : strAniName = "icon_order_0014"; break;// 파티생성 case ID_PARTY_INVITE : strAniName = "icon_order_0015"; break;// 파티초대 case ID_PICKUP_CARD : strAniName = "icon_order_0003"; break;// 줍기 // AziaMafia ADD EMOTE case ID_TP: strAniName = "motion_normal_icon30"; break;// 파티초대 case ID_LOOT: strAniName = "motion_normal_icon31"; break;// 파티초대 case ID_TAME: strAniName = "motion_normal_icon32"; break;// 파티초대 case ID_BUFF: strAniName = "motion_normal_icon33"; break;// 파티초대 case ID_BUFFGUILD: strAniName = "motion_normal_icon34"; break;// 파티초대 case ID_TPTAMINGZONE: strAniName = "motion_normal_icon35"; break;// 파티초대 case ID_ATRADE: strAniName = "motion_normal_icon36"; break;// 파티초대 default : { assert(0 && "새 ID 추가 하자" ); strAniName = "static_common_itemslot"; } break; } return strAniName; } //const char* SUIDisplayInfo::GetRankIconAniName( int nRank ) //{ // static const char* c_RankIconNames[] = // { // "", // "icon_common_rank1", // "icon_common_rank2", // "icon_common_rank3", // "icon_common_rank4", // "icon_common_rank5", // "icon_common_rank6", // }; // const char c_nRankIconCount = sizeof(c_RankIconNames) / sizeof(const char*); // // return (0 <= nRank && nRank < c_nRankIconCount) // ? c_RankIconNames[ nRank ] : ""; //} //////////////////////////////////////////////////////////////// // // 지속효과 // //////////////////////////////////////////////////////////////// std::string SUIDisplayInfo::GetStateToolTipText( int nStateID /* state code=상태이상 아이디 */, AR_TIME end_time, int nStateLevel, int nStateValue, bool bToggle, bool bDetail/*=true*/, bool bTime/*=true*/ ) { std::string StateTooltip, strTime; if ( nStateID == 9005 || nStateID == 9006 ) StateTooltip = SR( GetTenacityDB().GetToolTipID( nStateID ), "#@value@#", nStateValue ); else StateTooltip = SR( GetTenacityDB().GetToolTipID(nStateID), "#@time@#", "" ); // StateTooltip = SR( GetTenacityDB().GetToolTipID(nStateID), "#@time@#", "", "#@level@#", nStateLevel ); if( bDetail ) { StateTooltip.insert(0,""); std::string EffectSateTooltip = GetStateCaseToolTipText( nStateID, nStateLevel ); if( !EffectSateTooltip.empty() ) StateTooltip += EffectSateTooltip; if( !bToggle && bTime ) { float CrrTime( GetArTime() ); float fTime( (end_time-CrrTime)/100.0f ); if( CrrTime>end_time && fTime<1.0f ) { // strTime = "0"; // strTime += S(7025); } else { strTime = GetCutTimeString( (end_time-GetArTime())/100.0f, 2 ).c_str(); } if( !strTime.empty() ) { if( bDetail ) { StateTooltip += "
"; StateTooltip += strTime; } } } } else { std::string::size_type Pos = StateTooltip.find("<#ffffff>"); if( Pos != std::string::npos ) { StateTooltip.erase(Pos, StateTooltip.size()-1); StateTooltip.insert(0, ""); } } return StateTooltip; } std::string SUIDisplayInfo::CheckPositiveText( float fNum, bool bAmplify ) { std::string strTemp; if( fNum > 0 ) { strTemp = "+"; if( fNum - (int)fNum > 0 ) { if( bAmplify ) strTemp += "%.1f%%"; // sonador 10.4.1 스킬 툴팁 리뉴얼 else strTemp += "%.1f"; // 2010.06.10 - prodongi //fNum -= 0.05f; fNum += 0.005f; /// 2011.04.13 소수점 오차 때문에 더함, 더 좋은 해결책이 있다면 해결 바랍니다. - prodongi strTemp = rp::getRevisionFloat(fNum, 1, strTemp); /// 2012.01.02 XStringUtil::Format함수에서는 암시적으로 반올림이 되버리기 때문에 반올림 안시키는 함수를 호출 - prodongi } else { if( bAmplify ) strTemp += "%d%%"; else strTemp += "%d"; XStringUtil::Format(strTemp, strTemp.c_str(), (int)fNum); } } // floyd 2010. 4. 19 else if ( fNum < 0 ) { if( fNum - (int)fNum < 0 ) { if( bAmplify ) strTemp += "%.1f%%"; else strTemp += "%.1f"; // 2010.06.10 - prodongi fNum -= 0.005f; strTemp = rp::getRevisionFloat(fNum, 1, strTemp); /// 2012.01.02 XStringUtil::Format함수에서는 암시적으로 반올림이 되버리기 때문에 반올림 안시키는 함수를 호출 - prodongi } else { if( bAmplify ) strTemp += "%d%%"; else strTemp += "%d"; XStringUtil::Format(strTemp, strTemp.c_str(), (int)fNum); } } return strTemp; } std::string SUIDisplayInfo::GetStateBaseEffectCaseToolTipText( int nStateID, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) // sonador 10.4.2 지속효과 기본공격 반영률 관련 오류 수정 { std::string Tooltip; StateInfoEx* pState(NULL); pState = GetTenacityDB().GetTenacityData( nStateID ); if( pState == NULL ) return Tooltip; switch( pState->base_effect_id ) { case StateInfo::STATE_FX_BASE_NONE: break; case StateInfo::STATE_FX_BASE_CONTINUAL_PHYSICAL_DAMAGE: Tooltip = BasicStateFxTooltip_PhysicalDamage( pState, nStateLevel, userAttr, itemAttr ); break; case StateInfo::STATE_FX_BASE_CONTINUAL_MAGICAL_DAMAGE: Tooltip = BasicStateFxTooltip_MagicalDamage( pState, nStateLevel, userAttr, itemAttr ); break; case StateInfo::STATE_FX_BASE_CONTINUAL_PHYSICAL_DAMAGE_IGNORE_DEFENSE: Tooltip = BasicStateFxTooltip_PhysicalDamageIgnoreDefense( pState, nStateLevel, userAttr, itemAttr ); break; case StateInfo::STATE_FX_BASE_CONTINUAL_MAGICAL_DAMAGE_IGNORE_DEFENSE: Tooltip = BasicStateFxTooltip_MagicalDamageIgnoreDefense( pState, nStateLevel, userAttr, itemAttr ); break; case StateInfo::STATE_FX_BASE_MAGICAL_HP_RESTORATION: Tooltip = BasicStateFxTooltip_HpRestoration( pState, nStateLevel, userAttr, itemAttr ); break; case StateInfo::STATE_FX_BASE_MAGICAL_MP_RESTORATION: Tooltip = BasicStateFxTooltip_MpRestoration( pState, nStateLevel, userAttr, itemAttr ); break; } return Tooltip; } // 2010.05.17 - prodongi std::string SUIDisplayInfo::GetStateCaseToolTipText( int nStateID, int nStateLevel, int skillLevel ) const //std::string SUIDisplayInfo::GetStateCaseToolTipText( int nStateID, int nStateLevel ) { //TODO:지속효과 유형 관련해서 구현이 덜되어있음. DATA)스킬.xsl의 지속효과유형 탭을 참조하여 작성 할 것. 2009.03.06 sfreer std::string Tooltip; StateInfoEx* pState(NULL); pState = GetTenacityDB().GetTenacityData( nStateID ); if( pState == NULL ) return Tooltip; switch( pState->effect_type ) { case StateInfo::STATE_PARAMETER_INCREASE: //7153//"#@bitset_text@# +#@value@#" Tooltip = ParameterIncrease( pState, nStateLevel ); break; case StateInfo::STATE_PARAMETER_AMPLIFY: //7153//"#@bitset_text@# +#@value@#" Tooltip = ParameterAmplify( pState, nStateLevel ); break; case StateInfo::STATE_PARAMETER_INCREASE_SHIELD: //7155//"방패 장착 시 #@bitset_text@# +#@value@#" case StateInfo::STATE_PARAMETER_INCREASE_SHIELD_2: Tooltip = ParameterIncreaseEquipShild( pState, nStateLevel ); break; case StateInfo::STATE_BLESS_OF_GODDESS: Tooltip = getStateTooltipBlessOfGoddess( pState, nStateLevel ); break; // 2010.05.14 - prodongi case StateInfo::STATE_PARAMETER_SYNC: // #@bitset_text@#와 #@bitset_text@#를 동기화한다. Tooltip = ParameterSync(pState, nStateLevel); break; // 2010.07.07 - prodongi case StateInfo::STATE_ATTACK_TO_TARGET: // 2010.05.17 - prodongi case StateInfo::STATE_ATTACKED_TO_ATTACKER: Tooltip = AttackerAddState(pState, nStateLevel); break; // 2010.08.11 - prodongi case StateInfo::STATE_ATTACK_TO_MY: case StateInfo::STATE_ATTACKED_TO_MY: Tooltip = MyAddState(pState, nStateLevel); break; case StateInfo::STATE_DOUBLE_ATTACK: //7156//"#@weapon_type@# 장착 시 #@probability@#%의 확률로 추가 공격" Tooltip = DoubleAttack( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_ADD_DAMAGE: //7157//"기본 공격 시 #@probability#@%의 확률로 +#@value@# 추가 데미지" Tooltip = AttackAddDamege( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_ADD_DAMAGE_RATE: //7158//"기본 공격 시 #@probability#@%의 확률로 데미지의 #@value@#%만큼 추가 데미지" Tooltip = AttackAddDamegeRate( pState, nStateLevel ); break; case StateInfo::STATE_MAGIC_ADD_DAMAGE: //7159//"스킬 공격 시 #@probability#@%의 확률로 +#@value@# 추가 데미지" Tooltip = MagicAddDemage( pState, nStateLevel ); break; case StateInfo::STATE_MAGIC_ADD_DAMAGE_RATE: //7160//"스킬 공격 시 #@probability#@%의 확률로 데미지의 #@value@#%만큼 추가 데미지" Tooltip = MagicAddDemageRate( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_ADD_STATE: //7161//"기본 공격시 #@probability#@% 확률로 #@state_name@# 부가" Tooltip = AttackAddState( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_RECOVERY: //7162//"기본 공격시 #@probability#@% 확률로 #@point_name@# #@value@# 회복" Tooltip = AttackRecovery( pState, nStateLevel ); break; case StateInfo::STATE_ADD_HP_MP_WHEN_CRITICAL: // { 1607, 0, "크리티컬 성공시 #@probability@#% 확률로 #@point_name@# #@value@# 회복" }, Tooltip = HpMpRecoveryWhenCritial( pState, nStateLevel ); break; case StateInfo::STATE_AMPLIFY_SKILL_HEAL_AMOUNT: Tooltip = AmplifySkillHealAmount( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_RECOVERY_RATE: //7163//"기본 공격시 #@probability#@% 확률로 데미지의 #@value@#%만큼 #@point_name@# 회복" Tooltip = AttackRecoveryRate( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_ABSORB: //7164//"기본 공격시 #@probability#@% 확률로 #@point_name@# #@value@# 스틸" Tooltip = AttackAbsorb( pState, nStateLevel ); break; case StateInfo::STATE_BEATTACKED_REFLECTION: //7165//"피격 시 #@probability#@% 확률로 데미지의 #@value@#%만큼 반사" Tooltip = BeAttackedReflection( pState, nStateLevel ); break; case StateInfo::STATE_BEATTACKED_REFLECTION_IGNORE_DEFENSE: //7166//"피격 시 #@probability#@% 확률로 #@value@#의 데미지 반사" Tooltip = BeAttackedReflectionIgnoreDefense( pState, nStateLevel ); break; case StateInfo::STATE_DECREASE_DAMAGE_BY_RATE: Tooltip = ReduceDamageAllType( pState, nStateLevel ); break; case StateInfo::STATE_TRANSFER_DAMAGE_TO_MP: Tooltip = TransferDamageToMP( pState, nStateLevel ); break; case StateInfo::STATE_REALTIME_MAINTENANCE_RECOVERY: //7167//"100초마다 #@point_name@# #@value@# 회복" Tooltip = RealtimeMainTenanceRecovery( pState, nStateLevel ); break; case StateInfo::STATE_RECOVERY_HP_MP: /// 2011.04.05 - prodongi Tooltip = getStateToolTipRecoveryHpMp(pState, nStateLevel); break; case StateInfo::STATE_RECOVERY_HP: /// 2011.04.26 - prodongi Tooltip = getStateToolTipRecoveryHp(pState, nStateLevel); break; case StateInfo::STATE_INCAPACITATE_STATE: //7168//"#@state_name@#을 무력화." Tooltip = IncapacitateSate( pState, nStateLevel ); break; case StateInfo::STATE_IMPOSSIBLE_ACTION: //7169//"#@command_name@# 불가" Tooltip = ImpossibleAction( pState, nStateLevel ); break; case StateInfo::STATE_INCREASE_HATE: Tooltip = IncreaseHate( pState, nStateLevel ); break; case StateInfo::STATE_INCREASE_INTIMIDATION: Tooltip = IncreaseIntimidation( pState, nStateLevel ); break; case StateInfo::STATE_INTERRUPT_SKILL: Tooltip = InterruptSkill( pState, nStateLevel ); break; case StateInfo::STATE_ADD_STATE_IN_REGION: Tooltip = AddStateInRegion( pState, nStateLevel ); break; case StateInfo::STATE_DECREASE_MP_CONSUMPTION: //7170//"MP 소모량 #@value@#%" Tooltip = DecreaseMpConsumption( pState, nStateLevel ); break; case StateInfo::STATE_INCREASE_POWER_CRI_AG_COOL: //7153//"#@bitset_text@# +#@value@#" Tooltip = Increase_Power_Cri_Ag_Cool( pState, nStateLevel ); break; case StateInfo::STATE_SKILL_INCREASE_POWER_CRI_AG_COOL: //7153//"#@bitset_text@# +#@value@#" Tooltip = SkillIncrease_Power_Cri_Ag_Cool( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_KNOCKBACK: //7171//"기본 공격시 #@probability#@% 확률로 넉백 효과 발생" Tooltip = AttackKnockBack( pState, nStateLevel ); break; case StateInfo::STATE_ATTACK_RANGETYPE: //7172//"기본 공격시 #@probability#@% 확률로 범위 데미지 효과 발생" Tooltip = AttackRangeType( pState, nStateLevel ); break; case StateInfo::STATE_SELF_REBIRTH: Tooltip = SelfRebirth( pState, nStateLevel ); break; case StateInfo::STATE_DETECT_HIDING: Tooltip = DetectHiding( pState, nStateLevel ); break; case StateInfo::STATE_RIDING: Tooltip = RidingForSpeedUp( pState, nStateLevel ); break; /// 2011.03.07 - prodongi case StateInfo::STATE_INVULNERABLENESS: Tooltip = getStateToolTipInvulnerableness(pState); break; case StateInfo::STATE_ADD_STATE_TO_MY_WHEN_KILL_TARGET: Tooltip = getStateToolTipAddStateWhenKillTarget(pState, nStateLevel, false); break; case StateInfo::STATE_ADD_STATE_TO_TARGET_WHEN_CRITICAL_ATTACK: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 7099, 7091, 7095); break; case StateInfo::STATE_ADD_STATE_TO_MY_WHEN_CRITICAL_ATTACK: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 7099, 7091, 7096); break; case StateInfo::STATE_ADD_STATE_TO_ATTACKER_WHEN_CRITICAL_ATTACKED: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 7100, 7091, 7097); break; case StateInfo::STATE_ADD_STATE_TO_MY_WHEN_CRITICAL_ATTACKED: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 7100, 7091, 7096); break; case StateInfo::STATE_ADD_STATE_TO_ATTACKER_WHEN_AVOIDANCE: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 8027, 7092, 7097); break; case StateInfo::STATE_ADD_STATE_TO_MY_WHEN_AVOIDANCE: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 8027, 7092, 7096); break; case StateInfo::STATE_ADD_STATE_TO_ATTACKER_WHEN_SHIELD_BLOCK: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 8027, 7093, 7097); break; case StateInfo::STATE_ADD_STATE_TO_MY_WHEN_SHIELD_BLOCK: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 8027, 7093, 7096); break; case StateInfo::STATE_ADD_STATE_TO_ATTACKER_SHIELD_PERFECT_BLOCK: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 8027, 7094, 7097); break; case StateInfo::STATE_ADD_STATE_TO_MY_SHIELD_PERFECT_BLOCK: Tooltip = getStateToolTipAddStateWhenType1(pState, nStateLevel, 8027, 7094, 7096); break; case StateInfo::STATE_INFINITY_SUMMON_RECALL: Tooltip = getStateToolTipInfinitySummonRecall(pState); break; /// 2011.03.21 - prodongi case StateInfo::STATE_RANGE_TYPE_MODIFY_DAMAGE: Tooltip = getStateToolTipRangeTypeModifyDamage(pState, nStateLevel); break; case StateInfo::STATE_ATTACKED_DEC_DAMAGE: Tooltip = getStateToolTipAttackedDecDamage(pState, nStateLevel); break; case StateInfo::STATE_ATTACK_AMPLIFY_ATT_DAMAGE: Tooltip = getStateToolTipAttackAmplifyAttDamage(pState, nStateLevel); break; case StateInfo::STATE_ATTACKED_ADD_DAMAGE: Tooltip = getStateToolTipAttackedAddDamage(pState, nStateLevel); break; case StateInfo::STATE_ADD_STATE_DAMAGE: Tooltip = getStateToolTipAddStateDamage(pState, nStateLevel); break; case StateInfo::STATE_AMPLIFY_STATE_DAMAGE: Tooltip = getStateToolTipAmplifyStateDamage(pState, nStateLevel); break; case StateInfo::STATE_NOT_CONSUMPTION_ENERGY: Tooltip = getStateToolTipNotConsumptionEnergy(pState, nStateLevel); break; case StateInfo::STATE_ADD_STATE_TO_MY_WHEN_DEAD: Tooltip = getStateToolTipAddStateWhenKillTarget(pState, nStateLevel, true); break; case StateInfo::STATE_AUTO_RESURRECTION: Tooltip = getStateToolTipAutoResurrection(pState, nStateLevel); break; } return Tooltip; } std::string SUIDisplayInfo::BuildEnumString( std::vector& rStdList, std::string tag ) { std::string temp; int size( rStdList.size() ); if( size == 0 ) return temp; for(int i(0); i strList; typedef unsigned int UI; if( (UI)BisetID & StateInfo::STR ) strList.push_back( SR(strID,"#@bitset_text@#", S(7101), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::VIT ) strList.push_back( SR(strID,"#@bitset_text@#", S(7102), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::DEX ) strList.push_back( SR(strID,"#@bitset_text@#", S(7103), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::AGI ) strList.push_back( SR(strID,"#@bitset_text@#", S(7104), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::INT ) strList.push_back( SR(strID,"#@bitset_text@#", S(7105), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MEN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7106), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::LUCK ) strList.push_back( SR(strID,"#@bitset_text@#", S(7107), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::PHYSICS ) strList.push_back( SR(strID,"#@bitset_text@#", S(7108), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MAGIC ) strList.push_back( SR(strID,"#@bitset_text@#", S(7109), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::PHY_DEF ) strList.push_back( SR(strID,"#@bitset_text@#", S(7110), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MGC_DEF ) strList.push_back( SR(strID,"#@bitset_text@#", S(7111), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::A_SPEED ) strList.push_back( SR(strID,"#@bitset_text@#", S(7112), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::C_SPEED ) strList.push_back( SR(strID,"#@bitset_text@#", S(7113), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::M_SPEED ) strList.push_back( SR(strID,"#@bitset_text@#", S(7114), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::ACCURACY ) strList.push_back( SR(strID,"#@bitset_text@#", S(7115), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MGS_ACRC ) strList.push_back( SR(strID,"#@bitset_text@#", S(7116), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::CRI ) strList.push_back( SR(strID,"#@bitset_text@#", S(7117), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::BLOCK ) strList.push_back( SR(strID,"#@bitset_text@#", S(7118), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::BLC_DEF ) strList.push_back( SR(strID,"#@bitset_text@#", S(7119), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::AVOIDANCE ) strList.push_back( SR(strID,"#@bitset_text@#", S(7120), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MGS_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7121), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MAXHP ) strList.push_back( SR(strID,"#@bitset_text@#", S(7122), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MAXMP ) strList.push_back( SR(strID,"#@bitset_text@#", S(7123), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MAXSP ) strList.push_back( SR(strID,"#@bitset_text@#", S(7124), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::HP_RECVRY ) strList.push_back( SR(strID,"#@bitset_text@#", S(7125), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MP_RECVRY ) strList.push_back( SR(strID,"#@bitset_text@#", S(7126), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::SP_RECVRY ) strList.push_back( SR(strID,"#@bitset_text@#", S(7127), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::HP_REGEN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7128), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MP_REGEN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7129), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::CRI_POWER ) strList.push_back( SR(strID,"#@bitset_text@#", S(7261), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::POSSESS ) strList.push_back( SR(strID,"#@bitset_text@#", S(7130), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( !strList.empty() ) { std::string ret = BuildEnumString(strList, " / "); strList.clear(); return ret; } return ""; } std::string SUIDisplayInfo::Get_B_BitSetText( unsigned int strID, double BisetID, double dValue, bool bAmplify ) { std::vector strList; typedef unsigned int UI; if( (UI)BisetID & StateInfo::NOR_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7131), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::FIRE_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7132), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::WATER_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7133), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::WIND_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7134), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::EARTH_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7135), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::LIGHT_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7136), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::DARK_RESIST ) strList.push_back( SR(strID,"#@bitset_text@#", S(7137), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); /// 2011.03.30 - prodongi if( (UI)BisetID & StateInfo::PBLOCK_CHANCE ) strList.push_back( SR(strID,"#@bitset_text@#", S(9778), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::ADEF_IGNORE ) strList.push_back( SR(strID,"#@bitset_text@#", S(9779), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MDEF_IGNORE ) strList.push_back( SR(strID,"#@bitset_text@#", S(9780), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::ADEM_PENETRATION ) strList.push_back( SR(strID,"#@bitset_text@#", S(9781), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::MDEM_PENETRATION ) strList.push_back( SR(strID,"#@bitset_text@#", S(9782), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::NOR_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7138), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::FIRE_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7139), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::WATER_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7140), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::WIND_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7141), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::EARTH_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7142), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::LIGHT_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7143), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::DARK_CONTN ) strList.push_back( SR(strID,"#@bitset_text@#", S(7144), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::NOR_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7145), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::FIRE_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7146), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::WATER_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7147), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::WIND_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7148), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::EARTH_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7149), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::LIGHT_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7150), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::DARK_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7151), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( (UI)BisetID & StateInfo::CRI_DAG ) strList.push_back( SR(strID,"#@bitset_text@#", S(7152), "#@value@#", CheckPositiveText(dValue, bAmplify).c_str()) ); if( !strList.empty() ) { std::string ret = BuildEnumString(strList, " / "); strList.clear(); return ret; } return ""; } // 2010.05.14 - prodongi std::string SUIDisplayInfo::Get_C_BitSetText( unsigned int strID, double BisetID, double dValue, bool /*bAmplify*/ ) { std::vector strList; typedef unsigned int UI; if( (UI)BisetID & StateInfo::STR ) strList.push_back(S(7101)); if( (UI)BisetID & StateInfo::VIT ) strList.push_back(S(7102)); if( (UI)BisetID & StateInfo::DEX ) strList.push_back(S(7103)); if( (UI)BisetID & StateInfo::AGI ) strList.push_back(S(7104)); if( (UI)BisetID & StateInfo::INT ) strList.push_back(S(7105)); if( (UI)BisetID & StateInfo::MEN ) strList.push_back(S(7106)); if( (UI)BisetID & StateInfo::LUCK ) strList.push_back(S(7107)); if( (UI)BisetID & StateInfo::PHYSICS ) strList.push_back(S(1735)); if( (UI)BisetID & StateInfo::MAGIC ) strList.push_back(S(1736)); if( (UI)BisetID & StateInfo::PHY_DEF ) strList.push_back(S(1737)); if( (UI)BisetID & StateInfo::MGC_DEF ) strList.push_back(S(1738)); if( (UI)BisetID & StateInfo::A_SPEED ) strList.push_back(S(1739)); if( (UI)BisetID & StateInfo::C_SPEED ) strList.push_back(S(1740)); if( (UI)BisetID & StateInfo::M_SPEED ) strList.push_back(S(1741)); if( (UI)BisetID & StateInfo::ACCURACY ) strList.push_back(S(1742)); if( (UI)BisetID & StateInfo::MGS_ACRC ) strList.push_back(S(1743)); if( (UI)BisetID & StateInfo::CRI ) strList.push_back(S(1744)); if( (UI)BisetID & StateInfo::BLOCK ) strList.push_back(S(1745)); if( (UI)BisetID & StateInfo::BLC_DEF ) strList.push_back(S(7119)); if( (UI)BisetID & StateInfo::AVOIDANCE ) strList.push_back(S(1746)); if( (UI)BisetID & StateInfo::MGS_RESIST ) strList.push_back(S(1747)); if( (UI)BisetID & StateInfo::MAXHP ) strList.push_back(S(1748)); if( (UI)BisetID & StateInfo::MAXMP ) strList.push_back(S(1749)); if( (UI)BisetID & StateInfo::MAXSP ) strList.push_back(S(7124)); if( (UI)BisetID & StateInfo::HP_RECVRY ) strList.push_back(S(1750)); if( (UI)BisetID & StateInfo::MP_RECVRY ) strList.push_back(S(1751)); if( (UI)BisetID & StateInfo::SP_RECVRY ) strList.push_back(S(7127)); if( (UI)BisetID & StateInfo::HP_REGEN ) strList.push_back(S(1752)); if( (UI)BisetID & StateInfo::MP_REGEN ) strList.push_back(S(1753)); if( (UI)BisetID & StateInfo::CRI_POWER ) strList.push_back(S(7261)); if( (UI)BisetID & StateInfo::POSSESS ) strList.push_back(S(7130)); if (2 != strList.size()) { strList.clear(); return "invalid bit"; } std::string strValue; XStringUtil::Format(strValue, "%d", (int)(dValue * 100.0f)); //std::string strParse = "#@bitset_text@#과 #@bitset_text2@#을 #@value@#%로 동기화 한다."; std::string strParse = S(1754); XStringUtil::Replace(strParse, "#@bitset_text@#", strList[0].c_str()); XStringUtil::Replace(strParse, "#@bitset_text2@#", strList[1].c_str()); XStringUtil::Replace(strParse, "#@value@#", strValue.c_str()); strList.clear(); return strParse; } std::string SUIDisplayInfo::GetFirstStateBitSetText( StateInfoEx* pState, int strID, int pos, int nStateLevel, bool bAmplify ) const { if( pState == NULL ) return ""; double dID(0); double dValue(0); pState->GetBitSetData( pos, nStateLevel, dID, dValue ); if( bAmplify ) dValue *= 100.0f; return Get_A_BitSetText( strID, dID, dValue, bAmplify ); } std::string SUIDisplayInfo::GetSecondStateBitSetText( StateInfoEx* pState, int strID, int pos, int nStateLevel, bool bAmplify ) const { if( pState == NULL ) return ""; double dID(0); double dValue(0); pState->GetBitSetData( pos, nStateLevel, dID, dValue ); if( bAmplify ) dValue *= 100.0f; return Get_B_BitSetText( strID, dID, dValue, bAmplify ); } // 2010.05.14 - prodongi std::string SUIDisplayInfo::GetThirdStateBitSetText( StateInfoEx* pState, int strID, int pos, int nStateLevel, bool bAmplify ) const { if( pState == NULL ) return ""; double dID(0); double dValue(0); pState->GetBitSetData( pos, nStateLevel, dID, dValue ); if( bAmplify ) dValue *= 100.0f; return Get_C_BitSetText( strID, dID, dValue, bAmplify ); } std::string SUIDisplayInfo::GetWeaponText( std::vector& rWeaponList ) const { // Fraun performance tweak std::string str; int size( rWeaponList.size() ); if( size == 0 ) return str; std::vector strWeaponList; for( int i(0); ifire_interval; int elementalType = pState->elemental_type; int addDamage = ( userAttr.nAttackPointRight + itemAttr.nAttackPointRight ) * pState->GetBasicFx_AmpDamage( nStateLevel ) + pState->GetBasicFx_AddDamage( nStateLevel ); tooltip = SR( 1620, "#@state_time@#", GetTimeString( fxPeriod ).c_str(), "#@elemental_dmg_type@#", S( 7138 + elementalType ), "#@damage@#", addDamage ); return tooltip; } std::string SUIDisplayInfo::BasicStateFxTooltip_PhysicalDamageIgnoreDefense( StateInfoEx* pState, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) { // { 1621, 0, "매 #@state_time@# 마다 방어력을 무시한 #@damage@# #@elemental_dmg_type@#" }, std::string tooltip, strTemp; if( pState == NULL ) return tooltip; int fxPeriod = pState->fire_interval; int elementalType = pState->elemental_type; int addDamage = ( userAttr.nAttackPointRight + itemAttr.nAttackPointRight ) * pState->GetBasicFx_AmpDamage( nStateLevel ) + pState->GetBasicFx_AddDamage( nStateLevel ); tooltip = SR( 1621, "#@state_time@#", GetTimeString( fxPeriod ).c_str(), "#@elemental_dmg_type@#", S( 7138 + elementalType ), "#@damage@#", addDamage ); return tooltip; } std::string SUIDisplayInfo::BasicStateFxTooltip_MagicalDamage( StateInfoEx* pState, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) { // { 1620, 0, "매 #@state_time@# 마다 #@damage@# #@elemental_dmg_type@#" }, std::string tooltip, strTemp; if( pState == NULL ) return tooltip; int fxPeriod = pState->fire_interval; int elementalType = pState->elemental_type; int addDamage = ( userAttr.nMagicPoint + itemAttr.nMagicPoint ) * pState->GetBasicFx_AmpDamage( nStateLevel ) + pState->GetBasicFx_AddDamage( nStateLevel ); tooltip = SR( 1620, "#@state_time@#", GetTimeString( fxPeriod ).c_str(), "#@elemental_dmg_type@#", S( 7138 + elementalType ), "#@damage@#", addDamage ); return tooltip; } std::string SUIDisplayInfo::BasicStateFxTooltip_MagicalDamageIgnoreDefense( StateInfoEx* pState, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) { // { 1621, 0, "매 #@state_time@# 마다 방어력을 무시한 #@damage@# #@elemental_dmg_type@#" }, std::string tooltip, strTemp; if( pState == NULL ) return tooltip; int fxPeriod = pState->fire_interval; int elementalType = pState->elemental_type; int addDamage = ( userAttr.nMagicPoint + itemAttr.nMagicPoint ) * pState->GetBasicFx_AmpDamage( nStateLevel ) + pState->GetBasicFx_AddDamage( nStateLevel ); tooltip = SR( 1621, "#@state_time@#", GetTimeString( fxPeriod ).c_str(), "#@elemental_dmg_type@#", S( 7138 + elementalType ), "#@damage@#", addDamage ); return tooltip; } std::string SUIDisplayInfo::BasicStateFxTooltip_HpRestoration( StateInfoEx* pState, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) { // { 1622, 0, "매 #@state_time@# 마다 #@point_name@# #@value@# 회복" }, std::string tooltip, strTemp; if( pState == NULL ) return tooltip; int fxPeriod = pState->fire_interval; float addDamage = (float)( userAttr.nMagicPoint + itemAttr.nMagicPoint ) * pState->GetBasicFx_AmpDamage( nStateLevel ) + (float)pState->GetBasicFx_AddDamage( nStateLevel ); tooltip = SR( 1622, "#@state_time@#", GetTimeString( fxPeriod ).c_str(), "#@point_name@#", S( 7005 ), "#@value@#", (int)addDamage ); return tooltip; } std::string SUIDisplayInfo::BasicStateFxTooltip_MpRestoration( StateInfoEx* pState, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) { // { 1622, 0, "매 #@state_time@# 마다 #@point_name@# #@value@# 회복" }, std::string tooltip, strTemp; if( pState == NULL ) return tooltip; int fxPeriod = pState->fire_interval; float addDamage = (float)( userAttr.nMagicPoint + itemAttr.nMagicPoint ) * pState->GetBasicFx_AmpDamage( nStateLevel ) + (float)pState->GetBasicFx_AddDamage( nStateLevel ); tooltip = SR( 1622, "#@state_time@#", GetTimeString( fxPeriod ).c_str(), "#@point_name@#", S( 7006 ), "#@value@#", (int)addDamage ); return tooltip; } //{ 7153, 7153, "#@bitset_text@# +#@value@#" }, std::string SUIDisplayInfo::ParameterIncrease( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 1 { std::string tooltip, strTemp; if( pState == NULL ) return tooltip; tooltip = GetFirstStateBitSetText( pState, 7153, 0, nStateLevel, false ); strTemp = GetFirstStateBitSetText( pState, 7153, 3, nStateLevel, false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } // bitset 12-15번도 사용하게 변경, 텍스트는 비트셋A , by 정동섭 strTemp = GetFirstStateBitSetText( pState, 7153, 12, nStateLevel, false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = GetFirstStateBitSetText( pState, 7153, 15, nStateLevel, false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = GetSecondStateBitSetText( pState, 7153, 6, nStateLevel, false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = GetSecondStateBitSetText( pState, 7153, 9, nStateLevel, false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; } return tooltip; } //{ 7153, 7153, "#@bitset_text@# +#@value@#" }, std::string SUIDisplayInfo::ParameterAmplify( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 2 { std::string tooltip, strTemp; if( pState == NULL ) return tooltip; tooltip = GetFirstStateBitSetText( pState, 7153, 0, nStateLevel, true ); strTemp = GetFirstStateBitSetText( pState, 7153, 3, nStateLevel, true ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } // bitset 12-15번도 사용하게 변경, 텍스트는 비트셋A , by 정동섭 strTemp = GetFirstStateBitSetText( pState, 7153, 12, nStateLevel, true ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = GetFirstStateBitSetText( pState, 7153, 15, nStateLevel, true ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = GetSecondStateBitSetText( pState, 7153, 6, nStateLevel, true ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = GetSecondStateBitSetText( pState, 7153, 9, nStateLevel, true ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; } return tooltip; } std::string SUIDisplayInfo::getStateTooltipBlessOfGoddess( StateInfoEx* pState, int nStateLevel ) const { std::string tooltip, strTemp; if (pState == NULL) return tooltip; tooltip = Get_A_BitSetText( 7153, pState->fValue[0], pState->fValue[1], false ); strTemp = Get_A_BitSetText( 7153, pState->fValue[2], pState->fValue[3], false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = Get_A_BitSetText( 7153, pState->fValue[4], pState->fValue[5], false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = Get_A_BitSetText( 7153, pState->fValue[6], pState->fValue[7], false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = Get_A_BitSetText( 7153, pState->fValue[8], pState->fValue[9], false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = Get_A_BitSetText( 7153, pState->fValue[10], pState->fValue[11], false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; strTemp.clear(); } strTemp = Get_A_BitSetText( 7153, pState->fValue[12], pState->fValue[13] * 100, true ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; } strTemp = Get_A_BitSetText( 7153, 51, pState->fValue[19], false ); if( !strTemp.empty() ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += strTemp; } return tooltip; } //{ 7155, 7155, "방패 장착 시 #@bitset_text@# +#@value@#" }, std::string SUIDisplayInfo::ParameterIncreaseEquipShild( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 3 { std::string tooltip, strTemp; std::vector TempList; if( pState == NULL ) return tooltip; tooltip = GetFirstStateBitSetText( pState, 7155, 0, nStateLevel, true ); if( !tooltip.empty() ) { strTemp = GetFirstStateBitSetText( pState, 7153, 3, nStateLevel, true ); if( !strTemp.empty() ) TempList.push_back(strTemp); } else tooltip += GetFirstStateBitSetText( pState, 7155, 3, nStateLevel, true ); if( !tooltip.empty() ) { strTemp = GetSecondStateBitSetText( pState, 7153, 6, nStateLevel, true ); if( !strTemp.empty() ) TempList.push_back(strTemp); } else tooltip += GetSecondStateBitSetText( pState, 7155, 6, nStateLevel, true ); if( !tooltip.empty() ) { strTemp = GetSecondStateBitSetText( pState, 7153, 9, nStateLevel, true ); if( !strTemp.empty() ) TempList.push_back(strTemp); } else tooltip += GetSecondStateBitSetText( pState, 7155, 9, nStateLevel, true ); if( !TempList.empty() ) tooltip += BuildEnumString(TempList, " / "); TempList.clear(); return tooltip; } // 2010.05.14 - prodongi std::string SUIDisplayInfo::ParameterSync(StateInfoEx* pState, int nStateLevel) const { std::string tooltip, strTemp; if( pState == NULL ) return tooltip; tooltip = GetThirdStateBitSetText( pState, 7153, 0, nStateLevel, false ); return tooltip; } // 2010.05.17 - prodongi std::string SUIDisplayInfo::AttackerAddState(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, strTemp; /// 2011.03.07 - prodongi std::string strMagicName; convertMagicTypeToString(pState->fValue[18], strMagicName); strTemp = S(7090); if (XStringUtil::Replace(strTemp, "#@value@#", strMagicName.c_str())) { tooltip += strTemp; tooltip += " ,"; /// 2011.04.06 - prodongi strTemp.clear(); } // 2010.08.11 - prodongi /// 2012.01.18 확률과 시간을 소수 첫째 자리까지 출력되도록 수정 - prodongi std::string strTemp2; float stateLevel = (float)nStateLevel; float p = pState->fValue[6] + stateLevel*pState->fValue[7]; float t = pState->fValue[4] + stateLevel*pState->fValue[5]; std::string skillName = S(GetTenacityDB().GetNameID(pState->fValue[0])); strTemp2 = rp::getRevisionFloat(p, 1, "%.1f"); strTemp = S(1670); if (XStringUtil::Replace(strTemp, "#@value@#", strTemp2.c_str())) { tooltip += strTemp; strTemp.clear(); } tooltip += " "; tooltip += S(1696); tooltip += " "; strTemp2 = rp::getRevisionFloat(t, 1, "%.1f"); strTemp = S(1660); if (XStringUtil::Replace(strTemp, "#@value@#", strTemp2.c_str())) { tooltip += strTemp; strTemp.clear(); } strTemp = S(1661); if (XStringUtil::Replace(strTemp, "#@value@#", skillName)) { tooltip += " "; tooltip += strTemp; strTemp.clear(); } tooltip += "
"; return tooltip; } /// 2011.03.11 - prodongi std::string SUIDisplayInfo::getStateToolTipInvulnerableness(StateInfoEx* pState) const { if (!pState) return ""; std::string tooltip, temp, temp2; char strTemp2[32]; // sprintf(strTemp2, "%d", (int)pState->fValue[0]); temp = S(8030); if (XStringUtil::Replace(temp, "#@value@#", strTemp2)) { tooltip += temp; tooltip += "
"; } // sprintf(strTemp2, "%d%%", (int)pState->fValue[1]); temp = S(8030); if (XStringUtil::Replace(temp, "#@value@#", strTemp2)) { tooltip += temp; tooltip += "
"; } // sprintf(strTemp2, "%d", (int)pState->fValue[2]); temp = S(8031); temp2 = S(1569); XStringUtil::Replace(temp2, "#@value@#", strTemp2); if (XStringUtil::Replace(temp, "#@value@#", temp2.c_str())) { tooltip += temp; tooltip += "
"; } // sprintf(strTemp2, "%d", (int)(pState->fValue[3]*100)); temp = S(8031); temp2 = S(1574); XStringUtil::Replace(temp2, "#@value@#", strTemp2); if (XStringUtil::Replace(temp, "#@value@#", temp2.c_str())) { tooltip += temp; tooltip += "
"; } return tooltip; } /// 2011.03.08 - prodongi std::string SUIDisplayInfo::getStateToolTipAddStateWhenKillTarget(StateInfoEx* pState, int nStateLevel, bool my) const { if (!pState) return ""; std::string tooltip, temp, temp2; /// 생명력 xxx 이상 if (0 < (int)pState->fValue[14]) { temp2 = CStringUtil::StringFormat("%d", (int)pState->fValue[14]); temp = SR(7053, "#@value@#", temp2.c_str()); tooltip += temp; tooltip += ",
"; } /// 생명력 xxx 이하 if (0 < (int)pState->fValue[15]) { temp2 = CStringUtil::StringFormat("%d", (int)pState->fValue[15]); temp = SR(7054, "#@value@#", temp2.c_str()); tooltip += temp; tooltip += ",
"; } /// 공격대상과 레벨 차이 xxx이상일 경우, if (0 <= (int)pState->fValue[18]) { temp2 = CStringUtil::StringFormat("%d", (int)pState->fValue[18]); temp = SR(8094, "#@db_text@#", S(8095), "#@value@#", temp2.c_str()); tooltip += temp; tooltip += ",
"; } /// 공격대상과 MP 차이 xxx%이상일 경우, if (0 < (int)pState->fValue[19]) { temp2 = CStringUtil::StringFormat("%d", (int)pState->fValue[19]); temp = SR(8096, "#@db_text@#", S(42), "#@probability@#", temp2.c_str()); tooltip += temp; tooltip += ",
"; } /// 공격대상을 쓰러뜨렸을 때, (xx)% 확률로 자신에게 (xx)초동안 (지속효과 ID) 효과 부여 if ((int)pState->fValue[0]) { std::string skillName = S(GetTenacityDB().GetNameID(pState->fValue[0])); tooltip += (my) ? S(8106) : S(8097); tooltip += ", "; temp = SR(7066, "#@state@#", skillName.c_str()); tooltip += temp; tooltip += "
"; } /// 소모 MP xx if ((int)pState->fValue[13]) { temp2 = CStringUtil::StringFormat("%d", (int)pState->fValue[13]); temp = SR(8098, "#@db_text@#", S(42), "#@value@#", temp2.c_str()); tooltip += temp; tooltip += "
"; } return tooltip; } std::string SUIDisplayInfo::getStateToolTipAddStateWhenType1(StateInfoEx* pState, int nStateLevel, int stringId, int attackTypeId, int personId) const { if (!pState) return ""; std::string tooltip; int p = pState->fValue[6] + nStateLevel*pState->fValue[7]; std::string skillName = S(GetTenacityDB().GetNameID(pState->fValue[0])); char strTemp[32]; sprintf(strTemp, "%d", p); tooltip = S(stringId); XStringUtil::Replace(tooltip, "#@attack_type@#", S(attackTypeId)); XStringUtil::Replace(tooltip, "#@probability@#", strTemp); XStringUtil::Replace(tooltip, "#@person@#", S(personId)); XStringUtil::Replace(tooltip, "#@state@#", skillName.c_str()); return tooltip; } std::string SUIDisplayInfo::getStateToolTipInfinitySummonRecall(StateInfoEx* pState) const { if (!pState) return ""; std::string tooltip; tooltip = S(8028); char strTemp[32]; sprintf(strTemp, "%d", (int)pState->fValue[0]); XStringUtil::Replace(tooltip, "#@time@#", strTemp); return tooltip; } std::string SUIDisplayInfo::getStateToolTipRangeTypeModifyDamage(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip; std::string temp; int id; /// 데미지 속성 char const* dmgAttriName = StringDBHelper::getDmgAttriName(pState->fValue[5]); /// 효과 적용 레인지 타입 switch ((int)pState->fValue[7]) { case 0: id = 8073; break; case 1: id = 8074; break; case 99:id = 8075; break; default:id = 8075; } char const* rangeTypeName = GetStringDB().GetString(id); /// temp = S(8076); XStringUtil::Replace(temp, "#@value@#", dmgAttriName); XStringUtil::Replace(temp, "#@range_type@#", rangeTypeName); tooltip += temp; tooltip += ","; /// 렙당 발동 확률 int p = (int)pState->GetIncreaseData(3, nStateLevel); std::string strP = CStringUtil::StringFormat("%d", p); /// 데미지 증가 int dmg = (int)pState->GetIncreaseData(0, nStateLevel); std::string strDmg = CStringUtil::StringFormat("%d", dmg); /// temp = S(8077); XStringUtil::Replace(temp, "#@probability@#", strP); XStringUtil::Replace(temp, "#@value@#", strDmg); tooltip += temp; tooltip += "
"; /// 적용 공격자 계열1 temp = S(8060); XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[17])); tooltip += temp; tooltip += ","; tooltip += "
"; /// 적용 공격자 계열2 temp = S(8060); XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[18])); tooltip += temp; tooltip += ","; tooltip += "
"; /// 적용 공격자 계열3 temp = S(8060); XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[19])); tooltip += temp; tooltip += ","; tooltip += "
"; /// 데미지 감소 int phyDmg = pState->GetIncreaseData(9, nStateLevel); int sklDmg = pState->GetIncreaseData(11, nStateLevel); int magDmg = pState->GetIncreaseData(13, nStateLevel); dmg = phyDmg + sklDmg + magDmg; strDmg = CStringUtil::StringFormat("%d", dmg); /// temp = S(8078); XStringUtil::Replace(temp, "#@value@#", strDmg); tooltip += temp; tooltip += "
"; return tooltip; } std::string SUIDisplayInfo::getStateToolTipAttackedDecDamage(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, temp; /// tooltip = ReduceDamageAllType(pState, nStateLevel); tooltip += "
"; /// 적용 공격자 계열1 temp = S(8060); XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[17])); tooltip += temp; tooltip += ","; tooltip += "
"; /// 적용 공격자 계열2 temp = S(8060); XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[18])); tooltip += temp; tooltip += ","; tooltip += "
"; /// 적용 공격자 계열3 temp = S(8060); XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[19])); tooltip += temp; tooltip += ","; tooltip += "
"; /// 데미지 감소 int phyDmg = pState->GetIncreaseData(10, nStateLevel); int sklDmg = pState->GetIncreaseData(12, nStateLevel); int magDmg = pState->GetIncreaseData(14, nStateLevel); int dmg = phyDmg + sklDmg + magDmg; std::string strDmg = CStringUtil::StringFormat("%d%", dmg); /// temp = S(8078); XStringUtil::Replace(temp, "#@value@#", strDmg); tooltip += temp; tooltip += "
"; return tooltip; } std::string SUIDisplayInfo::getStateToolTipAttackAmplifyAttDamage(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, temp; /// 일반 공격 여부 if (0 < (int)pState->fValue[10]) { temp = S(8082); XStringUtil::Replace(temp, "#@value@#", S(6370)); tooltip += temp; tooltip += ","; tooltip += "
"; } /// 원거리 공격 여부 if (0 < (int)pState->fValue[11]) { temp = S(8082); XStringUtil::Replace(temp, "#@value@#", S(8079)); tooltip += temp; tooltip += ","; tooltip += "
"; } /// 물리 스킬 여부 if (0 < (int)pState->fValue[12]) { temp = S(8082); XStringUtil::Replace(temp, "#@value@#", S(8080)); tooltip += temp; tooltip += ","; tooltip += "
"; } /// 마법 스킬 여부 if (0 < (int)pState->fValue[13]) { temp = S(8082); XStringUtil::Replace(temp, "#@value@#", S(8081)); tooltip += temp; tooltip += ","; tooltip += "
"; } /// 공격력 반영 타입 std::string strAttackType; switch ((int)pState->fValue[4]) { case 0: strAttackType = S(7108); break; case 1: strAttackType = S(7109); break; case 99:strAttackType += S(7108); strAttackType += " + "; strAttackType += S(7109); break; } /// 발동 확률 int p = (int)(pState->GetIncreaseData(0, nStateLevel) * 100.0f); std::string strP = CStringUtil::StringFormat("%d", p); /// 데미지 속성 char const* strDmgAttriName = StringDBHelper::getDmgAttriName((int)pState->fValue[7]); /// temp = S(8083); XStringUtil::Replace(temp, "#@attack_type@#", strAttackType); XStringUtil::Replace(temp, "#@probability@#", strP); XStringUtil::Replace(temp, "#@dmg_attri@#", strDmgAttriName); tooltip += temp; tooltip += "
"; return tooltip; } std::string SUIDisplayInfo::getStateToolTipAttackedAddDamage(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, temp, strP; int p; /// 지속시간 동안 공격 대상에게 tooltip += S(8084); tooltip += "
"; /// 물리 공격 데미지 증폭 p = (int)(pState->GetIncreaseData(0, nStateLevel) * 100.0f); if (p) { temp = S(8091); strP = CStringUtil::StringFormat("%d", p); XStringUtil::Replace(temp, "#@value@#", S(8085)); XStringUtil::Replace(temp, "#@probability@#", strP); tooltip += temp; tooltip += "
"; } /// 물리 스킬 데미지 증폭 p = (int)(pState->GetIncreaseData(2, nStateLevel) * 100.0f); if (p) { temp = S(8091); strP = CStringUtil::StringFormat("%d", p); XStringUtil::Replace(temp, "#@value@#", S(8080)); XStringUtil::Replace(temp, "#@probability@#", strP); tooltip += temp; tooltip += "
"; } /// 마법 공격 데미지 증폭 p = (int)(pState->GetIncreaseData(6, nStateLevel) * 100.0f); if (p) { temp = S(8091); strP = CStringUtil::StringFormat("%d", p); XStringUtil::Replace(temp, "#@value@#", S(8086)); XStringUtil::Replace(temp, "#@probability@#", strP); tooltip += temp; tooltip += "
"; } tooltip += "
"; /// p = (int)(pState->GetIncreaseData(12, nStateLevel) * 100.0f); if (p) { strP = CStringUtil::StringFormat("%d", p); temp = S(8087); XStringUtil::Replace(temp, "#@dmg_attri@#", StringDBHelper::getDmgAttriName((int)pState->fValue[14])); XStringUtil::Replace(temp, "#@probability@#", strP); tooltip += temp; tooltip += "
"; } /// p = (int)pState->GetIncreaseData(10, nStateLevel); if (p) { strP = CStringUtil::StringFormat("%d", p); temp = S(8088); XStringUtil::Replace(temp, "#@db_text@#", S(40)); XStringUtil::Replace(temp, "#@probability@#", strP); tooltip += temp; tooltip += "
"; } /// 어그로 if (1 == (int)pState->fValue[19]) { tooltip += S(8089); tooltip += "
"; } else if (2 == (int)pState->fValue[19]) { tooltip += S(8090); tooltip += "
"; } return tooltip; } std::string SUIDisplayInfo::getStateToolTipBitSetAList(StateInfoEx* pState, int nStateLevel, int id, bool amplify) const { std::string tooltip, temp, strP, strBitSet; StringDBHelper::getBitSetANameList(pState->fValue[id], ", ", strBitSet); if (!strBitSet.empty()) { double p = (amplify) ? 100.0f : 1.0f; double value = pState->GetIncreaseData(id+1, nStateLevel) * p; if (amplify) strP = CStringUtil::StringFormat("%1.f%%", value); else strP = CStringUtil::StringFormat("%d%%", (int)value); temp = SR(8066, "#@bitset_name@#", strBitSet.c_str(), "#@value@#", strP.c_str()); tooltip += temp; tooltip += "
"; } return tooltip; } std::string SUIDisplayInfo::getStateToolTipBitSetBList(StateInfoEx* pState, int nStateLevel, int id, bool amplify) const { std::string tooltip, temp, strP, strBitSet; StringDBHelper::getBitSetBNameList(pState->fValue[id], ", ", strBitSet); if (!strBitSet.empty()) { double p = (amplify) ? 100.0f : 1.0f; double value = pState->GetIncreaseData(id+1, nStateLevel) * p; if (amplify) strP = CStringUtil::StringFormat("%1.f%%", value); else strP = CStringUtil::StringFormat("%d%%", (int)value); temp = SR(8066, "#@bitset_name@#", strBitSet.c_str(), "#@value@#", strP.c_str()); tooltip += temp; tooltip += "
"; } return tooltip; } std::string SUIDisplayInfo::getStateToolTipAddStateDamage(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; double value; std::string tooltip, strValue, temp, strAttri; std::string strBitSet1, strBitSet2, strBitSet; /// 비트셋 값13, 값14 StringDBHelper::getBitSetANameList(pState->fValue[12], ", ", strBitSet1); StringDBHelper::getBitSetBNameList(pState->fValue[13], ", ", strBitSet2); if (!strBitSet2.empty()) strBitSet1 += ", "; strBitSet = strBitSet1 + strBitSet2; /// 속성 값1 strAttri = StringDBHelper::getDmgAttriName(pState->fValue[0]); value = pState->GetIncreaseData(1, nStateLevel); if (!isZero(value)) { strValue = CStringUtil::StringFormat("%1.f%%", value * 100.0f); temp = SR(8118, "#@bitset_name@#", strBitSet.c_str(), "#@probability@#", strValue.c_str(), "#@value@#", strAttri.c_str()); temp += "
"; tooltip += temp; } value = pState->GetIncreaseData(3, nStateLevel); if (!isZero(value)) { strValue = CStringUtil::StringFormat("%d", (int)value); temp = SR(8118, "#@bitset_name@#", strBitSet.c_str(), "#@probability@#", strValue.c_str(), "#@value@#", strAttri.c_str()); temp += "
"; tooltip += temp; } /// 비트셋 값15, 값16 StringDBHelper::getBitSetANameList(pState->fValue[14], ", ", strBitSet1); StringDBHelper::getBitSetBNameList(pState->fValue[15], ", ", strBitSet2); if (!strBitSet2.empty()) strBitSet1 += ", "; strBitSet = strBitSet1 + strBitSet2; /// 속성 값7 strAttri = StringDBHelper::getDmgAttriName(pState->fValue[6]); value = pState->GetIncreaseData(7, nStateLevel); if (!isZero(value)) { strValue = CStringUtil::StringFormat("%1.f%%", value * 100.0f); temp = SR(8118, "#@bitset_name@#", strBitSet.c_str(), "#@probability@#", strValue.c_str(), "#@value@#", strAttri.c_str()); temp += "
"; tooltip += temp; } value = pState->GetIncreaseData(10, nStateLevel); if (!isZero(value)) { strValue = CStringUtil::StringFormat("%d", (int)value); temp = SR(8118, "#@bitset_name@#", strBitSet.c_str(), "#@probability@#", strValue.c_str(), "#@value@#", strAttri.c_str()); temp += "
"; tooltip += temp; } return tooltip; } std::string SUIDisplayInfo::getStateToolTipAmplifyStateDamage(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip; /// bitset A1 tooltip += getStateToolTipBitSetAList(pState, nStateLevel, 0, true); /// bitset B1 tooltip += getStateToolTipBitSetBList(pState, nStateLevel, 3, true); /// bitset A2 tooltip += getStateToolTipBitSetAList(pState, nStateLevel, 6, true); /// bitset B2 tooltip += getStateToolTipBitSetBList(pState, nStateLevel, 9, true); /// tooltip += S(8093); tooltip += "
"; return tooltip; } std::string SUIDisplayInfo::getStateToolTipNotConsumptionEnergy(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip; tooltip = S(8072); tooltip += "
"; return tooltip; } std::string SUIDisplayInfo::getStateToolTipAutoResurrection(StateInfoEx *pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, temp, strP; int p; /// 남은 MP 소모 xx % p = (int)(pState->GetIncreaseData(0, nStateLevel) * 100.0f); strP = CStringUtil::StringFormat("%d", p); temp = SR(8107, "#@db_text@#", S(42), "#@probability@#", strP.c_str()); tooltip += temp; tooltip += "
"; /// 소모된 MP로 HP 회복 xx % p = (int)(pState->GetIncreaseData(2, nStateLevel) * 100.0f); strP = CStringUtil::StringFormat("%d", p); temp = SR(8108, "#@db_text1@#", S(42), "#@db_text2@#", S(40), "#@probability@#", strP.c_str()); tooltip += temp; tooltip += "
"; return tooltip; } /// 2011.04.05 - prodongi std::string SUIDisplayInfo::getStateToolTipRecoveryHpMp(StateInfoEx *pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, temp, strP; /// hp int hp = (int)(pState->GetIncreaseData(0, nStateLevel) * 100.0f); int mp = (int)(pState->GetIncreaseData(3, nStateLevel) * 100.0f); if (0 < hp || 0 < mp) { tooltip = "<#ffffcc>"; } if (0 < hp) { strP = CStringUtil::StringFormat("%d", hp); temp = SR(8110, "#@db_text@#", S(40), "#@value@#", strP.c_str()); temp += "
"; tooltip += temp; } /// mp if (0 < mp) { strP = CStringUtil::StringFormat("%d", mp); temp = SR(8110, "#@db_text@#", S(42), "#@value@#", strP.c_str()); temp += "
"; tooltip += temp; } if (0 < hp || 0 < mp) { tooltip += "
<#ffffff>"; } return tooltip; } /// 2011.04.26 - prodongi std::string SUIDisplayInfo::getStateToolTipRecoveryHp(StateInfoEx *pState, int nStateLevel) const { if (!pState) return ""; std::string tooltip, temp; int p = (int)(pState->GetIncreaseData(2, nStateLevel) * 100.0f); if (p) { std::string strValue = CStringUtil::StringFormat("%d", p); temp = SR(1574, "#@value@#", strValue.c_str()); temp += "
"; tooltip = temp; } return tooltip; } // 2010.08.11 - prodongi std::string SUIDisplayInfo::MyAddState(StateInfoEx* pState, int nStateLevel) const { if (!pState) return ""; char strTemp2[32]; std::string tooltip, strTemp; // 2010.08.11 - prodongi int p = pState->fValue[6] + nStateLevel*pState->fValue[7]; int t = pState->fValue[4] + nStateLevel*pState->fValue[5]; std::string skillName = S(GetTenacityDB().GetNameID(pState->fValue[0])); sprintf(strTemp2, "%d", p); strTemp = S(1670); if (XStringUtil::Replace(strTemp, "#@value@#", strTemp2)) { tooltip += strTemp; strTemp.clear(); } tooltip += " "; sprintf(strTemp2, "%d", t); strTemp = S(1660); if (XStringUtil::Replace(strTemp, "#@value@#", strTemp2)) { tooltip += strTemp; strTemp.clear(); } strTemp = S(1661); if (XStringUtil::Replace(strTemp, "#@value@#", skillName)) { tooltip += " "; tooltip += strTemp; strTemp.clear(); } tooltip += "
"; return tooltip; } //{ 7156, 7156, "#@weapon_type@# 장착 시 #@probability@#%의 확률로 추가 공격" }, std::string SUIDisplayInfo::DoubleAttack( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 6 { std::string tooltip; if( pState == NULL ) return tooltip; std::vector WeaponList; int nWeaponID_1(0); int nWeaponID_2(0); int nWeaponID_3(0); int nWeaponID_4(0); nWeaponID_1 = pState->GetValue(8); nWeaponID_2 = pState->GetValue(9); nWeaponID_3 = pState->GetValue(10); nWeaponID_4 = pState->GetValue(11); if( nWeaponID_1 ) WeaponList.push_back( nWeaponID_1 ); if( nWeaponID_2 ) WeaponList.push_back( nWeaponID_2 ); if( nWeaponID_3 ) WeaponList.push_back( nWeaponID_3 ); if( nWeaponID_4 ) WeaponList.push_back( nWeaponID_4 ); int probability = pState->GetIncreaseData(0, nStateLevel); tooltip = SR(7156, "#@weapon_type@#", GetWeaponText(WeaponList).c_str(), "#@probability@#", probability ); WeaponList.clear(); return tooltip; } std::string SUIDisplayInfo::AttackAddDamege( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 22 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float value = pState->GetIncreaseData(0, nStateLevel); tooltip = SR(7157, "#@value@#", CheckPositiveText(value, false).c_str(), "#@probability@#", probability); return tooltip; } std::string SUIDisplayInfo::AttackAddDamegeRate( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 23 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float value = pState->GetIncreaseData(0, nStateLevel)*100; tooltip = SR(7158, "#@value@#", CheckPositiveText(value, false).c_str(), "#@probability@#", probability); return tooltip; } std::string SUIDisplayInfo::MagicAddDemage( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 24 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float value = pState->GetIncreaseData(0, nStateLevel); tooltip = SR(7159, "#@value@#", CheckPositiveText(value, false).c_str(), "#@probability@#", probability); return tooltip; } std::string SUIDisplayInfo::MagicAddDemageRate( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 25 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float value = pState->GetIncreaseData(0, nStateLevel)*100; tooltip = SR(7160, "#@value@#", CheckPositiveText(value, false).c_str(), "#@probability@#", probability); return tooltip; } std::string SUIDisplayInfo::AttackAddState( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 26 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); // 2010.08.16 - prodongi /* int stateID = pState->GetValue(0); std::string StateName = GetStringDB().GetString( GetTenacityDB().GetNameID(stateID) ); tooltip = SR(7161, "#@state_name@#", StateName.c_str(), "#@probability@#", probability); */ StateInfoEx* stateSub = GetTenacityDB().GetTenacityData(pState->GetValue(0)); std::string stateName = S(stateSub->name_id); int addDamage = stateSub->add_damage_base + nStateLevel * stateSub->add_damage_per_skl; /// 2011.05.27 - prodongi if (addDamage) { tooltip = SR(8026, "#@state_name@#", stateName.c_str(), "#@probability@#", SStringDB::ToString(probability).c_str(), "#@state_time@#", stateSub->fire_interval, "#@damage@#", addDamage); } return tooltip; } std::string SUIDisplayInfo::AttackRecovery( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 27 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float rcvHP = pState->GetIncreaseData(0, nStateLevel); float rcvMP = pState->GetIncreaseData(2, nStateLevel); float rcvSP = pState->GetIncreaseData(4, nStateLevel); if( rcvHP ) { tooltip = SR(7162, "#@point_name@#", S(7005), "#@value@#", CheckPositiveText(rcvHP, false).c_str(), "#@probability@#", probability); } if( rcvMP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7162, "#@point_name@#", S(7006), "#@value@#", CheckPositiveText(rcvMP, false).c_str(), "#@probability@#", probability ); } if( rcvSP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7162, "#@point_name@#", S(7007), "#@value@#", CheckPositiveText(rcvSP, false).c_str(), "#@probability@#", probability ); } return tooltip; } std::string SUIDisplayInfo::HpMpRecoveryWhenCritial( StateInfoEx* pState, int nStateLevel ) const { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData( 4, nStateLevel ); float rcvHP = pState->GetIncreaseData(0, nStateLevel); float rcvMP = pState->GetIncreaseData(2, nStateLevel); if( rcvHP ) { tooltip = SR(1607, "#@point_name@#", S(7005), "#@value@#", CheckPositiveText(rcvHP, false).c_str(), "#@probability@#", probability); } if( rcvMP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(1607, "#@point_name@#", S(7006), "#@value@#", CheckPositiveText(rcvMP, false).c_str(), "#@probability@#", probability ); } return tooltip; } std::string SUIDisplayInfo::AmplifySkillHealAmount( StateInfoEx* pState, int nStateLevel ) const { //{ 1608, 0, "스킬 회복시 #@point_name@# 회복율 #@value@#% 증가 및 추가 회복 #@add@#" }, std::string tooltip; if( pState == NULL ) return tooltip; // 2010.05.14 백분율 정수로 표시- prodongi int ampHP = (int)(pState->GetIncreaseData( 0, nStateLevel ) * 100.0f); int ampMP = (int)(pState->GetIncreaseData( 2, nStateLevel ) * 100.0f); int addHP = (int)(pState->GetIncreaseData( 4, nStateLevel )); int addMP = (int)(pState->GetIncreaseData( 6, nStateLevel )); /* float ampHP = pState->GetIncreaseData( 0, nStateLevel ); float ampMP = pState->GetIncreaseData( 2, nStateLevel ); int addHP = pState->GetIncreaseData( 4, nStateLevel ); int addMP = pState->GetIncreaseData( 6, nStateLevel ); */ if( ampHP ) { // 2010.05.14 - prodongi tooltip = SR( 1608, "#@point_name@#", S( 7005 ), "#@value@#", CheckPositiveText( ampHP, false ).c_str(), "#@add@#", CheckPositiveText( addHP, false ).c_str() ); // tooltip = SR( 1608, "#@point_name@#", S( 7005 ), "#@value@#", CheckPositiveText( ampHP, true ).c_str(), "#@add@#", CheckPositiveText( addHP, false ).c_str() ); } if( ampMP ) { if( !tooltip.empty() ) tooltip += "
"; // 2010.05.14 - prodongi tooltip = SR( 1608, "#@point_name@#", S( 7006 ), "#@value@#", CheckPositiveText( ampMP, false ).c_str(), "#@add@#", CheckPositiveText( addMP, false ).c_str() ); // tooltip = SR( 1608, "#@point_name@#", S( 7006 ), "#@value@#", CheckPositiveText( ampMP, true ).c_str(), "#@add@#", CheckPositiveText( addMP, false ).c_str() ); } return tooltip; } std::string SUIDisplayInfo::AttackRecoveryRate( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 41 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float rcvHP = pState->GetIncreaseData(0, nStateLevel)*100; float rcvMP = pState->GetIncreaseData(2, nStateLevel)*100; if( rcvHP ) { tooltip = SR(7163, "#@point_name@#", S(7005), "#@value@#", (int)rcvHP, "#@probability@#", probability); } if( rcvMP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7163, "#@point_name@#", S(7006), "#@value@#", (int)rcvMP, "#@probability@#", probability); } return tooltip; } std::string SUIDisplayInfo::AttackAbsorb( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 42 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float absorbHP = pState->GetIncreaseData(0, nStateLevel)*100; float absorbMP = pState->GetIncreaseData(2, nStateLevel)*100; if( absorbHP ) { tooltip = SR(7164, "#@point_name@#", S(7005), "#@value@#", CheckPositiveText(absorbHP, false).c_str(), "#@probability@#", probability ); } if( absorbMP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7164, "#@point_name@#", S(7006), "#@value@#", CheckPositiveText(absorbMP, false).c_str(), "#@probability@#", probability ); } return tooltip; } //현재 적용안된다. 추후 업뎃 std::string SUIDisplayInfo::BeAttackedReflection( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData( 6, nStateLevel ); int range = pState->fValue[ 9 ]; float reflectPhy = pState->GetIncreaseData( 0, nStateLevel ) * 100.f; float reduceSkl = pState->GetIncreaseData( 2, nStateLevel ) * 100.f; float reflectMag = pState->GetIncreaseData( 4, nStateLevel ) * 100.f; if( probability ) { tooltip = SR( 1625, "#@value@#", probability ); } if( range ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1577, "#@value@#", range ); } if( reduceSkl ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1626, "#@damage_type@#", S( 1611 ), "#@value@#", (int)reduceSkl ); } if( reflectPhy ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1626, "#@damage_type@#", S( 1610 ), "#@value@#", (int)reflectPhy ); } if( reflectMag ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1626, "#@damage_type@#", S( 1612 ), "#@value@#", (int)reflectMag ); } return tooltip; } std::string SUIDisplayInfo::BeAttackedReflectionIgnoreDefense( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 44 { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); float value = pState->GetIncreaseData(0, nStateLevel); tooltip = SR(7166, "#@value@#", CheckPositiveText(value, false).c_str(), "#@probability@#", probability); return tooltip; } std::string SUIDisplayInfo::ReduceDamageAllType( StateInfoEx* pState, int nStateLevel ) const { // { 1609, 0, "#@probability@#% 확률로 #@damage_type@# 데미지 #@value@#% 감소" }, // { 1610, 0, "물리" }, // { 1611, 0, "스킬" }, // { 1612, 0, "마법" }, std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->fValue[ 6 ]; float reducePhy = pState->GetIncreaseData( 0, nStateLevel ) * 100.f; float reduceSkl = pState->GetIncreaseData( 2, nStateLevel ) * 100.f; float reduceMag = pState->GetIncreaseData( 4, nStateLevel ) * 100.f; int stringid; if( reducePhy ) { stringid = (reducePhy < 0) ? 1699 : 1609; tooltip += SR( stringid, "#@damage_type@#", S( 1610 ), "#@value@#", abs((int)reducePhy), "#@probability@#", probability ); } if( reduceSkl ) { stringid = (reduceSkl < 0) ? 1699 : 1609; if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( stringid, "#@damage_type@#", S( 1611 ), "#@value@#", abs((int)reduceSkl), "#@probability@#", probability ); } if( reduceMag ) { stringid = (reduceMag < 0) ? 1699 : 1609; if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( stringid, "#@damage_type@#", S( 1612 ), "#@value@#", abs((int)reduceMag), "#@probability@#", probability ); } return tooltip; } std::string SUIDisplayInfo::TransferDamageToMP( StateInfoEx* pState, int nStateLevel ) const { // { 1613, 0, "피격시 #@value@#%의 데미지를 MP로 대신 소모" }, std::string tooltip; if( pState == NULL ) return tooltip; // 2010.05.14 정수 형태로 나와야 됨- prodongi int transferRate = (int)(pState->GetIncreaseData( 0, nStateLevel ) * 100.f); //float transferRate = pState->GetIncreaseData( 0, nStateLevel ) * 100.f; if( transferRate ) { tooltip = SR( 1613, "#@value@#", transferRate ); } return tooltip; } std::string SUIDisplayInfo::RealtimeMainTenanceRecovery( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 61 { std::string tooltip; if( pState == NULL ) return tooltip; float rcvHP = pState->GetIncreaseData(0, nStateLevel)/20.0f; float rcvMP = pState->GetIncreaseData(2, nStateLevel)/20.0f; float rcvSP = pState->GetIncreaseData(4, nStateLevel)/20.0f; if( rcvHP ) { tooltip = SR(7167, "#@point_name@#", S(7005), "#@value@#", CheckPositiveText(rcvHP, false).c_str()); } if( rcvMP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7167, "#@point_name@#", S(7006), "#@value@#", CheckPositiveText(rcvMP, false).c_str()); } if( rcvSP ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7167, "#@point_name@#", S(7007), "#@value@#", CheckPositiveText(rcvSP, false).c_str()); } return tooltip; } std::string SUIDisplayInfo::IncapacitateSate( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 81 { std::string tooltip; if( pState == NULL ) return tooltip; std::vector StateNameList; int stateID1 = pState->GetValue(0); std::string StateName1 = GetStringDB().GetString( GetTenacityDB().GetNameID(stateID1) ); StateNameList.push_back(StateName1); int stateID2 = pState->GetValue(3); std::string StateName2 = GetStringDB().GetString( GetTenacityDB().GetNameID(stateID2) ); StateNameList.push_back(StateName2); tooltip = SR(7168, "#@state_name@#", BuildEnumString(StateNameList, " / ").c_str() ); StateNameList.clear(); return tooltip; } std::string SUIDisplayInfo::ImpossibleAction( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 82 { std::string tooltip; if( pState == NULL ) return tooltip; float value = pState->GetValue(0); if( value ) tooltip = SR(7169, "#@command_name@#", S(7191) ); else { std::vector strList; if( pState->GetValue(1) ) strList.push_back(S(7188)); if( pState->GetValue(2) ) strList.push_back(S(7189)); if( pState->GetValue(3) ) strList.push_back(S(7190)); tooltip = SR(7169, "#@command_name@#", BuildEnumString(strList, " / ").c_str()); strList.clear(); } return tooltip; } std::string SUIDisplayInfo::IncreaseHate( StateInfoEx* pState, int nStateLevel ) const { //{ 1614, 0, "헤이트 #@value@# 증가" }, std::string tooltip; if( pState == NULL ) return tooltip; int incHate = pState->GetIncreaseData( 0, nStateLevel ); if( incHate ) { tooltip = SR( 1614, "#@value@#", incHate ); } return tooltip; } std::string SUIDisplayInfo::IncreaseIntimidation( StateInfoEx* pState, int nStateLevel ) const { // { 1615, 0, "위협수준 #@value@# 증가" }, std::string tooltip; if( pState == NULL ) return tooltip; float incIntim = (float)pState->GetIncreaseData( 0, nStateLevel ) * 100.f; if( incIntim ) { tooltip = SR( 7027, "#@aggro_point@#", CheckPositiveText( incIntim, true ).c_str() ); } return tooltip; } std::string SUIDisplayInfo::InterruptSkill( StateInfoEx* pState, int nStateLevel ) const { // { 1616, 0, "#@value@# 스킬 사용 불가" }, std::string tooltip; if( pState == NULL ) return tooltip; for( int i = 0; i < 12; ++i ) { int skillID = (int)pState->fValue[ i ]; if( !skillID ) continue; const char* skillName = GetStringDB().GetString( GetSkillDB().GetStringID( skillID ) ); if( skillName ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1616, "#@value@#", skillName ); } } return tooltip; } std::string SUIDisplayInfo::AddStateInRegion( StateInfoEx* pState, int nStateLevel ) const { // { 1617, 0, "#@probability@#% 확률로 #@state_time@# 동안 반경 #@radius@#m 내에 #@state@# 효과 부여" }, std::string tooltip; if( pState == NULL ) return tooltip; int stateID = pState->fValue[ 0 ]; int frequency = pState->fValue[ 1 ]; int duration = pState->GetIncreaseData( 2, nStateLevel ); int radius = pState->fValue[ 4 ]; int probability = pState->GetIncreaseData( 8, nStateLevel ); if( stateID ) { if( probability ) { tooltip = SR( 1625, "#@value@#", probability ); } if( frequency ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1628, "#@value@#", this->GetTimeString( frequency ).c_str() ); } if( duration ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1565, "#@value@#", duration ); } if( radius ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1552, "#@value@#", radius ); } // sonador 10.4.2 지속효과 기본공격 반영률 관련 오류 수정 //if( !tooltip.empty() ) tooltip += "
"; //tooltip += this->GetStateBaseEffectCaseToolTipText( stateID, nStateLevel ); } return tooltip; } //{ 7170, 7170, "MP 소모량 #@value@#%" }, std::string SUIDisplayInfo::DecreaseMpConsumption( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID 91 { std::string tooltip; if( pState == NULL ) return tooltip; float value = pState->GetIncreaseData(0, nStateLevel); tooltip = SR(7170, "#@value@#", CheckPositiveText(value, false).c_str()); return tooltip; } //클라에서 다 처리 std::string SUIDisplayInfo::Increase_Power_Cri_Ag_Cool( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID { std::string tooltip; if( pState == NULL ) return tooltip; float AttackPoint = pState->GetIncreaseData( 0, nStateLevel ) * 100; float Cri = pState->GetValue( 3, nStateLevel ) * (float)m_PlayerInfoMgr.GetPlayerInfo().GetAttribute().nCritical + pState->GetValue( 4, nStateLevel ); float AggPoint = pState->GetIncreaseData( 5, nStateLevel ) * 100; float Cooltime = pState->GetValue( 7, nStateLevel ) * 100; if( AttackPoint ) { tooltip = SR(7153,"#@bitset_text@#", S(7108), "#@value@#", CheckPositiveText(AttackPoint, true).c_str()); } if( Cri ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7153,"#@bitset_text@#", S(7117), "#@value@#", CheckPositiveText(Cri, true).c_str()); } if( Cooltime ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7153,"#@bitset_text@#", S(77), "#@value@#", CheckPositiveText(Cooltime, true).c_str()); } if( AggPoint ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7027, "#@aggro_point@#", CheckPositiveText(AggPoint, false).c_str()); } return tooltip; } //클라에서 다 처리 std::string SUIDisplayInfo::SkillIncrease_Power_Cri_Ag_Cool( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID { std::string tooltip; if( pState == NULL ) return tooltip; float AttackPoint = pState->GetIncreaseData(0, nStateLevel)*100; float MagicPoint = pState->GetIncreaseData(2, nStateLevel)*100; float Cri = pState->GetValue(4, nStateLevel); float Cooltime = pState->GetValue(7, nStateLevel)*100; float AggPoint = pState->GetValue(6, nStateLevel)*100; if( AttackPoint ) { tooltip = SR(7153,"#@bitset_text@#", S(7108), "#@value@#", CheckPositiveText(AttackPoint, true).c_str()); } if( MagicPoint ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7153,"#@bitset_text@#", S(7109), "#@value@#", CheckPositiveText(MagicPoint, false).c_str()); } if( Cri ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7153,"#@bitset_text@#", S(7117), "#@value@#", CheckPositiveText(Cri, false).c_str()); } if( Cooltime ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7153,"#@bitset_text@#", S(77), "#@value@#", CheckPositiveText(Cooltime, true).c_str()); } if( AggPoint ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR(7027, "#@aggro_point@#", CheckPositiveText(AggPoint, false).c_str()); } return tooltip; } //{ 7171, 7171, "기본 공격시 #@probability@#% 확률로 넉백 효과 발생" }, std::string SUIDisplayInfo::AttackKnockBack( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel); tooltip = SR(7171, "#@probability@#", probability ); return tooltip; } //{ 7172, 7172, "기본 공격시 #@probability@#% 확률로 범위 데미지 효과 발생" }, std::string SUIDisplayInfo::AttackRangeType( StateInfoEx* pState, int nStateLevel ) const //StsteTypeID { std::string tooltip; if( pState == NULL ) return tooltip; int probability = pState->GetIncreaseData(6, nStateLevel)*100; tooltip = SR(7172, "#@probability@#", probability ); return tooltip; } std::string SUIDisplayInfo::SelfRebirth( StateInfoEx* pState, int nStateLevel ) const { std::string tooltip; if( pState == NULL ) return tooltip; int recHp = pState->GetIncreaseData( 0, nStateLevel ) * 100; int recMp = pState->GetIncreaseData( 2, nStateLevel ) * 100; int recExp = pState->GetIncreaseData( 4, nStateLevel ) * 100; if( recHp ) { tooltip = SR( 1574, "#@value@#", recHp ); } if( recMp ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1575, "#@value@#", recMp ); } if( recExp ) { if( !tooltip.empty() ) tooltip += "
"; tooltip += SR( 1576, "#@value@#", recExp ); } return tooltip; } std::string SUIDisplayInfo::DetectHiding( StateInfoEx* pState, int nStateLevel ) const { // { 1618, 0, "반경 #@radius@#m 은신 감지" }, std::string tooltip; if( pState == NULL ) return tooltip; int radius = pState->GetIncreaseData( 0, nStateLevel ); if( radius ) { tooltip = SR( 1618, "#@radius@#", radius ); } return tooltip; } std::string SUIDisplayInfo::RidingForSpeedUp( StateInfoEx* pState, int nStateLevel ) const { // { 1619, 0, "이동속도 #@value@# 증가" }, std::string tooltip; if( pState == NULL ) return tooltip; int moveSpeed = pState->fValue[ 0 ]; if( moveSpeed ) { tooltip = SR( 1619, "#@value@#", moveSpeed ); } return tooltip; } //////////////////////////////////////////////////////////////// // // 퀵슬롯 // //////////////////////////////////////////////////////////////// const SUIQuickSlotInfo* SUIDisplayInfo::GetQuickSlot( /*QUICKSLOT_BTNSTATE State, */int nSlotIndex ) const { // index==-1일 경우 BackupAndDeleteQuickSlot()으로 지워진 마지막 인덱스를 돌려준다 if (nSlotIndex==-1) return m_pBackupedQuickSlot; // normal quickslot return (/* 0 <= State && State < QUICKSLOT_BTN_MAXCOUNT && */0 <= nSlotIndex && nSlotIndex < c_nQuickSlotCount ) ? m_pQuickSlots[ nSlotIndex ] : NULL; } void SUIDisplayInfo::BackupAndDeleteQuickSlot(/* QUICKSLOT_BTNSTATE State, */int nSlotIndex ) { SUIQuickSlotInfo* pInfo(NULL); if( m_pQuickSlots[nSlotIndex] ) { pInfo = GetQuickSlotData( m_pQuickSlots[nSlotIndex] ); } SAFE_DELETE(m_pBackupedQuickSlot); // Purge previously stored quickslot m_pBackupedQuickSlot=pInfo; // backup quickslot SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); } SUIQuickSlotInfo* SUIDisplayInfo::GetQuickSlotData( SUIQuickSlotInfo* pInfo ) { if( !pInfo ) return NULL; SUIQuickSlotInfo* pNewInfo(NULL); switch( pInfo->m_type ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: { AR_HANDLE handle = ((SUIQuickSlotItemInfo*)pInfo)->m_hItem; int itemCode = ((SUIQuickSlotItemInfo*)pInfo)->m_ItemCode; pNewInfo = new SUIQuickSlotItemInfo( handle, itemCode ); } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: { AR_HANDLE handle = ((SUIQuickSlotSkillInfo*)pInfo)->m_hTarget; int ID = ((SUIQuickSlotSkillInfo*)pInfo)->m_nSkillID; int level = ((SUIQuickSlotSkillInfo*)pInfo)->m_nSkillLevel; pNewInfo = new SUIQuickSlotSkillInfo( handle, ID, level,((SUIQuickSlotSkillInfo*)pInfo)->m_bPlayer ); } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: { int MotionID = ((SUIQuickSlotMotionInfo*)pInfo)->m_nMotionID; int CommandID = ((SUIQuickSlotMotionInfo*)pInfo)->m_nMotionCommandID; pNewInfo = new SUIQuickSlotMotionInfo( MotionID, CommandID ); } break; case SUIQuickSlotInfo::QSLOTTYPE_EMPTYITEM: { int ItemCode = ((SUIQuickSlotEmptyItemInfo*)pInfo)->iItemCode; pNewInfo = new SUIQuickSlotEmptyItemInfo( ItemCode ); } break; /*case SUIQuickSlotInfo::QSLOTTYPE_CREATURE_SKILL: { AR_HANDLE handle = ((SUIQuickSlotCreatureSkillInfo*)pInfo)->m_hTarget; int ID = ((SUIQuickSlotCreatureSkillInfo*)pInfo)->m_nSkillID; int level = ((SUIQuickSlotCreatureSkillInfo*)pInfo)->m_nSkillLevel; pNewInfo = new SUIQuickSlotCreatureSkillInfo( handle, ID, level ); } break;*/ } return pNewInfo; } void SUIDisplayInfo::RefreshQuickSlot(/* QUICKSLOT_BTNSTATE State, */int nSlotIndex ) { /*if( State >= QUICKSLOT_BTN_MAXCOUNT || nSlotIndex >= c_nQuickSlotCount || State < 0 || nSlotIndex< 0 ) return;*/ if( nSlotIndex >= c_nQuickSlotCount || nSlotIndex< 0 ) return; if( m_pQuickSlots[ nSlotIndex ] == NULL ) return; const SUIQuickSlotInfo* pSlot = GetQuickSlot( nSlotIndex ); if( NULL != pSlot ) { QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo = m_pQuickSlots[ nSlotIndex ]->DisplayInfo; switch( pSlot->m_type ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: { const SUIQuickSlotItemInfo* pItemSlot = (SUIQuickSlotItemInfo*)pSlot; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pItemSlot->m_hItem ); if( pSlot ) { if( RefreshItemQuickSlotDisplayInfo( rQuickSlotDispInfo, pSlot ) ) PostQuickSlotUpdateMsg(); } else { // 아이템이 사라진 경우 슬롯에서 제거한다. SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); PostQuickSlotUpdateMsg(); } } break; // 2012. 3. 28 - marine case SUIQuickSlotInfo::QSLOTTYPE_EMPTYITEM: { const SUIQuickSlotItemInfo* pItemSlot = (SUIQuickSlotItemInfo*)pSlot; if(pSlot) { if( RefreshEmptyItemQuickSlotDisplayInfo( rQuickSlotDispInfo, nSlotIndex ) ) PostQuickSlotUpdateMsg(); } else { // 아이템이 사라진 경우 슬롯에서 제거한다. SAFE_DELETE( m_pQuickSlots[ nSlotIndex ] ); PostQuickSlotUpdateMsg(); } } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: { const SUIQuickSlotSkillInfo* pSkillSlot = (SUIQuickSlotSkillInfo*)pSlot; RefreshSkillQuickSlotDisplayInfo( rQuickSlotDispInfo, pSkillSlot->m_nSkillID, pSkillSlot->m_nSkillLevel ); PostQuickSlotUpdateMsg(); } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: { const SUIQuickSlotMotionInfo* pMotionSlot = (SUIQuickSlotMotionInfo*)pSlot; RefreshMotionQuickSlotDisplayInfo( rQuickSlotDispInfo, pMotionSlot->m_nMotionID ); PostQuickSlotUpdateMsg(); } break; } } } bool SUIDisplayInfo::RefreshItemQuickSlotDisplayInfo( QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo, SInventorySlot* pSlot ) { QUICKSLOT_DISPLAYINFO DisplayInfo; DisplayInfo.bEquip = pSlot->IsEquipItem(); // if( DisplayInfo.bEquip && GetItemDB().GetWearType( pSlot->GetItemCode() ) == ItemBase::WEAR_RIDE_ITEM ) // DisplayInfo.strSubAniName = "static_common_useunitcardicon"; DisplayInfo.nCount = GetItemDB().IsJoin(pSlot->GetItemCode(), IsInstanceUnstackable(pSlot) ) ? pSlot->GetItemCount() : count_t( 0 ); DisplayInfo.strSprName = c_szDEF_SPR_NAME; DisplayInfo.strAniName = GetItemDB().GetIconName( pSlot->GetItemCode() ); DisplayInfo.strTooltip = GetItemTooltipText(pSlot,false); // 아이템 목록이 조금이라도 바뀌면 항상 호출되기 때문에 불필요한 오버헤드를 막기 위해 변경점이 있을때만 true를 리턴하도록 한다. if( rQuickSlotDispInfo != DisplayInfo ) { rQuickSlotDispInfo = DisplayInfo; return true; } return false; } //2012. 3. 28 - marine bool SUIDisplayInfo::RefreshEmptyItemQuickSlotDisplayInfo(QUICKSLOT_DISPLAYINFO &rQuickSlotDispInfo, int nSlotCount) { QUICKSLOT_DISPLAYINFO DisplayInfo; stEmptyItemSet EmptyItemSet = GetEmptyItemSet(nSlotCount); if(EmptyItemSet.iItem_Code == -1) return false; DisplayInfo.bEquip = false; DisplayInfo.nCount = count_t( 0 ); DisplayInfo.strSprName = c_szDEF_SPR_NAME; DisplayInfo.strAniName = GetItemDB().GetIconName( EmptyItemSet.iItem_Code ); DisplayInfo.strTooltip = GetItemName(EmptyItemSet.iItem_Code,false,0,0); // 아이템 목록이 조금이라도 바뀌면 항상 호출되기 때문에 불필요한 오버헤드를 막기 위해 변경점이 있을때만 true를 리턴하도록 한다. if( rQuickSlotDispInfo != DisplayInfo ) { rQuickSlotDispInfo = DisplayInfo; return true; } return false; } void SUIDisplayInfo::RefreshSkillQuickSlotDisplayInfo( QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo, int nSkillID, int nSkillLevel, AR_HANDLE hCreature ) { int nSkillIconID = -1; nSkillIconID = GetSkillDB().GetIconID(nSkillID); if( (-1) != nSkillIconID ) { rQuickSlotDispInfo.bEquip = false; rQuickSlotDispInfo.nCount = count_t( nSkillLevel ); rQuickSlotDispInfo.strSprName = c_szDEF_SPR_NAME; rQuickSlotDispInfo.strAniName = GetSkillDB().GetIconName( nSkillID ); rQuickSlotDispInfo.strTooltip = GetSkillTooltipText( nSkillID, nSkillLevel, false ); } } void SUIDisplayInfo::RefreshMotionQuickSlotDisplayInfo( QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo, int nMotionID ) { //int nMotionIconID = m_MotionMgr.GetMotionIconID( nMotionID ); //if( (-1) != nMotionIconID ) { rQuickSlotDispInfo.bEquip = false; rQuickSlotDispInfo.nCount = count_t( 0 ); rQuickSlotDispInfo.strSprName = c_szDEF_SPR_NAME; rQuickSlotDispInfo.strAniName = GetMotionAniName( nMotionID ); rQuickSlotDispInfo.strTooltip = CStringUtil::StringFormat( "%s
%s", m_MotionMgr.GetMotionName( nMotionID ), m_MotionMgr.GetToolTip( nMotionID ) ).c_str(); } } void SUIDisplayInfo::RefreshAllQuickSlots() { //for( int nBtn( 0 ); nBtn < QUICKSLOT_BTN_MAXCOUNT; ++nBtn ) { for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { SUIQuickSlotInfo* pSlot = m_pQuickSlots/*[ nBtn ]*/[ nSlot ]; if( NULL != pSlot ) { QUICKSLOT_DISPLAYINFO& rQuickSlotDispInfo = pSlot->DisplayInfo; switch( pSlot->m_type ) { case SUIQuickSlotInfo::QSLOTTYPE_ITEM: { const SUIQuickSlotItemInfo* pItemSlot = (SUIQuickSlotItemInfo*)pSlot; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( pItemSlot->m_hItem ); if( pSlot ) RefreshItemQuickSlotDisplayInfo( rQuickSlotDispInfo, pSlot ); else SAFE_DELETE( m_pQuickSlots[ nSlot ] ); // 아이템이 사라진 경우 슬롯에서 제거한다. } break; case SUIQuickSlotInfo::QSLOTTYPE_SKILL: { const SUIQuickSlotSkillInfo* pSkillSlot = (SUIQuickSlotSkillInfo*)pSlot; RefreshSkillQuickSlotDisplayInfo( rQuickSlotDispInfo, pSkillSlot->m_nSkillID, pSkillSlot->m_nSkillLevel ); } break; case SUIQuickSlotInfo::QSLOTTYPE_MOTION: { const SUIQuickSlotMotionInfo* pMotionSlot = (SUIQuickSlotMotionInfo*)pSlot; RefreshMotionQuickSlotDisplayInfo( rQuickSlotDispInfo, pMotionSlot->m_nMotionID ); } break; } } } } PostQuickSlotUpdateMsg(); // sonador 7.0.17 Mantis 0002806: [크리처] 재접속을 하면 스킬창의 정보가 사라집니다. m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CREATURE_QUICK_UPDATE() ); } void SUIDisplayInfo::RefreshItemQuickSlots() { bool bUpdated( false ); for( int nQuickSlotIndex = 0; nQuickSlotIndex < c_nQuickSlotCount; ++nQuickSlotIndex ) { SUIQuickSlotInfo* pSlot( m_pQuickSlots[ nQuickSlotIndex ] ); if( NULL == pSlot ) continue; if( SUIQuickSlotInfo::QSLOTTYPE_ITEM != pSlot->m_type ) continue; SUIQuickSlotItemInfo* pItemSlot( static_cast( pSlot ) ); if( NULL == pItemSlot ) continue; SInventorySlot* pItem( m_InventoryMgr.GetItemInfo( pItemSlot->m_hItem ) ); if( pItem ) { if( RefreshItemQuickSlotDisplayInfo( pSlot->DisplayInfo, pItem ) ) bUpdated = true; } else { if( false == CheckIsChangeEmptyItem( pItemSlot, nQuickSlotIndex ) ) bUpdated = true; } } if( bUpdated ) PostQuickSlotUpdateMsg(); } void SUIDisplayInfo::RefreshSkillQuickSlot( int nSkillID ) { //for( int nBtn( 0 ); nBtn < QUICKSLOT_BTN_MAXCOUNT; ++nBtn ) { for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { const SUIQuickSlotInfo* pSlot = m_pQuickSlots[ nSlot ]; if( NULL != pSlot && SUIQuickSlotInfo::QSLOTTYPE_SKILL == pSlot->m_type ) { if( ((SUIQuickSlotSkillInfo*)pSlot)->m_nSkillID == nSkillID ) PostQuickSlotUpdateMsg(); } } } } void SUIDisplayInfo::RefreshMotionQuickSlot( int nMotionCmd ) { //for( int nBtn( 0 ); nBtn < QUICKSLOT_BTN_MAXCOUNT; ++nBtn ) { for( int nSlot( 0 ); nSlot < c_nQuickSlotCount; ++nSlot ) { const SUIQuickSlotInfo* pSlot = m_pQuickSlots[ nSlot ]; if( NULL != pSlot && SUIQuickSlotInfo::QSLOTTYPE_MOTION == pSlot->m_type ) { if( ((SUIQuickSlotMotionInfo*)pSlot)->m_nMotionCommandID == nMotionCmd ) PostQuickSlotUpdateMsg(); } } } } void SUIDisplayInfo::PostQuickSlotUpdateMsg() { // 퀵슬롯 윈도우로 갱신메시지를 보낸다. m_pGameManager->PostMsgAtDynamic( new SIMSG_REFRESH_QUICKSLOT() ); } void SUIDisplayInfo::ProcConsole( SGameMessage* pGameMsg ) { SMSG_CONSOLE_BUILDER* pMsg = dynamicCast(pGameMsg); std::vector vecKeyList; MsgSplit( pMsg->m_strKey.c_str(), vecKeyList, L"." ); if( vecKeyList.size() < 2 ) { vecKeyList.clear(); return; } // refresh 처리 if( ::_stricmp(vecKeyList[0].c_str(), "refresh") == 0 ) { // 옵션 if( ::_stricmp(vecKeyList[1].c_str(), "opt") == 0 ) { if( vecKeyList.size() > 2 ) { if( ::_stricmp(vecKeyList[2].c_str(), "intf") == 0 ) { m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CONSOLE_RELUST(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_SYSTEM) ); vecKeyList.clear(); return; } } } } // debug else if( ::_stricmp(pMsg->m_strKey.c_str(), "debug.intf.getItemIcon") == 0 ) { if( pMsg->m_nValueCount == 1 ) { std::vector vecInvenList; /// 2010.11.24 - prodongi m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList, m_CreatureSlotMgr ); //m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList ); std::vector::iterator it = vecInvenList.begin(); while( it != vecInvenList.end() ) { SInventorySlot* pSlot = (*it); if( pSlot && ::_stricmp(pMsg->m_vecValueList[0].c_str(), GetItemName(pSlot->GetItemCode(), false, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag()).c_str()) == 0 ) { std::string strResult; XStringUtil::Format( strResult, "%d", pSlot->GetIconID() ); SMSG_CONSOLE_BUILDER ConsoleMsg; ConsoleMsg.m_bOut = true; ConsoleMsg.m_strKey = pMsg->m_strKey; ConsoleMsg.m_nCommandType = SMSG_CONSOLE_BUILDER::TYPE_DEBUG; ConsoleMsg.m_nValueCount = 1; ConsoleMsg.m_vecValueList.push_back( strResult ); if( g_pSBotMng ) g_pSBotMng->ProcConsole( &ConsoleMsg ); vecKeyList.clear(); vecInvenList.clear(); return; } it++; } vecInvenList.clear(); } SMSG_CONSOLE_BUILDER ConsoleMsg; ConsoleMsg.m_bOut = true; ConsoleMsg.m_strKey = pMsg->m_strKey; ConsoleMsg.m_nCommandType = SMSG_CONSOLE_BUILDER::TYPE_DEBUG; ConsoleMsg.m_nValueCount = 0; if( g_pSBotMng ) g_pSBotMng->ProcConsole( &ConsoleMsg ); } vecKeyList.clear(); } void SUIDisplayInfo::ReqGuildIcon( int nGuild_id ) { m_pGameManager->PostMsgAtDynamic( new SMSG_REQ_GUILD_ICON( nGuild_id ) ); } void SUIDisplayInfo::RefectTrade() { SMSG_TRADE* pMsg = new SMSG_TRADE; pMsg->mode = TS_TRADE::REJECT_TRADE; pMsg->target_player = m_PlayerInfoMgr.GetTradeTarget(); pMsg->rq_mode = true; m_pGameManager->PostMsgAtDynamic( pMsg ); } void SUIDisplayInfo::CuttingText( KUIControlStatic* pNameText, const char* pName, std::string& rOutCutName, int nWidth, int nFontSize/*=10*/, const char* szFontName/*=NULL*/ ) { if( !pNameText || !pName ) return; if( szFontName == NULL ) szFontName = S(6426); rOutCutName = pName; KSize size = KTextPhrase::GetStringSize( rOutCutName.c_str(), 1024 ); if( size.width >= nWidth ) { STRING_VECTOR vecLineList; pNameText->SplitLine( vecLineList, rOutCutName.c_str(), szFontName, nFontSize ); if( vecLineList.size() > 0 ) { /*wchar_t wtempCmpStr[1024] ={NULL,}; DWORD CodePage = GetCodePageFromLang((LANGID)GetSystemDefaultLangID()); //이것을 삭제할때는 위의 #include "CInput.h"도 삭제할 것 MultiByteToWideChar(CodePage, 0, vecLineList[0].c_str(), vecLineList[0].length(), wtempCmpStr, 1024); std::wstring wCmpStr = wtempCmpStr; wCmpStr += L".."; char tempCutStr[1024] = {NULL,}; ConvertString(CodePage, wCmpStr.c_str(), wCmpStr.length(), tempCutStr, 1024); rOutCutName = tempCutStr;*/ //유코드 변환 과정에서 윈도우 로컬 관련 문제점을 iconv로 수정 //2009-06-24: hunee std::wstring wstr = nsl::uni::conv(vecLineList[0].c_str()); wstr += L".."; std::string str = nsl::uni::conv(wstr.c_str()); rOutCutName = str; } } } const char* SUIDisplayInfo::GetDragMaterialSound() { int nMaterial(-1); SUIDragInfo* pUIDragInfo = GetUIDragInfo(); if( NULL != pUIDragInfo ) { switch( pUIDragInfo->m_type ) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// case SUIDragInfo::DRAGTYPE_INVENITEM: { SUIInvenItemDragInfo* pItemDragInfo = (SUIInvenItemDragInfo*)pUIDragInfo; nMaterial = GetMaterial(pItemDragInfo->m_hItem); } break; case SUIDragInfo::DRAGTYPE_STORAGE: { SUIStorageDragInfo* pItemDragInfo = (SUIStorageDragInfo*)pUIDragInfo; nMaterial = GetMaterial(pItemDragInfo->m_hItem); } break; case SUIDragInfo::DRAGTYPE_COMBINEITEM: { SUICombineItemDragInfo* pItemDragInfo = (SUICombineItemDragInfo*)pUIDragInfo; nMaterial = GetMaterial(pItemDragInfo->m_hItem); } break; case SUIDragInfo::DRAGTYPE_EQUIPCREATURE: { SUIEquipCreatureInfo* pItemDragInfo = (SUIEquipCreatureInfo*)pUIDragInfo; nMaterial = GetMaterial(pItemDragInfo->m_hItem); } break; case SUIDragInfo::DRAGTYPE_SHOPSELLITEM: { SUIShopSellItemDragInfo* pItemDragInfo = (SUIShopSellItemDragInfo*)pUIDragInfo; nMaterial = GetMaterial(pItemDragInfo->m_hItem); } break; case SUIDragInfo::DRAGTYPE_SHOPBUYITEM: { SUIShopBuyItemDragInfo* pItemDragInfo = (SUIShopBuyItemDragInfo*)pUIDragInfo; nMaterial = GetItemDB().GetMaterial(pItemDragInfo->m_ItemID); } break; case SUIDragInfo::DRAGTYPE_BOOTH: { SUIStoreItemDragInfo* pItemDragInfo = (SUIStoreItemDragInfo*)pUIDragInfo; nMaterial = GetItemDB().GetMaterial(pItemDragInfo->m_Code); } break; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// case SUIDragInfo::DRAGTYPE_MOTION: case SUIDragInfo::DRAGTYPE_CREATURECARD: case SUIDragInfo::DRAGTYPE_SKILL: { nMaterial = -1; } break; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //특별히 어떻게 처리해야할지 추후에 생각해보고 업데이트 해봅시다. case SUIDragInfo::DRAGTYPE_SHOPPINGKART: case SUIDragInfo::DRAGTYPE_QUICKSLOT: //case SUIDragInfo::DRAGTYPE_CREATURE_QUICKSLOT: case SUIDragInfo::DRAGTYPE_CASHITEM: { SUIInvenItemDragInfo* pItemDragInfo = (SUIInvenItemDragInfo*)pUIDragInfo; nMaterial = -1; } break; } // SUICashItemDragInfo{unsigned int item_uid; // cuid (캐쉬템고유번호)}; // SUIShoppingKartDragInfo{bool m_bBuyMode;int m_nIndex;}; // SUIQuickSlotDragInfo{QUICKSLOT_BTNSTATE m_ButtonState;int m_nSlotIndex;}; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } return GetMaterialSound( nMaterial ); } int SUIDisplayInfo::GetMaterial( AR_HANDLE handle ) { SInventorySlot* pItem = m_InventoryMgr.GetItemInfo( handle ); if( pItem ) { return GetItemDB().GetMaterial(pItem->GetItemCode()); } return -1; } int SUIDisplayInfo::GetMaterial_code( int nCode ) { return GetItemDB().GetMaterial(nCode); } const char* SUIDisplayInfo::GetMaterialSound( int nMaterial ) { switch( nMaterial ) { case 0: return "ui_wear_skin01.wav"; break;//피부 case 1: return "ui_wear_leather01.wav"; break;//가죽 case 2: return "ui_wear_wood01.wav"; break;//나무 case 3: return "ui_wear_steel01.wav"; break;//금속 case 4: return "ui_wear_feather01.wav"; break;//깃털 case 5: return "ui_wear_stone01.wav"; break;//돌 case 6: return "ui_wear_bone01.wav"; break;//뼈 case 7: return "ui_wear_acc01.wav"; break;//악세서리 case 8: return "ui_wear_cube01.wav"; break;//큐브 case 9: return "ui_wear_paper01.wav"; break;//종이 case 10: return "ui_wear_shackle01.wav"; break;//쇠사슬 case 11: return "ui_wear_water01.wav"; break;//물 case 12: return "ui_wear_cloth01.wav"; break;//옷감류 case 13: return "ui_wear_powder01.wav"; break;//가루류 case 14: return "soulstonedrop.wav"; break;//보석(소울스톤) default : return "ui_icon_drag.wav"; // case 99: //기타 } return "ui_icon_drag.wav"; } bool SUIDisplayInfo::IsCreatureBattleMode( AR_HANDLE hCreature ) { SGame* pGame = m_pGameManager->GetActiveGame(); if( pGame == NULL ) return false; SGameAvatarEx* pAvatar = (SGameAvatarEx*)( pGame->GetGameObject( hCreature ) ); if( pAvatar ) { if( pAvatar->GetCreatureBattleMode() ) { if( pAvatar->IsMoving() || pAvatar->IsCasting() || pAvatar->IsUsingSkill() ) // pAvatar->IsAttack() || // pAvatar->IsAttacking() || // pAvatar->IsChasing() // pAvatar->IsIng() ) { return false; } return true; } } return false; } void SUIDisplayInfo::UseItemByText( SInventorySlot* pSlot ) { if( pSlot == NULL ) return; SIMSG_UI_ACT_INVENTORY* pMessageChain = new SIMSG_UI_ACT_INVENTORY(); pMessageChain->m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_USE; pMessageChain->m_nHandle = pSlot->GetItem()->handle; // text input 창을 띄워주세요~ m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTTEXT( SIMSG_UI_REQ_INPUTTEXT::USAGE_FEATHER_OF_DESIRE, pMessageChain, SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INVENTORY, S(6523), 6781 ) ); // [sonador][7.0.6] Mantis 0002624 } //펫이름 변경 아이템 추가.. 2009.11.18. sfreer void SUIDisplayInfo::ChangePetName() { /* KillChatFocus(); SMSG_SHOW_SET_PET_NAME* pShowSetPetNameMsg = static_cast< SMSG_SHOW_SET_PET_NAME* >( pMsg ); SGame* ActiveGame = m_pGameManager->GetActiveGame(); if( ActiveGame ) { DATA_PET* PetData = ActiveGame->IsLocalPet( pShowSetPetNameMsg->pet_handle ); if( PetData ) { SIMSG_REQ_SET_PET_NAME* reqSetPetName = new SIMSG_REQ_SET_PET_NAME(); reqSetPetName->handle = pShowSetPetNameMsg->pet_handle; std::string Description = S( 1103 ); XStringUtil::Replace( Description, "#@pet_name@#", PetData->name ); SIMSG_UI_REQ_INPUTTEXT msg( SIMSG_UI_REQ_INPUTTEXT::USAGE_CHANGE_PET_NAME, reqSetPetName, TOGGLE_WINDOW::UIWINDOW_INPUTTEXT, Description.c_str() ); ProcMsgToUIWindow( TOGGLE_WINDOW::UIWINDOW_INPUTTEXT, &msg ); OnShowUIWindow( TOGGLE_WINDOW::UIWINDOW_INPUTTEXT, true, true ); } } pMsg->bUse = true; */ SPetMgr* pPetMgr = GetPetManager(); if( !pPetMgr ) return; AR_HANDLE hPet = pPetMgr->GetSummonPetData().pet_handle; if( !pPetMgr->IsSummonPet(hPet) ) { AddSystemMessage( S(798), 99); // Please summon your decorative pet before trying to rename it. return; } SGame* pGame( m_pGameManager->GetActiveGame() ); if( !pGame ) return; DATA_PET* PetData = m_pGameManager->GetActiveGame()->IsLocalPet( hPet ); if( PetData ) { std::string Description = S( 1103 ); XStringUtil::Replace( Description, "#@pet_name@#", PetData->name ); m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTTEXT( SIMSG_UI_REQ_INPUTTEXT::USAGE_CHANGE_PET_NAME, SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INVENTORY, Description.c_str(), 6785 ) ); } } void SUIDisplayInfo::ChangeCreatureName() { SCreatureSlotMgr* pCreatureSlotMgr = GetCreatureManager(); if( !pCreatureSlotMgr ) return; //소환수 이름표사용시 메인 크리쳐의 이름을 변경하게 수정 //메인 소환수는 index가 0인가? //2009-07-02 : hunee //AR_HANDLE hCreature = pCreatureSlotMgr->GetActiveCreatureQuickSlot(); AR_HANDLE hCreature = pCreatureSlotMgr->GetSummonedCreature(0); if( !pCreatureSlotMgr->IsExistSummonedCreature(hCreature) ) { AddSystemMessage( S(390), 7); // The summoned creature does not exist. return; } else { if( !pCreatureSlotMgr->IsExistSummonedCreature(hCreature) ) { AddSystemMessage( S(390), 7 ); // The summoned creature does not exist. return; } SGame* pGame( m_pGameManager->GetActiveGame() ); if( !pGame ) return; SGameAvatarEx* pCreature = (SGameAvatarEx*)(pGame->GetGameObject(hCreature)); if( !pCreature || !pCreature->IsLocalCreature() ) { AddSystemMessage( S(390), 7 ); // The summoned creature does not exist. return; } std::string strCreatureClass; const SCreatureInfo* pInfo = m_CreatureSlotMgr.GetCreatureInfo( hCreature ); if( pInfo ) { _SUMMON_INFO_FILE * pSummon = GetCreatureDB().GetCreatureData( pInfo->GetID() ); if( pSummon ) strCreatureClass = GetStringDB().GetString( pSummon->name_id ); } std::string strText = SR(6434, "#@creature_class@#", strCreatureClass.c_str(), "#@creature_name@#", pCreature->GetName() ); m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTTEXT( SIMSG_UI_REQ_INPUTTEXT::USAGE_CREATURE_NAMEPLATE, SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INVENTORY, strText.c_str(), 6784 ) ); // [sonador][7.0.6] Mantis 0002624 } } // 2010.08.19 - prodongi std::string SUIDisplayInfo::getItemEffectTooltipText(ItemBaseEx_info const* itemBase, int ethereal) { std::string tooltip; SItemEffectResourceDB::FoundResult found; GetItemEffectResourceDB().Find( itemBase->nEffectId, found ); if(found.size() > 0) { std::string strResultkey; std::string strEffectOption; std::string strTempOption; if (ItemBase::TYPE_CARD == itemBase->nType && 0 == ethereal) { tooltip = ""; } else { SItemEffectResourceDB::FoundResult::iterator it = found.begin(); std::string strTemp1, strTemp2; for (; it != found.end(); ++it) { // 2010.09.03 - prodongi strEffectOption.clear(); ItemEffectResource const* reso = *it; if (1 != reso->ordinal_id) continue; // 2010.07.07 - prodongi if (StateInfo::STATE_ATTACK_TO_TARGET == reso->effect_id || StateInfo::STATE_ATTACK_TO_MY == reso->effect_id || StateInfo::STATE_ATTACKED_TO_ATTACKER == reso->effect_id || StateInfo::STATE_ATTACKED_TO_MY == reso->effect_id) { // 2010.08.27 필요 없는 정보라고 해서 주석처리 함 - prodongi //strEffectOption = GetStateCaseToolTipText(reso->value[0], 0); //strEffectOption += "
"; // 2010.09.03 - prodongi //strEffectOption.clear(); } else { int nCount = 0; for( int i = 0; i < 4; ++ i ) { if( reso->value[nCount] ) { strTempOption = "#@bitset_text@#"; strResultkey = BuildOptionTooltipValue( strTempOption, reso->value[nCount], reso->value[nCount+1], reso->value[nCount+2], 0 ); if (!strTempOption.empty()) { strEffectOption += strTempOption; strEffectOption += "
"; } } nCount += 3; } } strTemp2 = GetStringDB().GetString( reso->tooltip_id ); if( NULL != strstr( strTemp2.c_str(), "#@bitset_text@#")) CStringUtil::ReplacePhrase( strTemp2, "#@bitset_text@#", strEffectOption ); // 2010.08.27 - prodongi //else else if (!strEffectOption.empty()) { // 2010.09.03 - prodongi if (strTemp2.find("
") == std::string::npos) strTemp2 += "
"; strTemp2 += strEffectOption; //strTemp2 += "
"; } strTemp1 += strTemp2; } // 2010.10.04 color값이 항상 <#D600EA>가 아니기 때문에 설정 부분을 삭제한다 - prodongi //tooltip = CStringUtil::StringFormat( "<#D600EA>%s<#ffffff>", strTemp1.c_str() ); tooltip = strTemp1; } } return tooltip; } int SUIDisplayInfo::findEmptyBeltSlot(AR_HANDLE handle) { SInventorySlot* slot = m_InventoryMgr.GetItemInfo(handle); if (!slot) { assert(!slot && "failed find findEmptyBeltSlot item info"); return 0; } int enhance = slot->GetEnhance(); int itemGroup = GetItemDB().GetGroup(slot->GetItemCode()); for (int i = 0; i < c_BeltSlotCnt; ++i) { if (!m_InventoryMgr.GetBeltSlot(i)) { /* AziaMafia PetBelt Change if (ItemBase::GROUP_BOSSCARD == itemGroup ) return i; if (2 == i) { if (1 <= enhance) return i; } else if (3 == i) { if (2 <= enhance) return i; } else */ return i; } } return 0; } int SUIDisplayInfo::getQuestDifficulty(int difficulty, int limitLevel) { int nPlayerLevel = GetPlayerInfoManager()->GetPlayerInfo().GetLevel(); switch( difficulty ) { case 0: if( limitLevel + 4 < nPlayerLevel ) return 0; else if( limitLevel - 4 <= nPlayerLevel && nPlayerLevel <= limitLevel + 4 ) return 1; else if( nPlayerLevel < limitLevel - 4 ) return 2; break; case 1: if( limitLevel + 8 < nPlayerLevel ) return 0; else if( limitLevel <= nPlayerLevel && nPlayerLevel <= limitLevel + 8 ) return 1; else if( nPlayerLevel < limitLevel ) return 2; break; case 2: if( limitLevel + 12 < nPlayerLevel ) return 0; else if( limitLevel + 4 <= nPlayerLevel && nPlayerLevel <= limitLevel + 12 ) return 1; else if( nPlayerLevel < limitLevel + 4 ) return 2; break; case 3: if( limitLevel + 16 < nPlayerLevel ) return 0; else if( limitLevel + 8 <= nPlayerLevel && nPlayerLevel <= limitLevel + 16 ) return 1; else if( nPlayerLevel < limitLevel + 8 ) return 2; break; } return 0; } //----------------------------------------------------------------------------------------------------------------- // 제한 레벨 툴팁 만들기 //----------------------------------------------------------------------------------------------------------------- void SUIDisplayInfo::ReplaceLimitLevelToolTip( string& strToolTip, const ItemBaseEx_info* pItemBase, const int nPlayerLevel ) { if( NULL == pItemBase ) return ; int nLevelLimit( 1 ); if ( 0 < pItemBase->nMinLevel ) // 아이템 랭크와 상관없이 설정된 레벨에 따라서 표시 nLevelLimit = pItemBase->nMinLevel; else nLevelLimit = GameRule::GetItemLevelLimit( pItemBase->nRank ); if( nLevelLimit < 1 ) nLevelLimit = 1; if( nLevelLimit > nPlayerLevel ) CStringUtil::ReplacePhrase( strToolTip, std::string( c_szItemTooltip_LimitLevel ), CStringUtil::StringFormat( "<#ff0000>%d<#ffffff>", nLevelLimit ) ); else CStringUtil::ReplacePhrase( strToolTip, std::string( c_szItemTooltip_LimitLevel ), CStringUtil::StringFormat( "%d", nLevelLimit ) ); } //----------------------------------------------------------------------------------------------------------------- // 권장 레벨 툴팁 만들기 //----------------------------------------------------------------------------------------------------------------- void SUIDisplayInfo::ReplaceRecommandLevelToolTip( string& strToolTip, const ItemBaseEx_info* pItemBase, const BYTE byLevel ) { if( NULL == pItemBase ) return ; int nRecommendLevel( pItemBase->nMaxLevel); if( nRecommendLevel < 0 ) nRecommendLevel = 0; string strRecommendLevel( CStringUtil::StringFormat( "%d", nRecommendLevel ) ); CStringUtil::ReplacePhrase( strToolTip, std::string( c_szItemTooltip_RecommendLevel ), strRecommendLevel ); } //----------------------------------------------------------------------------------------------------------------- // 착용 가능 직업 툴팁 만들기 //----------------------------------------------------------------------------------------------------------------- void SUIDisplayInfo::ReplaceJopDepthToolTip( string& strToolTip, const ItemBaseEx_info* pItemBase, int nJobID ) { if( NULL == pItemBase ) return ; if( ItemBase::JOB_DEPTH_ALL == pItemBase->job_depth ) CStringUtil::ReplacePhrase( strToolTip, std::string( c_szItemTooltip_JobDepth ), S(7247) ); else { bool bWearable = GetItemDB().IsWearablebyJobDepth( pItemBase, nJobID ); std::string temp( "" ); if( bWearable == false ) { temp += "<#ff0000>"; } if (ItemBase::JOB_DEPTH_0 & pItemBase->job_depth) { temp += S(7243); temp += " / "; } if (ItemBase::JOB_DEPTH_1 & pItemBase->job_depth) { temp += S(7244); temp += " / "; } if (ItemBase::JOB_DEPTH_2 & pItemBase->job_depth) { temp += S(7245); temp += " / "; } if (ItemBase::JOB_DEPTH_MASTER & pItemBase->job_depth) { temp += S(7246); temp += " / "; } if (!temp.empty()) { std::string::size_type f = temp.find_last_not_of(" / "); temp = temp.substr(0, f+1); } if( bWearable == false ) { temp += "<#ffffff>"; } CStringUtil::ReplacePhrase( strToolTip, std::string( c_szItemTooltip_JobDepth ), temp); } } //----------------------------------------------------------------------------------------------------------------- // 각성 툴팁 만들기 //----------------------------------------------------------------------------------------------------------------- void SUIDisplayInfo::ReplaceAwakenOptionToolTip( string& strToolTip, const ItemBaseEx_info* pItemBase, TS_ITEM_BASE_INFO::AwakenOption* const pAwakenOption, int ethereal, const bool bAwakeningItem, rp::CAutoToolTip* pAutoToolTip ) { if( NULL == pAwakenOption || NULL == pAutoToolTip ) return ; if( false == bAwakeningItem ) return ; const DWORD* pType( pAwakenOption->nValue ); const int* pValue( pAwakenOption->nData ); string strAwakeningTooltip( "
<#00AEEF><$1252:[Ability activated through awakening]>" ); string strOption( "" ); if( pItemBase->nGroup == ItemBase::GROUP_HELM || pItemBase->nGroup == ItemBase::GROUP_GLOVE || pItemBase->nGroup == ItemBase::GROUP_BOOTS || pItemBase->nGroup == ItemBase::GROUP_BELT) { strAwakeningTooltip = "
<#00AEEF>Ultimate Awakening Options<#ffffff>"; } for ( int nAwakening = 0; nAwakening < ItemBase::MAX_AWAKENING_OPTION; nAwakening++ ) { if ( pType[nAwakening] == 0) continue; std::string strTemp; if( ITEM_EFFECT_PASSIVE::APPLY_EFFECT == pValue[nAwakening])// && 1 == 2 ) // AziaMafia Off APPLY_EFFECT Awaken // Fraun turned it back on 7/20/2025 { strTemp = "#@itemeffecttooltip@#"; ReplaceEffectOptionTooltip( strTemp, pItemBase, pType[nAwakening], ethereal, false); if( strTemp.empty() == true ) continue; strOption.append( "
" ); } else { strOption.append( "
" ); if ( pValue[nAwakening] >= 0 ) { strTemp = CStringUtil::StringFormat("<#00AEEF>%s <#ffffff>", (pAutoToolTip->GetItemAwakeningOptionString(pType[nAwakening])).c_str()); if ( pType[nAwakening] >= ITEM_EFFECT_PASSIVE::INC_FIRE_DAMAGE && pType[nAwakening] <= ITEM_EFFECT_PASSIVE::INC_DARK_DAMAGE || pType[nAwakening] >= ITEM_EFFECT_PASSIVE::INC_DOUBLE_ATTACK && pType[nAwakening] <= ITEM_EFFECT_PASSIVE::INC_BELT_ENHANCE ) strTemp.append( CStringUtil::StringFormat( "<#8DC63F>%d%%<#ffffff>", pValue[nAwakening] ) ); else strTemp.append( CStringUtil::StringFormat( "<#8DC63F>+%d<#ffffff>", pValue[nAwakening] ) ); } else { strTemp = CStringUtil::StringFormat("<#B92C36>%s <#ffffff>", (pAutoToolTip->GetItemAwakeningOptionString(pType[nAwakening])).c_str()); if (pType[nAwakening] >= ITEM_EFFECT_PASSIVE::INC_FIRE_DAMAGE && pType[nAwakening] <= ITEM_EFFECT_PASSIVE::INC_DARK_DAMAGE || pType[nAwakening] >= ITEM_EFFECT_PASSIVE::INC_DOUBLE_ATTACK && pType[nAwakening] <= ITEM_EFFECT_PASSIVE::INC_BELT_ENHANCE ) strTemp.append(CStringUtil::StringFormat("<#B92C36>%d%%<#ffffff>", pValue[nAwakening])); else strTemp.append(CStringUtil::StringFormat("<#B92C36>%d<#ffffff>", pValue[nAwakening])); } } strOption.append( strTemp ); } strAwakeningTooltip.append( strOption ); CStringUtil::ReplacePhrase( strToolTip, c_szItemTooltip_AwakenOption, strAwakeningTooltip ); } // Fraun Sky Accessories 7/12/2025 void SUIDisplayInfo::ReplaceAdditionalItemEffectOptionTooltip( string& strToolTip, const ItemBaseEx_info* pItemBase, int nAdditionalItemEffect, rp::CAutoToolTip* pAutoToolTip ) { string strAdditionalItemEffect(""); SItemEffectResourceDB::FoundResult found; GetItemEffectResourceDB().Find(nAdditionalItemEffect, found); // Searching in the ItemEffect rdb for our additional item effect if (found.size() > 0) { strAdditionalItemEffect += S(5303); //
<#a9cce3>Additional stats:
std::string strResultkey; std::string strEffectOption; std::string strTempOption; SItemEffectResourceDB::FoundResult::iterator it = found.begin(); std::string strTemp1, strTemp2; for (; it != found.end(); ++it) { strEffectOption.clear(); ItemEffectResource const* reso = *it; if (1 != reso->ordinal_id) continue; if( StateInfo::STATE_ATTACK_TO_TARGET != reso->effect_id && StateInfo::STATE_ATTACK_TO_MY != reso->effect_id && StateInfo::STATE_ATTACKED_TO_ATTACKER != reso->effect_id && StateInfo::STATE_ATTACKED_TO_MY != reso->effect_id) { int nCount = 0; for (int i = 0; i < 4; ++i) { if (reso->value[nCount]) { strTempOption = "#@bitset_text@#"; strResultkey = BuildOptionTooltipValue( strTempOption, reso->value[nCount], reso->value[nCount + 1], reso->value[nCount + 2], 0); if (!strTempOption.empty()) { strEffectOption += strTempOption; strEffectOption += "
"; } } nCount += 3; } } strTemp2 = GetStringDB().GetString(reso->tooltip_id); if (NULL != strstr(strTemp2.c_str(), "#@bitset_text@#")) { CStringUtil::ReplacePhrase(strTemp2, "#@bitset_text@#", strEffectOption); } else if (!strEffectOption.empty()) { if (strTemp2.find("
") == std::string::npos) { strTemp2 += "
"; } strTemp2 += strEffectOption; } strTemp1 += strTemp2; } strAdditionalItemEffect += strTemp1; strAdditionalItemEffect += "
"; } CStringUtil::ReplacePhrase(strToolTip, c_szItemTooltip_AdditionalItemEffect, strAdditionalItemEffect); } //----------------------------------------------------------------------------------------------------------------- // 랜덤 옵션 툴팁 만들기 //----------------------------------------------------------------------------------------------------------------- void SUIDisplayInfo::ReplaceRandomOptionTooltip( string& strToolTip, const ItemBaseEx_info* pItemBase, TS_ITEM_BASE_INFO::RANDOM_OPTION* const pRandomOption, int ethereal, const bool bIsRandomOptionItem, const bool bIsIdentifiedRandomOptionItem ) { if( NULL == pRandomOption ) return; if( bIsRandomOptionItem && // 랜덤 옵션 아이템이고 bIsIdentifiedRandomOptionItem && // 확인 된 아이템이고 pRandomOption->IsHaveData() ) // 데이터가 있다면 { string strRandomOptionTooltip( "
<#FFFFFF>" ); strRandomOptionTooltip.append( S( 690000048 ) ); // [Random Effects] strRandomOptionTooltip.append( "<#D600EA>" ); for ( int nRandomOptionIndex = 0; nRandomOptionIndex < ItemBase::MAX_RANDOM_OPTION_NUMBER; nRandomOptionIndex++ ) { const int nType( pRandomOption->nType[nRandomOptionIndex] ); const double dbValue( pRandomOption->stValue[nRandomOptionIndex] ); const double dbData( pRandomOption->stData[nRandomOptionIndex] ); if( NONE == nType ) continue; string strRandomOptionDetail; if( ITEM_EFFECT_PASSIVE::APPLY_EFFECT == nType ) { strRandomOptionDetail = "#@itemeffecttooltip@#"; ReplaceEffectOptionTooltip( strRandomOptionDetail, pItemBase, static_cast< int >( dbValue ), ethereal, false ); if( strRandomOptionDetail.empty() == true ) continue; strRandomOptionTooltip.append( "
" ); } else { strRandomOptionDetail = GetItemRandomOptionString( nType, dbValue, dbData ); if( strRandomOptionDetail.empty() == true ) continue; strRandomOptionTooltip.append( "
" ); } strRandomOptionTooltip.append( strRandomOptionDetail ); } strRandomOptionTooltip.append( "<#FFFFFF>" ); CStringUtil::ReplacePhrase( strToolTip, c_szItemTooltip_RandomOption, strRandomOptionTooltip ); } } //----------------------------------------------------------------------------------------------------------------- // 랜덤 옵션에 따른 툴팁 얻기 //----------------------------------------------------------------------------------------------------------------- string SUIDisplayInfo::GetItemRandomOptionString( const int nType, double fVar1, double fVar2 ) { std::string strResult( "" ); std::string strKeyword( GetItemTooltipKeyword( nType ) ); if( !strKeyword.empty() ) { if( strKeyword == "INC_PARAMETER_A" ) { strResult = GetItempBitsetAText( 7153, fVar1, fVar2, false, NULL ); } else if( strKeyword == "INC_PARAMETER_B" ) { strResult = GetItempBitsetBText( 7153, fVar1, fVar2, false, NULL ); } else if( strKeyword == "AMP_PARAMETER_A" ) { fVar2 *= 100.0f; strResult = GetItempBitsetAText( 7153, fVar1, fVar2, true, NULL ); } else if( strKeyword == "AMP_PARAMETER_B" ) { fVar2 *= 100.0f; strResult = GetItempBitsetBText( 7153, fVar1, fVar2, true, NULL ); } else if (strKeyword == "INC_SOCKET_COUNT_A" && (int)fVar1 > 0 ) { XStringUtil::Format(strResult, "Socket +%d", (int)fVar1); SDEBUGLOG( "[SDisplayInfo]" ); } else if (strKeyword == "INC_SOCKET_COUNT_B" && (int)fVar1 > 0 ) { XStringUtil::Format(strResult, "Socket +%d", (int)fVar1); SDEBUGLOG( "[SDisplayInfo]랜덤 옵션 소캣추가 (B)" ); } else if (strKeyword == "ADD_STATE_BY_EQUIP_ITEM" && (int)fVar1 > 0) { strResult = ("<#FF9B0C>[skin] @name_creature@ Evo @evolution@ @stage@<#D600EA>"); std::string strValue = S(GetCreatureDB().GetTextID((int)fVar1)); std::string stage = S(6998); std::string Evo = CStringUtil::StringFormat("%d", GetCreatureDB().GetEvolutionForm((int)fVar1)).c_str(); CStringUtil::ReplacePhrase(strResult, "@name_creature@", strValue); CStringUtil::ReplacePhrase(strResult, "@evolution@", Evo); if ((int)fVar2 == 1) CStringUtil::ReplacePhrase(strResult, "@stage@", " "); else CStringUtil::ReplacePhrase(strResult, "@stage@", stage); } else if (strKeyword == "INC_SKILL") { std::string tip(""); SkillBaseEx* s_need_data = GetSkillDB().GetSkillData((int)fVar1); if (s_need_data) { if (g_pCurrentGameSystem->GetSkillSlotMgr().GetCurrentSkillLevel(s_need_data->GetID()) > 0 ) { tip += "<#8DC63F>"; std::string strSkillName = GetStringDB().GetString(s_need_data->GetNameID()); tip += SR(4470, "#@skill_name@#", strSkillName.c_str(), "#@skill_level@#", CStringUtil::StringFormat("%d", (int)fVar2).c_str()); tip += "<#D600EA>"; //std::string Evo = CStringUtil::StringFormat("%d", g_pCurrentGameSystem->GetSkillSlotMgr().GetCurrentSkillLevel(s_need_data->GetID()) ); //CStringUtil::ReplacePhrase(tip, "%pop", Evo); } else { tip += "<#B92C36>"; std::string strSkillName = GetStringDB().GetString(s_need_data->GetNameID()); tip += SR(4470, "#@skill_name@#", strSkillName.c_str(), "#@skill_level@#", CStringUtil::StringFormat("%d", (int)fVar2).c_str()); tip += "<#B92C36>"; //std::string Evo = CStringUtil::StringFormat("%d", g_pCurrentGameSystem->GetSkillSlotMgr().GetCurrentSkillLevel(s_need_data->GetID())); //CStringUtil::ReplacePhrase(tip, "%pop", Evo); } CStringUtil::ReplacePhrase(tip, "", ""); strResult = tip; SDEBUGLOG("[SDisplayInfo]랜덤 옵션 소캣추가 (B)"); } } else if (strKeyword == "INC_ALL_DAMAGE") { fVar2 *= 100.0f; strResult = SR(2100033349, "#@d@#", CStringUtil::StringFormat("%d", (int)fVar2).c_str()); } else if (strKeyword == "REDUC_ALL_DAMAGE") { fVar2 *= 100.0f; strResult = SR(2100033350, "#@d@#", CStringUtil::StringFormat("%d", (int)fVar2).c_str()); } else { // 기획자와 이야기 된 부분 다른 타입을 쓸 경우 추가 코딩이 필요 SLOG( "[SDisplayInfo] 랜덤 옵션에서 지원하지 않는 타입입니다. [%d]", nType ); } } return strResult; } void SUIDisplayInfo::ReplaceEffectOptionTooltip( string& strTooltip, const ItemBaseEx_info* pItemBase, int nEffectID, int ethereal, bool add_tag ) { SItemEffectResourceDB::FoundResult found; GetItemEffectResourceDB().Find( nEffectID, found ); std::string strResultkey; std::string strEffectOption; std::string strEffect_tooltip; if(found.size() > 0) { if (ItemBase::TYPE_CARD == pItemBase->nType && 0 == ethereal) { strEffect_tooltip = ""; } else { SItemEffectResourceDB::FoundResult::iterator it = found.begin(); std::string strTemp1, strTemp2; for (; it != found.end(); ++it) { ItemEffectResource const* reso = *it; if (1 != reso->ordinal_id) continue; // 2010.07.07 - prodongi if (StateInfo::STATE_ATTACK_TO_TARGET == reso->effect_id || StateInfo::STATE_ATTACK_TO_MY == reso->effect_id || StateInfo::STATE_ATTACKED_TO_ATTACKER == reso->effect_id || StateInfo::STATE_ATTACKED_TO_MY == reso->effect_id) { strEffectOption.clear(); } else { int nCount = 0; bool bNeedBRTag = false; for( int i = 0; i < 4; ++ i ) { if( reso->value[nCount] ) { if( bNeedBRTag == true ) { strEffectOption += "
"; bNeedBRTag = false; } std::string strTempOption = "#@bitset_text@#"; strResultkey = BuildOptionTooltipValue( strTempOption, reso->value[nCount], reso->value[nCount+1], reso->value[nCount+2], 0 ); if (!strTempOption.empty()) { strEffectOption += strTempOption; bNeedBRTag = true; } } nCount += 3; } } strTemp2 = GetStringDB().GetString( reso->tooltip_id ); if( NULL != strstr( strTemp2.c_str(), "#@bitset_text@#")) CStringUtil::ReplacePhrase( strTemp2, "#@bitset_text@#", strEffectOption ); // 2010.08.27 - prodongi //else else if (!strEffectOption.empty()) { // ù
if( add_tag == true ) { strTemp2 += "
"; } strTemp2 += strEffectOption; } strTemp1 += strTemp2; } if( add_tag == true ) { strEffect_tooltip = CStringUtil::StringFormat( "<#D600EA>%s
<#ffffff>", strTemp1.c_str() ); } else { strEffect_tooltip = strTemp1; } } CStringUtil::ReplacePhrase( strTooltip, "#@itemeffecttooltip@#", strEffect_tooltip ); } #ifdef _MEMORY_LEAK_FIX_ /// 2012.04.12 - prodongi found.clear(); #endif } void SUIDisplayInfo::getQuestDifficultyColor(int difficulty, int limitLevel, std::string &color) { int diff = getQuestDifficulty(difficulty, limitLevel); if (0 == diff) color = "<#e4e4e4>"; else if (1 == diff) color = "<#3cb878>"; else if (2 == diff) color = "<#b92c36>"; } rp::CAutoToolTip* SUIDisplayInfo::GetAutoToolTip() { return m_pAutoToolTip ? m_pAutoToolTip : NULL; }