Files
Leviathan/Client/Game/game/Interface/SUIDisplayInfo.cpp
T
2026-06-01 12:46:52 +02:00

9416 lines
316 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include <algorithm>
//#include <string>
#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 <toolkit/XStringUtil.h>
#include <toolkit/XEnv.h>
#include "KCommandBuilder.h"
#include <toolkit/nsluni.h>
#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 <toolkit/nsl.h>
#include <toolkit/nsluni.h>
#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<std::string>& 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<SRaidMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::RAID_MGR ) ) )
, m_PartyMgr( *static_cast<CPartyListMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PARTY_MGR )) )
, m_GuildMgr( *static_cast<SGuildMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILD_MGR )) )
, m_FriendMgr( *static_cast<SFriendMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::FRIEND_MGR )) )
, m_CutMgr( *static_cast<SCutMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CUT_MGR )) )
, m_TradeMgr( *static_cast<STradeMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::TRADE_MGR )) )
, m_StorageMgr( *static_cast<SStorageMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::STORAGE_MGR )) )
, m_MotionMgr( *static_cast<SMotionMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::MOTION_MGR )) )
, m_PlayerInfoMgr( *static_cast<SPlayerInfoMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PLAYERINFO_MGR )) )
, m_InventoryMgr( *static_cast<SInventoryMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::INVENTORY_MGR )) )
, m_CreatureSlotMgr( *static_cast<SCreatureSlotMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESLOT_MGR )) )
, m_SkillSlotMgr( *static_cast<SSkillSlotMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::SKILLSLOT_MGR )) )
, m_CreatureSkillSlotMgr( *static_cast<SCreatureSkillSlotMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESKILLSLOT_MGR )) )
, m_GuildDataMgr( *static_cast<SGuildDataMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILDDATA_MGR )) )
, m_PetMgr( *static_cast<SPetMgr*>(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<QUICKSLOT_BTN_MAXCOUNT; ++i )
{
for( int j(0); j<c_nQuickSlotCount; ++j )
SAFE_DELETE( m_pQuickSlots[j] );
}
// sonador 10.4.1 스킬 툴팁 리뉴얼
SAFE_DELETE( m_pSkillSubject );
SAFE_DELETE( m_pSkillTooltipComposer );
SAFE_DELETE( m_pAutoToolTip );
}
class SCreatureSlotMgr* SUIDisplayInfo::GetCreatureManager() const { return &m_CreatureSlotMgr; };
class SSkillSlotMgr* SUIDisplayInfo::GetSkillSlotManager() const { return &m_SkillSlotMgr; };
class SPlayerInfoMgr* SUIDisplayInfo::GetPlayerInfoManager() const { return &m_PlayerInfoMgr; };
// { [soandor][3.1.2] 경매장 구현
class SInventoryMgr* SUIDisplayInfo::GetInventoryManager() const { return &m_InventoryMgr; };
class SPetMgr* SUIDisplayInfo::GetPetManager() const { return &m_PetMgr; };
// }
bool SUIDisplayInfo::IsPartyMember( AR_HANDLE hTarget )
{
return m_PartyMgr.FindMember( hTarget ) != NULL ? true : false;
}
bool SUIDisplayInfo::IsExistItem( int nItemCode )
{
return m_InventoryMgr.IsExistItem( nItemCode );
}
bool SUIDisplayInfo::IsExistInvenItem( int nItemCode )
{
return m_InventoryMgr.IsExistInvenItem( nItemCode );
}
void SUIDisplayInfo::Process( DWORD dwTime )
{
m_dwCurTime = dwTime;
static DWORD last_time = 500;
if( dwTime > 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<SIMSG_HOTKEY_EX*>(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<SkillResult>::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 "<center><out>M</out>";
}
// 키로 단위 체크
else if( *nJP > c_nJPKLimit )
{
*nJP /= 1000;
return "<center><OUT>K</OUT>";
}
*/
/*
// 키로 단위 체크
/// 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<float>(nCur)/static_cast<float>(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<int>(fPer);
int nRest = static_cast<int>(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<SGameWorld*>(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 )
{
// Lets 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("<br>[ %d ]<br>",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 += "<br>";
}
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 += "<br>";
}
tooltip += nextTip;
}
/// 2011.04.22 - prodongi
if (!isLastBR(tooltip.c_str()))
{
tooltip += "<br>";
}
}
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 += "<BR>";
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<int> vIDList;
GetCreatureDB().GetEvolveID( pInfo->GetID(), vIDList ); //진화전의 크리처 아이디도 얻어온다
maxLv = 0;
const std::vector< SkillTreeEx >* pSkillTreeList;
for( int i(0); i<vIDList.size(); ++i )
{
const _SUMMON_INFO_FILE* pSummonDB = GetCreatureDB().GetCreatureData( vIDList[i] );
if( pSummonDB == NULL )
continue;
for( int i = 0; i < _countof( pSummonDB->skill_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; i<c_MaxPoint; ++i )
// {
// if( (int)(f_Time*sq) ) break;
// sq *= 10;
// }
// std::string strPoint = CStringUtil::StringFormat( "%%.%df", i );
// strPoint += "%s";
// return strTime += CStringUtil::StringFormat( strPoint.c_str(), f_Time, S(7025) );
return strTime += CStringUtil::StringFormat( "%.1f%s", f_Time, S(7025) );
}
else return strTime += CStringUtil::StringFormat( "%d%s", (int)f_Time, S(7025) );
}
return strTime;
}
/// 2011.06.20 - prodongi
std::string SUIDisplayInfo::GetCoolTimeString(float t) const
{
std::string str = S(77);
str += " ";
str += GetTimeString(t);
return str;
}
/*
std::string SUIDisplayInfo::GetSkillTooltip( int nSkillID, int nUseLevel )
{
if( m_pSkillSlotMgr == NULL ) return "err";
SkillBaseEx* s_data = GetSkillDB().GetSkillData( nSkillID );
if( s_data == NULL ) return std::string( "" );
if( !s_data->IsPassive() )
{
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); //"<size:2><BR>";
strToolTip += S(6298); //"<size:8>[ 필요조건 ]";
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<SGameWorld*>(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); i<StoreItemCount; ++i )
{
if( SStoreMgr::GetInstance().GetItemHandle(i) == hItem )
return true;
}
return false;
}
void SUIDisplayInfo::SetPartyTarget( AR_HANDLE hTarget )
{
m_hPartyHandle = hTarget;
}
void SUIDisplayInfo::UseNameChangeItem( AR_HANDLE hItem, AR_HANDLE hCreature, const char* lpText )
{
if( !hItem || !hCreature || !lpText ) 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;
invMsg.m_nActType = SIMSG_UI_ACT_INVENTORY::ACT_USE;
invMsg.m_TargetHandle = hCreature; //선택된 크리쳐만 가능
invMsg.m_ItemUseTargetHandle = hCreature;
invMsg.m_strParameter = lpText;
m_pGameManager->ProcMsgAtStatic( &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<int> xFlag /* = XFlag<int>() */,
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<int, std::pair<int, int>> nSkyItemEffects;
if (nSkyItemEffects.empty())
{
nSkyItemEffects[110000] = std::pair<int, int>(1, 70); // Strength
nSkyItemEffects[110010] = std::pair<int, int>(2, 70); // Strength
nSkyItemEffects[110020] = std::pair<int, int>(3, 70); // Strength
nSkyItemEffects[110030] = std::pair<int, int>(4, 70); // Strength
nSkyItemEffects[110040] = std::pair<int, int>(5, 70); // Strength
nSkyItemEffects[110050] = std::pair<int, int>(6, 70); // Strength
nSkyItemEffects[110060] = std::pair<int, int>(7, 70); // Strength
nSkyItemEffects[110070] = std::pair<int, int>(8, 70); // Strength
nSkyItemEffects[110080] = std::pair<int, int>(9, 70); // Strength
nSkyItemEffects[110001] = std::pair<int, int>(1, 71); // Vitality
nSkyItemEffects[110011] = std::pair<int, int>(2, 71); // Vitality
nSkyItemEffects[110021] = std::pair<int, int>(3, 71); // Vitality
nSkyItemEffects[110031] = std::pair<int, int>(4, 71); // Vitality
nSkyItemEffects[110041] = std::pair<int, int>(5, 71); // Vitality
nSkyItemEffects[110051] = std::pair<int, int>(6, 71); // Vitality
nSkyItemEffects[110061] = std::pair<int, int>(7, 71); // Vitality
nSkyItemEffects[110071] = std::pair<int, int>(8, 71); // Vitality
nSkyItemEffects[110081] = std::pair<int, int>(9, 71); // Vitality
nSkyItemEffects[110002] = std::pair<int, int>(1, 73); // Agility
nSkyItemEffects[110012] = std::pair<int, int>(2, 73); // Agility
nSkyItemEffects[110022] = std::pair<int, int>(3, 73); // Agility
nSkyItemEffects[110032] = std::pair<int, int>(4, 73); // Agility
nSkyItemEffects[110042] = std::pair<int, int>(5, 73); // Agility
nSkyItemEffects[110052] = std::pair<int, int>(6, 73); // Agility
nSkyItemEffects[110062] = std::pair<int, int>(7, 73); // Agility
nSkyItemEffects[110072] = std::pair<int, int>(8, 73); // Agility
nSkyItemEffects[110082] = std::pair<int, int>(9, 73); // Agility
nSkyItemEffects[110003] = std::pair<int, int>(1, 72); // Dexterity
nSkyItemEffects[110013] = std::pair<int, int>(2, 72); // Dexterity
nSkyItemEffects[110023] = std::pair<int, int>(3, 72); // Dexterity
nSkyItemEffects[110033] = std::pair<int, int>(4, 72); // Dexterity
nSkyItemEffects[110043] = std::pair<int, int>(5, 72); // Dexterity
nSkyItemEffects[110053] = std::pair<int, int>(6, 72); // Dexterity
nSkyItemEffects[110063] = std::pair<int, int>(7, 72); // Dexterity
nSkyItemEffects[110073] = std::pair<int, int>(8, 72); // Dexterity
nSkyItemEffects[110083] = std::pair<int, int>(9, 72); // Dexterity
nSkyItemEffects[110004] = std::pair<int, int>(1, 74); // Intelligence
nSkyItemEffects[110014] = std::pair<int, int>(2, 74); // Intelligence
nSkyItemEffects[110024] = std::pair<int, int>(3, 74); // Intelligence
nSkyItemEffects[110034] = std::pair<int, int>(4, 74); // Intelligence
nSkyItemEffects[110044] = std::pair<int, int>(5, 74); // Intelligence
nSkyItemEffects[110054] = std::pair<int, int>(6, 74); // Intelligence
nSkyItemEffects[110064] = std::pair<int, int>(7, 74); // Intelligence
nSkyItemEffects[110074] = std::pair<int, int>(8, 74); // Intelligence
nSkyItemEffects[110084] = std::pair<int, int>(9, 74); // Intelligence
nSkyItemEffects[110005] = std::pair<int, int>(1, 75); // Wisdom
nSkyItemEffects[110015] = std::pair<int, int>(2, 75); // Wisdom
nSkyItemEffects[110025] = std::pair<int, int>(3, 75); // Wisdom
nSkyItemEffects[110035] = std::pair<int, int>(4, 75); // Wisdom
nSkyItemEffects[110045] = std::pair<int, int>(5, 75); // Wisdom
nSkyItemEffects[110055] = std::pair<int, int>(6, 75); // Wisdom
nSkyItemEffects[110065] = std::pair<int, int>(7, 75); // Wisdom
nSkyItemEffects[110075] = std::pair<int, int>(8, 75); // Wisdom
nSkyItemEffects[110085] = std::pair<int, int>(9, 75); // Wisdom
}
std::map<int, std::pair<int, int>>::iterator skyIt = nSkyItemEffects.find(nAdditionalItemEffect);
if (skyIt != nSkyItemEffects.end())
{
itemAdditionalPlus += "[+";
itemAdditionalPlus += std::to_string(static_cast<long long>(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( "<size:10>+%d ", byEnhance ) + strItemName;
else
strItemName = CStringUtil::StringFormat( "<size:13><#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<int> xFlag, /* = XFlag<int>() */
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("<size:10>[ summon : %d ]<br>",nSummonID).c_str();
strTooltip += "<size:13>";
//휘귀도에 따른 랭크아이콘
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 += "<br>";
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 += "<br>";
}
}
}
else
{
strTooltip = GetItemName( nItemID, false, byEnhance, byLevel, xFlag );
if( byLevel > 0 )
strTooltip += CStringUtil::StringFormat( " <#FFFF00>Lv%d<#FFFFFF>", byLevel );
strTooltip += "<br>";
strTooltip += SStringDB::ParseString( GetStringDB().GetString( 25 ), "#@creature_name@#", GetStringDB().GetString( nCreatureNameID ) );
}
}
else
{
if( !bDetail )
strTooltip = CStringUtil::StringFormat( "<#fbe6ad><size:13>%s<#ffffff>", GetItemName( nItemID, false ).c_str() );
else // 크리처 테이밍 할 수 있는 카드
strTooltip = SStringDB::ParseString( GetStringDB().GetString( GetItemDB().GetToolTipID( nItemID ) ) );
}
if( nSummonID )
{
strTooltip += "<br>";
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 += "<size:10>";
strTooltip += "<br>";
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 += "<br>";
strTooltip += GetStringDB().GetString( 34 );
strTooltip += GetStringDB().GetString( 35 );
}
}
// 2010.05.06 강화단계 - prodongi
strTooltip += "<br>";
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 += "<br>";
strTooltip += CStringUtil::StringFormat("%s : %d", S(7815), dur);
}
if( bDetail )
{
// 아이템 이름
/// 2010.10.10 - prodongi
strItemName = CStringUtil::StringFormat( "<#fbe6ad><size:13>%s<#ffffff>", GetItemName( nItemID, false, 0, 0, XFlag<int>(), 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><size:13>%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( "<size:13>%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 += "<size:10><br>";
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 += "<br>";
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("<br><size:10>[ %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 += "<BR>";
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 += "<br><#00AEEF><$2110000107:><#ffffff>"; // "<br><#00AEEF><$1251:각성가능> = <$10705001:각성가능><#ffffff>"
}
if (pItemBase->nClass == ItemBase::CLASS_EARRING ||
pItemBase->nClass == ItemBase::CLASS_RING ||
pItemBase->nClass == ItemBase::CLASS_ARMULET
)
{
strTooltip += "<br><#00AEEF><$2110000108:><#ffffff>"; // <br><#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 += "<br><#00AEEF><$2110000109:><#ffffff>"; // <br><#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("<BR>");
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 += "<br>";
if( !bNextSTr ) strTooltip += "<br>";
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<ItemBase*> 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 += "<BR>";
setEquippedItems += GetStringDB().GetString( stringId );
}
else
{
setEquippedItems += "<#808080>";
setEquippedItems += "<BR>";
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 += "<BR>";
setEquippedItems += GetStringDB().GetString( vSetItemData[n]->nNameId );
}
// 비활성화
else
{
setEquippedItems += "<#808080>";
setEquippedItems += "<BR>";
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 += "<BR>";
// 셋트 아이템 특수 성능 툴팁
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 += "<BR>";
setEquippedItems += "<#FFFFFF>";
CStringUtil::ReplacePhrase( strTooltip, "#@setitem_part@#", setEquippedItems );
CStringUtil::ReplacePhrase( strTooltip, "#@setitem_fx@#", setFxTooltip );
}
}
if( nRemainTime > 0 ) //대여 아이템
{
strTooltip += "<br>";
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 += "<br><br>";
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( "<br><#FFF020><$690000033:부여석으로 인한 추가 물리 피해> +%d<#FFFFFF>", elemental_effect_attack_point );
if ( elemental_effect_magic_point > 0 )
strTooltip += CStringUtil::StringFormat( "<br><#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 +="<br>강제출력<br>Ethereal_Durability:#@Ethereal_Durability@#<br>Ethereal_Durability_test:#@Ethereal_Durability_test@#<br>Soulstone_Durability_test:#@Soulstone_Durability_test@#<br>";
}
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 += "<br><br><#b92c36>";
strTooltip += S(1153);
}
}
if ( nEnhance_chance )
{
strTooltip += CStringUtil::StringFormat( "<br><#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 += "<BR><size:4><BR><size:10><#FFFFFF>";
}
}
int nJewelID(0);
std::string strSoketIcon;
std::vector<std::string> vecJewelStr;
for( int i(0); i<nSlotCnt; ++i )
{
if( pLevel )
nJewelID = pLevel[i];
else nJewelID = 0;
std::string strJewel;
if( !nJewelID )
{
strJewel = "#@socket_empty@#<offset:25>";
strJewel += S(93);
vecJewelStr.push_back(strJewel);
}
else
{
GetSoketTag(nJewelID, strSoketIcon);
if( strSoketIcon.empty() ) continue;
strJewel = CStringUtil::StringFormat( "%s<offset:25>", strSoketIcon.c_str() );
int nType;
double dVar1, dVar2;
std::vector<std::string> 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); i<vecStr.size(); ++i )
{
if( i>0 ) strJewel += " / ";
strJewel += vecStr[i];
}
if( !vecStr.empty() )
vecJewelStr.push_back(strJewel);
vecStr.clear();
}
}
for( int i(0); i<vecJewelStr.size(); ++i )
{
if( i>0 ) strOptionVale += "<br>";
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<SSkillSlot*>& vecSkillList = m_SkillSlotMgr.GetSkillList();
std::vector<SSkillSlot*>::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;j<HOTKEYCODE::MAX;j++)
{
KEYEX key;
std::string strtemp = szKeymappingHeader;
key= table.GetKeymapping(j);
strtemp += CStringUtil::StringFormat( "%d%s%d%s%d%s%d%s%d",
j,
c_szKeymappingDivision,
(key.bAlt ? 1:0),
c_szKeymappingDivision,
(key.bShift ? 1:0),
c_szKeymappingDivision,
(key.bCtrl ? 1:0),
c_szKeymappingDivision,
key.wParam );
strtemp += c_szClientInfoLinefeed;
rSaveString += strtemp;
}
// 엔터채팅여부
{
std::string strtemp = szEnterchatHeader;
if(table.IsEnterChat())
strtemp+="1";
else
strtemp+="0";
strtemp+=c_szClientInfoLinefeed;
rSaveString+=strtemp;
}
}
//유저 키맵핑 분리저장
void SUIDisplayInfo::LoadSavedKeyInfo( const std::string& rInfoString )
{
m_dwLastClientInfoSaveTime = m_dwCurTime; // 이 시점부터 client info를 저장할 수 있게 된다.
m_strPreviousSavedKeyInfo = rInfoString;
STRING_VECTOR TextLines;
CStringUtil::GetTextLinesFromString( rInfoString, TextLines, c_szClientInfoLinefeed );
//키맵핑 정보 읽기
bool bEnterChat = true;
int nVersion = 0;
GetGameSavedKeymapping().Clear();
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_szKeymapping2Header, strContent ) )
{
LoadKeymappingInfo( GetGameSavedKeymapping(), 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(!bEnterChat)
{
SGameWorldKeymapping PrevRappelzDefKeymapping;
PrevRappelzDefKeymapping.SetPrevRappelzDefaultKeymapping();
if(GetGameSavedKeymapping() != PrevRappelzDefKeymapping)
{
bEnterChat = true;
}
}
GetGameSavedKeymapping().EnterChat(bEnterChat);
if( nVersion == KEYMAP_VERSION::BEGINER || // 신규 유저, 키맵핑을 한번도 바꾸지 않은 유저.
nVersion != c_iClinetDataVersion ) // 버전이 다르면 그냥 초기화
{
GetGameSavedKeymapping().Clear();
}
SaveKeymappingInfo_saved();
//만약 키맵핑 설정이 없다면..
if(GetGameSavedKeymapping().IsEmpty())
{
#if 0
// 옵션(키설정)부 "저장정보 불러오기" 비활성
SUISystemWnd* pSystemWnd = ( SUISystemWnd* )m_pGameManager->GetGameInterface()->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<SInventorySlot*> vecInvenList;
/// 2010.11.24 - prodongi
m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList, m_CreatureSlotMgr );
//m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList );
for( std::vector<SInventorySlot*>::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("<B><#FF9B0C>[skin] @name_creature@ Evo @evolution@ @stage@</B><#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<const SUIQuickSlotSkillInfo*>(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); state<QUICKSLOT_BTN_MAXCOUNT; ++state )
//{
for( int index(0); index<c_nQuickSlotCount; ++index )
{
if( !m_pQuickSlots[index] || m_pQuickSlots[index]->m_type != SUIQuickSlotInfo::QSLOTTYPE_SKILL ) continue;
SkillSlot = static_cast<SUIQuickSlotSkillInfo*>( 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<int>(QS_WAITING), nSlotIndex );
m_ExistEmptyItem.pushEmptyItem( stNewEmptyItemSet );
return true;
}
return false;
}
void SUIDisplayInfo::EmptyItemCheckandDelete( int nSlotCount )
{
std::vector<stEmptyItemSet>::iterator it = m_ExistEmptyItem.vEmptyItems.begin();
std::vector<stEmptyItemSet>::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<stEmptyItemSet>::iterator it = vEmptyItems.begin();
std::vector<stEmptyItemSet>::iterator it_e = vEmptyItems.end();
std::vector<stEmptyItemSet>::iterator it_1;
std::vector<stEmptyItemSet>::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<stEmptyItemSet>::iterator it = vEmptyItems.begin();
std::vector<stEmptyItemSet>::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<stEmptyItemSet>::iterator it = vEmptyItems.begin();
std::vector<stEmptyItemSet>::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<stEmptyItemSet>::iterator it = vEmptyItems.begin();
std::vector<stEmptyItemSet>::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<stEmptyItemSet>::iterator it = m_ExistEmptyItem.vEmptyItems.begin();
std::vector<stEmptyItemSet>::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<stEmptyItemSet>::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<stEmptyItemSet>::iterator it = m_ExistEmptyItem.vEmptyItems.begin();
std::vector<stEmptyItemSet>::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,"<size:12>");
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 += "<size:5><BR><size:10>";
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, "<size:9>");
}
}
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<std::string>& rStdList, std::string tag )
{
std::string temp;
int size( rStdList.size() );
if( size == 0 ) return temp;
for(int i(0); i<size; ++i)
{
if(i) temp += +tag.c_str();
temp += rStdList[i];
}
return temp;
}
std::string SUIDisplayInfo::Get_A_BitSetText( unsigned int strID, double BisetID, double dValue, bool bAmplify )
{
std::vector<std::string> 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<std::string> 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<std::string> 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<int>& rWeaponList ) const
{
// Fraun performance tweak
std::string str;
int size( rWeaponList.size() );
if( size == 0 ) return str;
std::vector<std::string> strWeaponList;
for( int i(0); i<size; ++i )
{
switch (rWeaponList[i])
{
case ItemBase::CLASS_ONEHAND_SWORD: strWeaponList.push_back( S(7173) ); break;
case ItemBase::CLASS_TWOHAND_SWORD: strWeaponList.push_back( S(7174) ); break;
case ItemBase::CLASS_DAGGER: strWeaponList.push_back( S(7175) ); break;
case ItemBase::CLASS_TWOHAND_SPEAR: strWeaponList.push_back( S(7176) ); break;
case ItemBase::CLASS_TWOHAND_AXE: strWeaponList.push_back( S(7177) ); break;
case ItemBase::CLASS_ONEHAND_MACE: strWeaponList.push_back( S(7178) ); break;
case ItemBase::CLASS_TWOHAND_MACE: strWeaponList.push_back( S(7179) ); break;
case ItemBase::CLASS_LIGHT_BOW: strWeaponList.push_back( S(7180) ); break;
case ItemBase::CLASS_HEAVY_BOW: strWeaponList.push_back( S(7181) ); break;
case ItemBase::CLASS_CROSSBOW: strWeaponList.push_back( S(7182) ); break;
case ItemBase::CLASS_ONEHAND_STAFF: strWeaponList.push_back( S(7183) ); break;
case ItemBase::CLASS_TWOHAND_STAFF: strWeaponList.push_back( S(7184) ); break;
case ItemBase::CLASS_DOUBLE_SWORD: strWeaponList.push_back( S(7185) ); break;
case ItemBase::CLASS_DOUBLE_DAGGER: strWeaponList.push_back( S(7186) ); break;
case ItemBase::CLASS_EVERY_WEAPON: strWeaponList.push_back( S(7187) ); break;
case ItemBase::CLASS_ONEHAND_AXE: strWeaponList.push_back( S(7248) ); break;
case ItemBase::CLASS_DOUBLE_AXE: strWeaponList.push_back( S(7249) ); break;
}
/*
if( rWeaponList[i] == ItemBase::CLASS_ONEHAND_SWORD ) strWeaponList.push_back( S(7173) );
else if( rWeaponList[i] == ItemBase::CLASS_TWOHAND_SWORD ) strWeaponList.push_back( S(7174) );
else if( rWeaponList[i] == ItemBase::CLASS_DAGGER ) strWeaponList.push_back( S(7175) );
else if( rWeaponList[i] == ItemBase::CLASS_TWOHAND_SPEAR ) strWeaponList.push_back( S(7176) );
else if( rWeaponList[i] == ItemBase::CLASS_TWOHAND_AXE ) strWeaponList.push_back( S(7177) );
else if( rWeaponList[i] == ItemBase::CLASS_ONEHAND_MACE ) strWeaponList.push_back( S(7178) );
else if( rWeaponList[i] == ItemBase::CLASS_TWOHAND_MACE ) strWeaponList.push_back( S(7179) );
else if( rWeaponList[i] == ItemBase::CLASS_LIGHT_BOW ) strWeaponList.push_back( S(7180) );
else if( rWeaponList[i] == ItemBase::CLASS_HEAVY_BOW ) strWeaponList.push_back( S(7181) );
else if( rWeaponList[i] == ItemBase::CLASS_CROSSBOW ) strWeaponList.push_back( S(7182) );
else if( rWeaponList[i] == ItemBase::CLASS_ONEHAND_STAFF ) strWeaponList.push_back( S(7183) );
else if( rWeaponList[i] == ItemBase::CLASS_TWOHAND_STAFF ) strWeaponList.push_back( S(7184) );
else if( rWeaponList[i] == ItemBase::CLASS_DOUBLE_SWORD ) strWeaponList.push_back( S(7185) );
else if( rWeaponList[i] == ItemBase::CLASS_DOUBLE_DAGGER ) strWeaponList.push_back( S(7186) );
else if( rWeaponList[i] == ItemBase::CLASS_EVERY_WEAPON ) strWeaponList.push_back( S(7187) );
else if( rWeaponList[i] == ItemBase::CLASS_ONEHAND_AXE ) strWeaponList.push_back( S(7248) );
else if( rWeaponList[i] == ItemBase::CLASS_DOUBLE_AXE ) strWeaponList.push_back( S(7249) );
*/
}
if( !strWeaponList.empty() )
str = BuildEnumString(strWeaponList, " / ");
strWeaponList.clear();
return str;
}
std::string SUIDisplayInfo::BasicStateFxTooltip_PhysicalDamage( StateInfoEx* pState, int nStateLevel, const CreatureAttribute& userAttr, const CreatureAttribute& itemAttr ) // sonador 10.4.2 지속효과 기본공격 반영률 관련 오류 수정
{
// { 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.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 += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
// bitset 12-15번도 사용하게 변경, 텍스트는 비트셋A , by 정동섭
strTemp = GetFirstStateBitSetText( pState, 7153, 12, nStateLevel, false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = GetFirstStateBitSetText( pState, 7153, 15, nStateLevel, false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = GetSecondStateBitSetText( pState, 7153, 6, nStateLevel, false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = GetSecondStateBitSetText( pState, 7153, 9, nStateLevel, false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
// bitset 12-15번도 사용하게 변경, 텍스트는 비트셋A , by 정동섭
strTemp = GetFirstStateBitSetText( pState, 7153, 12, nStateLevel, true );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = GetFirstStateBitSetText( pState, 7153, 15, nStateLevel, true );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = GetSecondStateBitSetText( pState, 7153, 6, nStateLevel, true );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = GetSecondStateBitSetText( pState, 7153, 9, nStateLevel, true );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = Get_A_BitSetText( 7153, pState->fValue[4], pState->fValue[5], false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = Get_A_BitSetText( 7153, pState->fValue[6], pState->fValue[7], false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = Get_A_BitSetText( 7153, pState->fValue[8], pState->fValue[9], false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = Get_A_BitSetText( 7153, pState->fValue[10], pState->fValue[11], false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
strTemp.clear();
}
strTemp = Get_A_BitSetText( 7153, pState->fValue[12], pState->fValue[13] * 100, true );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += strTemp;
}
strTemp = Get_A_BitSetText( 7153, 51, pState->fValue[19], false );
if( !strTemp.empty() )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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<std::string> 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 += "<br>";
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 += "<br>";
}
//
sprintf(strTemp2, "%d%%", (int)pState->fValue[1]);
temp = S(8030);
if (XStringUtil::Replace(temp, "#@value@#", strTemp2))
{
tooltip += temp;
tooltip += "<br>";
}
//
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 += "<br>";
}
//
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 += "<br>";
}
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 += ", <br>";
}
/// 생명력 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 += ", <br>";
}
/// 공격대상과 레벨 차이 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 += ", <br>";
}
/// 공격대상과 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 += ", <br>";
}
/// 공격대상을 쓰러뜨렸을 때, (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 += "<br>";
}
/// 소모 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 += "<br>";
}
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 += "<br>";
/// 적용 공격자 계열1
temp = S(8060);
XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[17]));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
/// 적용 공격자 계열2
temp = S(8060);
XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[18]));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
/// 적용 공격자 계열3
temp = S(8060);
XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[19]));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
/// 데미지 감소
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 += "<br>";
return tooltip;
}
std::string SUIDisplayInfo::getStateToolTipAttackedDecDamage(StateInfoEx* pState, int nStateLevel) const
{
if (!pState)
return "";
std::string tooltip, temp;
///
tooltip = ReduceDamageAllType(pState, nStateLevel);
tooltip += "<br>";
/// 적용 공격자 계열1
temp = S(8060);
XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[17]));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
/// 적용 공격자 계열2
temp = S(8060);
XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[18]));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
/// 적용 공격자 계열3
temp = S(8060);
XStringUtil::Replace(temp, "#@value@#", StringDBHelper::getDescentName(pState->fValue[19]));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
/// 데미지 감소
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 += "<br>";
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 += "<br>";
}
/// 원거리 공격 여부
if (0 < (int)pState->fValue[11])
{
temp = S(8082);
XStringUtil::Replace(temp, "#@value@#", S(8079));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
}
/// 물리 스킬 여부
if (0 < (int)pState->fValue[12])
{
temp = S(8082);
XStringUtil::Replace(temp, "#@value@#", S(8080));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
}
/// 마법 스킬 여부
if (0 < (int)pState->fValue[13])
{
temp = S(8082);
XStringUtil::Replace(temp, "#@value@#", S(8081));
tooltip += temp;
tooltip += ",";
tooltip += "<br>";
}
/// 공격력 반영 타입
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 += "<br>";
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 += "<br>";
/// 물리 공격 데미지 증폭
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 += "<br>";
}
/// 물리 스킬 데미지 증폭
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 += "<br>";
}
/// 마법 공격 데미지 증폭
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 += "<br>";
}
tooltip += "<br>";
///
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 += "<br>";
}
///
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 += "<br>";
}
/// 어그로
if (1 == (int)pState->fValue[19])
{
tooltip += S(8089);
tooltip += "<br>";
}
else if (2 == (int)pState->fValue[19])
{
tooltip += S(8090);
tooltip += "<br>";
}
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 += "<br>";
}
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 += "<br>";
}
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 += "<br>";
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 += "<br>";
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 += "<br>";
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 += "<br>";
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 += "<br>";
return tooltip;
}
std::string SUIDisplayInfo::getStateToolTipNotConsumptionEnergy(StateInfoEx* pState, int nStateLevel) const
{
if (!pState)
return "";
std::string tooltip;
tooltip = S(8072);
tooltip += "<br>";
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 += "<br>";
/// 소모된 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 += "<br>";
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 = "<size:10><#ffffcc>";
}
if (0 < hp)
{
strP = CStringUtil::StringFormat("%d", hp);
temp = SR(8110, "#@db_text@#", S(40), "#@value@#", strP.c_str());
temp += "<br>";
tooltip += temp;
}
/// mp
if (0 < mp)
{
strP = CStringUtil::StringFormat("%d", mp);
temp = SR(8110, "#@db_text@#", S(42), "#@value@#", strP.c_str());
temp += "<br>";
tooltip += temp;
}
if (0 < hp || 0 < mp)
{
tooltip += "<size:4><BR><size:10><#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 += "<br>";
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 += "<br>";
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<int> 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 += "<BR>";
tooltip += SR(7162, "#@point_name@#", S(7006), "#@value@#", CheckPositiveText(rcvMP, false).c_str(), "#@probability@#", probability );
}
if( rcvSP )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
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 += "<BR>";
// 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 += "<BR>";
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 += "<BR>";
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 += "<BR>";
tooltip += SR( 1577, "#@value@#", range );
}
if( reduceSkl )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR( 1626, "#@damage_type@#", S( 1611 ), "#@value@#", (int)reduceSkl );
}
if( reflectPhy )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR( 1626, "#@damage_type@#", S( 1610 ), "#@value@#", (int)reflectPhy );
}
if( reflectMag )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
tooltip += SR( stringid, "#@damage_type@#", S( 1611 ), "#@value@#", abs((int)reduceSkl), "#@probability@#", probability );
}
if( reduceMag )
{
stringid = (reduceMag < 0) ? 1699 : 1609;
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
tooltip += SR(7167, "#@point_name@#", S(7006), "#@value@#", CheckPositiveText(rcvMP, false).c_str());
}
if( rcvSP )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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<std::string> 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<std::string> 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 += "<BR>";
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 += "<BR>";
tooltip += SR( 1628, "#@value@#", this->GetTimeString( frequency ).c_str() );
}
if( duration )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR( 1565, "#@value@#", duration );
}
if( radius )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR( 1552, "#@value@#", radius );
}
// sonador 10.4.2 지속효과 기본공격 반영률 관련 오류 수정
//if( !tooltip.empty() ) tooltip += "<BR>";
//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 += "<BR>";
tooltip += SR(7153,"#@bitset_text@#", S(7117), "#@value@#", CheckPositiveText(Cri, true).c_str());
}
if( Cooltime )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR(7153,"#@bitset_text@#", S(77), "#@value@#", CheckPositiveText(Cooltime, true).c_str());
}
if( AggPoint )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
tooltip += SR(7153,"#@bitset_text@#", S(7109), "#@value@#", CheckPositiveText(MagicPoint, false).c_str());
}
if( Cri )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR(7153,"#@bitset_text@#", S(7117), "#@value@#", CheckPositiveText(Cri, false).c_str());
}
if( Cooltime )
{
if( !tooltip.empty() ) tooltip += "<BR>";
tooltip += SR(7153,"#@bitset_text@#", S(77), "#@value@#", CheckPositiveText(Cooltime, true).c_str());
}
if( AggPoint )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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 += "<BR>";
tooltip += SR( 1575, "#@value@#", recMp );
}
if( recExp )
{
if( !tooltip.empty() ) tooltip += "<BR>";
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<br>%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<SUIQuickSlotItemInfo*>( 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<SMSG_CONSOLE_BUILDER*>(pGameMsg);
std::vector<std::string> 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<SInventorySlot*> vecInvenList;
/// 2010.11.24 - prodongi
m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList, m_CreatureSlotMgr );
//m_InventoryMgr.GetInvenDataList( UI_ITEM_ALL, vecInvenList );
std::vector<SInventorySlot*>::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 += "<BR>";
// 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 += "<BR>";
}
}
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("<BR>") == std::string::npos)
strTemp2 += "<BR>";
strTemp2 += strEffectOption;
//strTemp2 += "<BR>";
}
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( "<br><#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 = "<br><#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( "<br>" );
}
else
{
strOption.append( "<br>" );
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); // <br><#a9cce3>Additional stats:<br>
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 += "<BR>";
}
}
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("<BR>") == std::string::npos)
{
strTemp2 += "<BR>";
}
strTemp2 += strEffectOption;
}
strTemp1 += strTemp2;
}
strAdditionalItemEffect += strTemp1;
strAdditionalItemEffect += "<br>";
}
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( "<br><#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( "<br>" );
}
else
{
strRandomOptionDetail = GetItemRandomOptionString( nType, dbValue, dbData );
if( strRandomOptionDetail.empty() == true )
continue;
strRandomOptionTooltip.append( "<br>" );
}
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 = ("<B><#FF9B0C>[skin] @name_creature@ Evo @evolution@ @stage@</B><#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 += "<B><#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 += "</B><#D600EA>";
//std::string Evo = CStringUtil::StringFormat("%d", g_pCurrentGameSystem->GetSkillSlotMgr().GetCurrentSkillLevel(s_need_data->GetID()) );
//CStringUtil::ReplacePhrase(tip, "%pop", Evo);
}
else
{
tip += "<B><#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 += "</B><#B92C36>";
//std::string Evo = CStringUtil::StringFormat("%d", g_pCurrentGameSystem->GetSkillSlotMgr().GetCurrentSkillLevel(s_need_data->GetID()));
//CStringUtil::ReplacePhrase(tip, "%pop", Evo);
}
CStringUtil::ReplacePhrase(tip, "<size:9>", "");
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 += "<BR>";
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())
{
// ù <BR>
if( add_tag == true )
{
strTemp2 += "<BR>";
}
strTemp2 += strEffectOption;
}
strTemp1 += strTemp2;
}
if( add_tag == true )
{
strEffect_tooltip = CStringUtil::StringFormat( "<#D600EA>%s<br><#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;
}