Files
2026-06-01 12:46:52 +02:00

4721 lines
162 KiB
C++

#include "stdafx.h"
#include "SUIDisplayInfo.h"
#include "SGame.h"
#include "SGameMessage.h"
//#include "SGameMessageUI.h"
#include "SUISysMsgDefine.h"
#include "ErrorCode/ErrorCode.h"
#include "SStringDB.h"
#include "SItemDB.h"
#include "SSkillDB.h"
#include "SJobDB.h"
#include "SMonsterDB.h"
#include "SCreatureDB.h"
#include "SMessengerMgr.h"
#include "SPlayerInfoMgr.h"
#include "SSummonSlotMgr.h"
#include "SInventoryMgr.h"
#include "SSkillSlot.h"
#include "SkillBaseFile.h"
#include "STenacityDB.h"
#include <toolkit/XStringUtil.h>
#include "SGameManager.h"
#include "TemplateUtil.h" // sonador 1.10.3 전투 메시지 출력 처리 구조 개선
#include "SkillEx.h" // #2.1.2.12
#include "SLog.h"
// 2010.06.15 - prodongi
#include "GameDefine.h"
#include "SGameSystem.h"
extern SGameSystem* g_pCurrentGameSystem;
namespace
{
enum EFFECT_TYPE
{
ATTACK_POWER = 101,
ATTACK_POWER_ONE = 102,
ATTACK_INCREASE = 103,
ATTACK_INCREASE_ONE = 104,
ATTACK_POWER_DIRECTION = 105,
ATTACK_POWER_STAT = 106,
ATTACK_MULTIPLE_DAMAGE_T3 = 107, //-N4-
ATTACK_MULTIPLE_DAMAGE_TRIPLE_ATTACK = 108,
ATTACK_RANGE = 111, //-N4-
ATTACK_MULTIPLE_RANGE = 112, //-N4-
ATTACK_SPACIAL_RANGE = 113, //-N4-
ATTACK_ABSORPTION_HPMP = 121,
ATTACK_SINGLE_DAMAGE_KNOCK_BACK = 131, //-N4
ATTACK_SINGLE_REGION_DAMAGE_KNOCK_BACK = 132,
ATTACK_MULTIPLE_DAMAGE_KNOCK_BACK = 133,
ATTACK_MULTIPLE_REGION_DAMAGE_KNOCK_BACK = 134,
ATTACK_SINGLE_DAMAGE_WITHOUT_WEAPON_RUSH_KNOCK_BACK = 151,
ATTACK_SINGLE_DAMAGE_RUSH_KNOCK_BACK = 152,
MAGIC_POWER = 201,
MAGIC_POWER_ONE = 202,
// MAGIC_SINGLE_DAMAGE_T2 = 203,
// MAGIC_MULTIPLE_DAMAGE_T2 = 204,
MAGIC_POWER_AREA = 205,
MAGIC_MULTIPLE_DAMAGE_T1_DEAL_SUMMON_HP = 206,
MAGIC_MULTIPLE_RANGE_DAMAGE = 211,
MAGIC_MULTIPLE_REGION_DAMAGE = 212,
MAGIC_SPECIAL_REGION_DAMAGE = 213,
MAGIC_MULTIPLE_REGION_DAMAGE_T2 = 214,
MAGIC_ABSORPTION_HPMP = 221,
EF_ADD_STATE = 301, //-N4-
STATE_SUCCESS_BYATTACK = 311,
STATE_SUCCESS_BYATTACK_ONE = 312,
STATE_SUCCESS_BYMAGIC = 321,
AREA_EFFECT_MAGIC_DAMAGE = 352,
// AREA_EFFECT_HEAL = 353,
DEBUFF_STATE_LEVEL = 401,
BUFF_STATE_LEVEL = 402,
RECOVERY_HP = 501,
RECOVERY_MP = 502,
RECOVERY_SP = 503,
EXP_INCREASE_BYREVIVAL = 504,
EF_ADD_HP_MP = 505, //-N4-
// ADD_HP_MP_BY_SUMMON_DAMAGE = 506,
// ADD_HP_MP_BY_SUMMON_DEAD = 507,
BODY_ABSORPTION_HPMP_POINT = 511, //-N4-
ADD_HP_MP_BY_STEAL_SUMMON_HP_MP = 512,
EF_SUMMON = 601, //-N4-
EF_UNSUMMON = 602, //-N4-
TAMING_SUCCESS = 603,
MP_COST_PERSECOND = 701,
AGRGRO = 900, //-N4-
};
const int c_nSummonSkillID = 4001;
const int c_nUnSummonSkillID = 4002;
// 2010.06.15 GameDefine.h로 옮김 - prodongi
//#define FORCE_CHIP_SKILL_ID 6008
};
//////////////////////////////////////////////////////////////////////////
// 시스템 메시지 처리
//////////////////////////////////////////////////////////////////////////
void SUIDisplayInfo::SetSkillSysMsg( int nMsgType, int nSkillID, int nLv )
{
// Fraun performance tweak
SkillBaseEx* s_data = GetSkillDB().GetSkillData( nSkillID );
if( s_data == NULL )
{
AddSystemMessage(CStringUtil::StringFormat( "[Error] Skill id: %d; NO skill data!", nSkillID ).c_str(), 255);
_oprint("[Error] Skill id: %d; NO skill data!\n", nSkillID);
return;
}
switch( nMsgType )
{
case SYS_MSG_LEARN_SKILL:
case SYS_MSG_SKILL_UP:
{
int nLevel = m_SkillSlotMgr.GetUseSkillLevel( nSkillID ) ;
if( nLevel == 1 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_SKILL_LEARN), "#@skill_name@#", GetStringMessage( s_data->GetNameID() ) ).c_str(), 6);
}
else if( nLevel > 1 && nLevel != 0 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_SKILL_UP), "#@skill_name@#", GetStringMessage( s_data->GetNameID() ), "#@skill_level@#", SStringDB::ToString( nLevel ).c_str() ).c_str(), 6);
}
}
break;
}
}
//파티 관련
void SUIDisplayInfo::SetPartySysMsg( int nMsgType, const char* pName, const char* pItemName, const char* pItemCnt )
{
// Fraun performance tweak
switch( nMsgType )
{
case SYS_MSG_PARTY_SETUP: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", pName, "#@user_name@#", pItemName ).c_str(), 99); break;
case SYS_MSG_PARTY_CANT_SETUP: AddSystemMessage(S(SYS_MSG_PARTY_CANT_SETUP), 99); break;
case SYS_MSG_PARTY_INVITE_CHECK: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", m_PartyMgr.GetPartyName(), "#@user_name@#", m_PartyMgr.GetPartyLeaderName() ).c_str(), 99); break;
case SYS_MSG_PARTY_JOIN_MEMBER: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", m_PartyMgr.GetPartyName() ).c_str(), 99); break;
case SYS_MSG_PARTY_BAN: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", m_PartyMgr.GetPartyName() ).c_str(), 99); break;
case SYS_MSG_PARTY_BREAK_CHECK: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", m_PartyMgr.GetPartyName() ).c_str(), 99); break;
case SYS_MSG_PARTY_BREAK: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", m_PartyMgr.GetPartyName() ).c_str(), 99); break;
case SYS_MSG_PARTY_LEAVE: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@party_name@#", m_PartyMgr.getOldPartyName() ).c_str(), 99); break;
case SYS_MSG_PARTY_TRANSFERING: AddSystemMessage(S(SYS_MSG_PARTY_TRANSFERING), 99); break;
case SYS_MSG_PARTY_REJECT_TRANSFER: AddSystemMessage(S(SYS_MSG_PARTY_REJECT_TRANSFER), 99); break;
case SYS_MSG_PARTY_ALREADY_OTHER_MEMBER: AddSystemMessage(S(SYS_MSG_PARTY_ALREADY_OTHER_MEMBER), 99); break;
case SYS_MSG_PARTY_TRANSFER_NOT_ALLOW: AddSystemMessage(S(SYS_MSG_PARTY_TRANSFER_NOT_ALLOW), 99); break;
case SYS_MSG_PARTY_NOTICE_ITEM_RULE_PRIVATE: AddSystemMessage(S(SYS_MSG_PARTY_NOTICE_ITEM_RULE_PRIVATE), 99);break;
case SYS_MSG_PARTY_NOTICE_ITEM_RULE_RANDOM: AddSystemMessage(S(SYS_MSG_PARTY_NOTICE_ITEM_RULE_RANDOM), 99); break;
case SYS_MSG_PARTY_NOTICE_ITEM_RULE_LINEAR: AddSystemMessage(S(SYS_MSG_PARTY_NOTICE_ITEM_RULE_LINEAR), 99); break;
case SYS_MSG_DONUSE_PARTY_COMMAND: AddSystemMessage(S(SYS_MSG_DONUSE_PARTY_COMMAND), 99); break;
case SYS_MSG_CREATURE_TAME_SUCCESS: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@creature_name@#", S( atoi( pName ) ) ).c_str(), 99); break;
case SYS_MSG_CREATURE_TAME_SUCCESS_BONUS: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@creature_name@#", S( atoi( pName ) ) ).c_str(), 99); break;
case SYS_MSG_CREATURE_TAME_DISAPPEAR: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@creature_name@#", S( atoi( pName ) ) ).c_str(), 99); break;
//파티원 "#@user_name@#"님이 #@item_name@# 아이템을 획득했습니
case SYS_MSG_PARTY_NOTICE_GET_ITEM:
{
std::string strName, strItemName;
if( pName ) strName = pName;
else strName = S(88);//"무엇인가 ";
if( pItemName ) strItemName = pItemName;
else strItemName = S(88);//"무엇인가";
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_PARTY_NOTICE_GET_ITEM), "#@user_name@#", strName.c_str(), "#@item_name@#", strItemName.c_str() ).c_str(), 5);
}
break;
//파티원 "#@user_name@#"님이 #@item_name@# #@item_num@#개를 획
case SYS_MSG_PARTY_NOTICE_GET_ITEM_NUMBER:
{
std::string strName, strItemName;
if( pName ) strName = pName;
else strName = S(88);//"무엇인가 ";
if( pItemName ) strItemName = pItemName;
else strItemName = S(88);//"무엇인가";
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_PARTY_NOTICE_GET_ITEM_NUMBER),
"#@user_name@#", strName.c_str(),
"#@item_name@#", strItemName.c_str(),
"#@item_num@#" , pItemCnt ).c_str(), 5);
}
break;
case SYS_MSG_PARTY_INVITING:
case SYS_MSG_PARTY_JOIN_MEMBER_NOTICE:
case SYS_MSG_PARTY_REJECT_JOIN:
case SYS_MSG_PARTY_BAN_CHECK:
case SYS_MSG_PARTY_BAN_NOTICE:
case SYS_MSG_PARTY_LEAVE_NOTICE:
case SYS_MSG_PARTY_TRANSFER:
case SYS_MSG_PARTY_TRANSFERING_NOTICE:
case SYS_MSG_PARTY_NEW_READER:
case SYS_MSG_PARTY_REJECT_TRANSFER_NOTICE:
{ // 99
if (pName)
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@user_name@#", pName).c_str(), 2);
else
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@user_name@#", "Something").c_str(), 2);
break;
}
case SYS_MSG_PARTY_NOTICE_MEMBER_LOGIN: // 2
case SYS_MSG_PARTY_NOTICE_MEMBER_LOGOUT:
{
if( pName )
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@user_name@#", pName ).c_str(), 2);
else
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@user_name@#", "Something" ).c_str(), 2);
break;
}
}
}
void SUIDisplayInfo::SetSysMsg( int nMsgType, const char* lpText )
{
// Fraun performance tweak
switch( nMsgType )
{
case SYS_MSG_CREATURE_NAME_CHANGE: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@creature_name@#", lpText ).c_str(), 0); break;
}
}
void SUIDisplayInfo::SetSysMsg( int nMsgType, __int64 nValue, __int64 nValue2 )
{
// Fraun performance tweak
switch( nMsgType )
{
case SYS_MSG_WRONGSTR: AddSystemMessage(SStringDB::ParseString( S(SYS_MSG_WRONGSTR) ).c_str(), 99); break;
case SYS_MSG_PARTY_WRONGSTR: AddSystemMessage(SStringDB::ParseString( S(SYS_MSG_PARTY_WRONGSTR) ).c_str(), 99); break;
case SYS_MSG_NAME_DUPLICATE: AddSystemMessage(SStringDB::ParseString( S(431) ).c_str(), 99); break;
case SYS_MSG_BUILDUP_ITEM_FAIL: AddSystemMessage(SStringDB::ParseString( S(SYS_MSG_BUILDUP_ITEM_FAIL) ).c_str(), 99); break;
case SYS_MSG_GET_EXP_JP:
{
if( m_nDiffExp > 0 && m_nDiffJP == 0 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_GET_EXP), "#@exp@#", expToString( m_nDiffExp ).c_str()).c_str(), 1);
}
else if( m_nDiffExp == 0 && m_nDiffJP > 0 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_GET_JP), "#@jp@#", SStringDB::ToString( m_nDiffJP ).c_str() ).c_str(), 1);
}
else if( m_nDiffExp > 0 && m_nDiffJP > 0 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_GET_EXP_JP), "#@exp@#", expToString( m_nDiffExp ).c_str(), "#@jp@#", SStringDB::ToString( m_nDiffJP ).c_str() ).c_str(), 1);
}
else if( m_nDiffExp < 0 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_LOST_EXP), "#@exp@#", expToString( m_nDiffExp*(-1) ).c_str() ).c_str(), 1);
}
else if( m_nDiffJP < 0 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_LOST_JP), "#@jp@#", SStringDB::ToString( m_nDiffJP*(-1) ).c_str() ).c_str(), 1);
}
break;
}
case SYS_MSG_LV_UP:
{
int nlevel = m_PlayerInfoMgr.GetLevel();
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@level@#", SStringDB::ToString( nlevel ).c_str() ).c_str(), 99);
break;
}
case SYS_MSG_JLV_UP:
{
int nlevel = m_PlayerInfoMgr.GetJLv();
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@jlv@#", SStringDB::ToString( nlevel ).c_str() ).c_str(), 99);
break;
}
case SYS_MSG_MORAL_POINT_INCREASE: // sonador 1.10.1 Added messages for moral point increase/decrease and for the sparring arena
case SYS_MSG_MORAL_POINT_DECREASE:
{
AddSystemMessage(S( nMsgType ), 99);
break;
}
case SYS_MSG_RECOVER_HP: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@hp@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 6); break;
case SYS_MSG_RECOVER_MP: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@mp@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 6); break;
case SYS_MSG_RECOVER_SP: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@sp@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 6); break;
case SYS_MSG_ALLCHAT_DECREASE: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@HP&MP%@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 99); break;
case SYS_MSG_LOCALCHAT_DECREASE:AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@HP&MP%@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 99); break;
case SYS_MSG_LV_DOWN: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@level@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 99); break;
case SYS_MSG_JOB_CHANGE: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@job_name@#", GetJobDB().GetJobName(nValue) ).c_str(), 99); break;
case SYS_MSG_EVERYCHAT: AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@level@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 99); break;
//Display messages for acquiring and using Holic Points
case SYS_MSG_GET_HOLICPOINT:
case SYS_MSG_USE_HOLICPOINT:
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@p@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 99); break;
break;
}
case SYS_MSG_PKMODE_IMPOSSIBLE:
case SYS_MSG_JLV_UP_STATUS:
case SYS_MSG_BUILDUP_COMPLETE:
case SYS_MSG_ITEM_NOT_PICKUP:
case SYS_MSG_WEIGHT_TOO_HEAVY:
{
AddSystemMessage( S(nMsgType), 99 );
break;
}
case SYS_MSG_OTHER_ACTION_WAIT:
{
AddSystemMessage( S(nMsgType), 6 );
break;
}
case SYS_MSG_BONUS03:
case SYS_MSG_BONUS_DOUBLE02:
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage( nMsgType ), "#@bonus@#", SStringDB::ToString( nValue ).c_str(), "#@lak@#", SStringDB::ToString( nValue2 ).c_str() ).c_str(), 99);
break;
}
case SYS_MSG_PKMODE_ON://#@second@#초 후 PK MODE가 활성화 됩니다. PK 아이콘을 클릭하여 취소가 가능합니다.
case SYS_MSG_PKMODE_OFF://#@second@#초 후 PK MODE가 해제 됩니다.
case SMSG_ITEM_TIME_DISAPPEAR:
case SMSG_STORAGE_ITEM_TIME_DISAPPEAR:
{
// 메시지 출력시 해당 아이템의 Handle 값 말고 바로 서버에서 Code 값 주게 수정 (창고아이템은 따로 UpdateInfo를 보관하지 않아 Handle을 줘도 못 찾는것 같다..)
const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( nValue );
if( pItemBase )
{
std::string strItemName( GetStringDB().GetString( pItemBase->nNameId ) );
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@item_name@#", strItemName.c_str() ).c_str(), 99);
}
break;
}
case SYS_MSG_ACTION_FAIL:
case SYS_MSG_DUMP_FAIL:
case SYS_MSG_SAVER_ALREADY:
{
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType)).c_str(), 99);
break;
}
case SYS_MSG_USE_ITEM:
case SYS_MSG_PUT_ON_ITEM:
case SYS_MSG_PUT_OFF_ITEM:
{
SInventorySlot* pSlot = m_InventoryMgr.GetUpdateItemInfo(nValue);
if (pSlot != NULL)
{
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@item_name@#", GetItemName(pSlot->GetItemCode(), true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag()).c_str()).c_str(), 6);
}
break;
}
case SYS_MSG_BUY_ITEM:
case SYS_MSG_SELL_ITEM:
case SYS_MSG_DUMP_ITEM_CONFIRM:
case SYS_MSG_BUY_ITEM_FAIL001:
case SYS_MSG_SELL_ITEM_FAIL:
{
SInventorySlot* pSlot = m_InventoryMgr.GetUpdateItemInfo( nValue );
if( pSlot != NULL )
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@item_name@#", GetItemName(pSlot->GetItemCode(), true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag()).c_str() ).c_str(), 99);
break;
}
case SYS_MSG_GET_RUPI: // 5
{
money_t nDiffGold = m_PlayerInfoMgr.GetPlayerInfo().GetGold() - m_nOldGold;
if (nDiffGold > 0)
{
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@gold@#", SStringDB::ToString(nDiffGold.getAmount()).c_str()).c_str(), 5);
}
m_nOldGold = m_PlayerInfoMgr.GetPlayerInfo().GetGold();
break;
}
case SYS_MSG_PAY_RUPI:
case SYS_MSG_RECEIVE_RUPI:
case SYS_MSG_SAVING_RUPI:
case SYS_MSG_WITHDRAW_RUPI:
case SYS_MSG_TOTALSALE_RUPI:
{
money_t nDiffGold = m_PlayerInfoMgr.GetPlayerInfo().GetGold() - m_nOldGold;
if( nDiffGold > 0 )
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@gold@#", SStringDB::ToString( nDiffGold.getAmount() ).c_str() ).c_str(), 99);
m_nOldGold = m_PlayerInfoMgr.GetPlayerInfo().GetGold();
break;
}
case SYS_MSG_GET_ITEM:
{
SInventorySlot* pSlot = m_InventoryMgr.GetUpdateItemInfo( (AR_HANDLE)nValue );
if( pSlot )
{
int nRank = GetItemDB().GetItemRank( pSlot->GetItemCode() );
std::string strItemColor = GetItemColor( nRank );
int nCode( pSlot->GetItemCode() );
std::string strItemName, strItemCnt;
XStringUtil::Format( strItemName, "%s%s<#fdddb0>", strItemColor.c_str(), GetItemName( nCode, true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag() ).c_str() );
XStringUtil::Format( strItemCnt, "%s%s<#fdddb0>", strItemColor.c_str(), SStringDB::ToString( pSlot->GetUpdateCount().getAmount() ).c_str() );
if( GetItemDB().IsJoin(nCode, IsInstanceUnstackable(pSlot) ) ) // 수량성
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_GET_ITEM_NUM), "#@item_name@#", strItemName.c_str(), "#@item_num@#", strItemCnt.c_str() ).c_str(), 5);
}
else
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_GET_ITEM), "#@item_name@#", strItemName.c_str() ).c_str(), 5);
}
}
break;
}
case SYS_MSG_PUT_ITEM_FAIL: // 6
case SYS_MSG_DUMP_ITEM_FAIL: // 6
{
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_PUT_ITEM_TOOFAST: // 0
case SYS_MSG_USE_ITEM_FAIL_NOT_EXSIT: // 0
case SYS_MSG_USE_ITEM_FAIL_NOT_ACTABLE: // 0
case SYS_MSG_USE_ITEM_FAIL_INVALID_ARGUMENT: // 0
{
AddSystemMessage(S(nMsgType), 0);
break;
}
case SYS_MSG_DURATION_LIMIT: // 99
case SYS_MSG_GET_ITEM_FAIL: // 99
case SYS_MSG_OVER_CHARGE: // 99
case SYS_MSG_BUILDUP_ITEM: // 99
case SYS_MSG_BUILDUP_ITEM_NO_SKILL: // 99
case SYS_MSG_BUILDUP_ITEM_FAILED: // 99
case SYS_MSG_TRANSACTION_COMPLETE: // 99
case SYS_MSG_TRADE_NOT_TRADETARGET: // 99
case SYS_MSG_CHA_BATTLE: // 99
case SYS_MSG_SELL_ITEM_NOT_AVAILABLE: // 99
case SYS_MSG_BUY_ITEM_FAIL002: // 99
case SYS_MSG_TOO_HEAVY: // 99
case SYS_MSG_ITEM_DELAYTIME: // 99
case SYS_MSG_USE_ITEM_FAIL: // 99
case SYS_MSG_USE_ITEM_WEIGHT: // 99
case SYS_MSG_USE_ITEM_FAIL_LEVELMAX: // 99
case SYS_MSG_USE_ITEM_FAIL_LEVELMIN: // 99
case SYS_MSG_USE_ITEM_FAIL_TARGET_LOCATION_WRONG: // 99
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_BUILDUP_ITEM_EQUIP:
case SYS_MSG_TRADE_CANCEL:
case SYS_MSG_TRADE_COMPLETE_CHECK:
case SYS_MSG_DUMP_EQUIP_ITEM:
{
AddSystemMessage(S(nMsgType), 5);
break;
}
case SYS_MSG_LAK_PEDENT_EQUIP_REPLACE:
case SYS_MSG_BUILDUP_ITEM_NOT_USE:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_GET_LAK:
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@lak@#", SStringDB::ToString( nValue ).c_str() ).c_str(), 5);
break;
}
case SYS_MSG_BUYNUM_ITEM:
case SYS_MSG_SELLNUM_ITEM:
{
const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( nValue );
if( pItemBase )
{
std::string strItemName( GetStringDB().GetString( pItemBase->nNameId ) );
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType), "#@item_name@#", strItemName.c_str(), "#@item_num@#", SStringDB::ToString( nValue2 ).c_str() ).c_str(), 99);
}
break;
}
case SYS_MSG_TRADE_REQUEST: AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_TRADE_REQUEST), "#@user_name@#", m_PlayerInfoMgr.GetTargetName() ).c_str(), 99);
break;
case SYS_MSG_TRADE_REJECT: AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_TRADE_REJECT), "#@user_name@#", m_PlayerInfoMgr.GetTradeTargetName() ).c_str(), 99);
break;
case SYS_MSG_TRADE_REJECTION:
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_TRADE_REJECTION), "#@user_name@#", m_PlayerInfoMgr.GetTradeTargetName() ).c_str(), 99);
break;
case SYS_MSG_UPGRADE_ITEM:
{
SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( (AR_HANDLE)nValue );
if( pSlot )
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_UPGRADE_ITEM), "#@item_name@#", GetItemName(pSlot->GetItemCode(), true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag()).c_str(), "#@item_level@#", SStringDB::ToString( pSlot->GetLevel() ).c_str() ).c_str(), 99);
}
break;
case SYS_MSG_DUMP_ITEM:
case SYS_MSG_DUMP_ITEM_NUM:
{
SInventorySlot* pSlot = m_InventoryMgr.GetUpdateItemInfo( (AR_HANDLE)nValue );
if( pSlot )
{
int nRank = GetItemDB().GetItemRank( pSlot->GetItemCode() );
std::string strItemColor = GetItemColor( nRank );
count_t nUpdateCount = pSlot->GetUpdateCount();
if( nUpdateCount < 0 ) nUpdateCount = -nUpdateCount;
std::string strItemName, strItemCnt;
XStringUtil::Format( strItemName, "%s%s<#fdddb0>", strItemColor.c_str(), GetItemName( pSlot->GetItemCode(), true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag() ).c_str() );
XStringUtil::Format( strItemCnt, "%s%s<#fdddb0>", strItemColor.c_str(), SStringDB::ToString( nUpdateCount.getAmount() ).c_str() );
if( nUpdateCount > 1 )
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_DUMP_ITEM_NUM), "#@item_name@#", strItemName.c_str(), "#@item_num@#", strItemCnt.c_str() ).c_str(), 6);
}
else
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage(SYS_MSG_DUMP_ITEM), "#@item_name@#", strItemName.c_str() ).c_str(), 6);
}
}
break;
}
case SYS_MSG_CREATURE_TAME_EMPTY: // 99
case SYS_MSG_CREATURE_FULL_HP: // 99
case SYS_MSG_CREATURE_TAME_FAIL: // 99
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_MAGIC_MISS: // 6
{
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_CREATURE_REMOVE_ERR: // 7
{
AddSystemMessage(S(nMsgType), 7);
break;
}
case SYS_MSG_CREATURE_SECOND_SUMMON: // 7
case SYS_MSG_CREATURE_AUTO_RECALL: // 7
case SYS_MSG_CREATURE_MOUNT: // 7
case SYS_MSG_CREATURE_DISMOUNT: // 7
case SYS_MSG_CREATURE_CALL: // 7
{
AddSystemMessage(SStringDB::ParseString( GetStringMessage( nMsgType ), "#@creature_name@#", GetStringDB().GetString( GetCreatureDB().GetTextID( nValue ) ) ).c_str(), 7);
break;
}
case SYS_MSG_CREATURE_AUTO_RECALL_TIME: // Possibly wrong output location
case SYS_MSG_CREATURE_CONTROL_ATTACK: // Possibly wrong output location
case SYS_MSG_CREATURE_CONTROL_RETREAT: // Possibly wrong output location
case SYS_MSG_CREATURE_CONTROL_FOLLOW: // Possibly wrong output location
case SYS_MSG_CREATURE_CONTROL_WAIT: // Possibly wrong output location
case SYS_MSG_CREATURE_CONTROL_DISTANCE: // Possibly wrong output location
case SYS_MSG_CREATURE_SKILL_CANCEL: // Possibly wrong output location
case SYS_MSG_CREATURE_SKILL_MANA_LACK: // Possibly wrong output location
{
AddSystemMessage( S(nMsgType), 7);
break;
}
case SYS_MSG_CREATURE_SKILL_MISS:
{
AddSystemMessage( SStringDB::ParseString( GetStringMessage(SYS_MSG_CREATURE_SKILL_MISS), "#@creature_name@#", GetStringDB().GetString(GetCreatureDB().GetTextID(nValue)) ).c_str(), 4);
break;
}
case SYS_MSG_CREATURE_SKILL_FAIL: // Possibly wrong output location
case SYS_MSG_CREATURE_SKILL_BUFF:
case SYS_MSG_CREATURE_USE_BUFF:
case SYS_MSG_CREATURE_SKILL_DISAPPEAR:
case SYS_MSG_CREATURE_AUTOSKILL_SELECTION:
case SYS_MSG_CREATURE_AUTOSKILL_CANCEL:
{
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@creature_name@#", GetStringDB().GetString(GetCreatureDB().GetTextID(nValue))).c_str(), 7);
break;
}
case SYS_MSG_CREATURE_AUTOSKILL_IMPOSSIBLE:
{
AddSystemMessage( S(SYS_MSG_CREATURE_AUTOSKILL_IMPOSSIBLE), 6);
break;
}
case SYS_MSG_CREATURE_TAME_USE: // Possibly wrong output location
{
AddSystemMessage( S(SYS_MSG_CREATURE_TAME_USE), 99);
break;
}
case SYS_MSG_CREATURE_MOUNTFALL:
{
AddSystemMessage(S(SYS_MSG_CREATURE_MOUNTFALL), 7);
break;
}
case SYS_MSG_CREATURE_AUTOMOVE:
{
AddSystemMessage(S(SYS_MSG_CREATURE_AUTOMOVE), 99);
break;
}
case SYS_MSG_ATTACK_IMPASSABLE:
case SYS_MSG_CHA_MOVING:
{
AddSystemMessage( S(nMsgType), 6);
break;
}
case SYS_MSG_LEARN_SKILL: // Possibly wrong output location
case SYS_MSG_RIDING_IMPASSABLE:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_BATTLE_DAMAGE002:
{
// Possibly wrong output location
// Critical hit! #@t@# takes #@d@# damage.
AddSystemMessage(S(SYS_MSG_BATTLE_DAMAGE002), 4);
break;
}
case SYS_MSG_ATTACK_MISS:
{
AddSystemMessage(S(SYS_MSG_ATTACK_MISS), 3);
break;
}
case SYS_MSG_USE_DEBUFF:
{
// Possibly wrong output location
AddSystemMessage(S(SYS_MSG_USE_DEBUFF), 6);
break;
}
case SYS_MSG_SKILL_DAMAGE_CRITICAL:
{
// Possibly wrong output location
AddSystemMessage(S(SYS_MSG_SKILL_DAMAGE_CRITICAL), 4);
break;
}
case SYS_MSG_CREATURE_MOUNT_IMPOSSIBLE:
case SYS_MSG_CREATURE_MOUNT_IMPOSSIBLE_NEAR:
case SYS_MSG_CREATURE_RESURRECTION: // Possibly wrong output location
{
AddSystemMessage(S(nMsgType), 7);
break;
}
case SYS_MSG_ENERGY_LACK:
case SYS_MSG_POINT_TARGET_ITEM:
{
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_IMMORAL_POINT_INCREASE:
case SYS_MSG_IMMORAL_POINT_DECREASE:
{ // 99
AddSystemMessage( SR(nMsgType, "#@num@#", nValue).c_str(), 99);
break;
}
case SYS_MSG_MOVE_IMPOSSIBLE:
case SYS_MSG_NOT_CHAT_COMMAND:
case SYS_MSG_WEIGHT_50_EXCESS_HANDICAP:
case SYS_MSG_WEIGHT_70_EXCESS_HANDICAP:
case SYS_MSG_WEIGHT_90_EXCESS_HANDICAP:
case SYS_MSG_WEIGHT_EXCESS_NOT_ATTACK:
case SYS_MSG_CANT_CONTRIBUTION:
case SYS_MSG_CONTRIBUTE_ITEM_NOT_EXIST:
case SYS_MSG_BUILDUP_ITEM_NOT_EXIST:
{ // 99
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_GUILD_SETUP: // Possibly wrong output location
case SYS_MSG_GUILD_CANT_SETUP:
case SYS_MSG_GUILD_INVITING: // Possibly wrong output location
case SYS_MSG_GUILD_INVITE_CHECK: // Possibly wrong output location
case SYS_MSG_GUILD_JOIN_MEMBER: // Possibly wrong output location
case SYS_MSG_GUILD_JOIN_MEMBER_NOTICE: // Possibly wrong output location
case SYS_MSG_GUILD_REJECT_JOIN: // Possibly wrong output location
case SYS_MSG_GUILD_BAN: // Possibly wrong output location
case SYS_MSG_GUILD_BAN_NOTICE: // Possibly wrong output location
case SYS_MSG_GUILD_BREAK_CHECK: // Possibly wrong output location
case SYS_MSG_GUILD_BREAK: // Possibly wrong output location
case SYS_MSG_GUILD_LEAVE: // Possibly wrong output location
case SYS_MSG_GUILD_LEAVE_NOTICE: // Possibly wrong output location
case SYS_MSG_GUILD_TRANSFER: // Possibly wrong output location
case SYS_MSG_GUILD_TRANSFERING:
case SYS_MSG_GUILD_TRANSFERING_NOTICE: // Possibly wrong output location
case SYS_MSG_GUILD_NEW_LEADER: // Possibly wrong output location
case SYS_MSG_GUILD_REJECT_TRANSFER:
case SYS_MSG_GUILD_REJECT_TRANSFER_NOTICE: // Possibly wrong output location
case SYS_MSG_GUILD_ALREADY_OTHER_MEMBER:
case SYS_MSG_GUILD_TRANSFER_NOT_ALLOW:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_GUILD_NOTICE_MEMBER_LOGIN:
case SYS_MSG_GUILD_NOTICE_MEMBER_LOGOUT:
{ // Possibly wrong output location
AddSystemMessage(S(nMsgType), 2);
break;
}
case SYS_MSG_GUILD_NOTICE_MEMBER_BREAKUP: // Possibly wrong output location
case SYS_MSG_GUILD_NAME_OVERLAP:
case SYS_MSG_GUILD_NAME_IMPOSSIBLE:
case SYS_MSG_GUILD_LEAVE_CHECK:
case SYS_MSG_GUILD_REJOIN_LIMIT:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_BOOTH_CANT_SETUP:
case SYS_MSG_BOOTH_NOT_USE_ITEM:
case SYS_MSG_BOOTH_NOT_USE_STORE:
case SYS_MSG_BOOTH_NOT_USE_SKILL:
case SYS_MSG_BOOTH_NOTICE_PRICE:
case SYS_MSG_BOOTH_NOTICE_AMOUNT:
case SYS_MSG_BOOTH_NOTICE_NOT_ADDITION:
case SYS_MSG_BOOTH_NOTICE_ADVICE_PRICE:
case SYS_MSG_BOOTH_NOTICE_ADVICE_WEIGHT:
case SYS_MSG_BOOTH_NOTICE_SHORTAGE_RP:
{ // 99
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_BOOTH_NOTICE_SELLING:
case SYS_MSG_BOOTH_NOTICE_BUYING:
{ // 99
SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo( nValue );
if (pSlot != NULL)
{
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@item_name@#", GetItemName(pSlot->GetItemCode(), true, pSlot->GetEnhance(), pSlot->GetLevel(), pSlot->GetXFlag()).c_str(),
"#@item_num@#", SStringDB::ToString(pSlot->GetUpdateCount().getAmount()).c_str(),
"#@user_name@#", m_PlayerInfoMgr.GetTargetName()).c_str(), 99);
}
break;
}
case SYS_MSG_BOOTH_NOTICE_INTERRUPTION:
case SYS_MSG_BOOTH_NOTICE_CLOSE:
case SYS_MSG_BOOTH_NOTICE_TRANSACTION:
case SYS_MSG_BOOTH_DISTANCE:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_USE_SKILL_FAIL:
case SYS_MSG_USE_SKILL_YET:
case SYS_MSG_USE_SKILL_CANCEL:
case SYS_MSG_MP_NOT_ENOUGH:
case SYS_MSG_HP_NOT_ENOUGH:
case SYS_MSG_POINT_TARGET:
{
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_SKILL_MISS:
{
AddSystemMessage(S(nMsgType), 4);
break;
}
case SYS_MSG_SKILL_FAIL:
{
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_CHA_SITWARNIG:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_SKILL_IMPASSABLE1:
case SYS_MSG_SKILL_IMPASSABLE2:
case SYS_MSG_USE_SKILL_NOTUSE:
case SYS_MSG_USE_SKILL_NEED_TARGET:
{
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_CREATURE_FORMATION:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_SKILL_NEED_ARROW:
case SYS_MSG_SKILL_DELAYTIME:
{// 6
AddSystemMessage(S(nMsgType), 6);
break;
}
case SYS_MSG_CHATTING_BAN:
case SYS_MSG_CHATTING_BAN_NOW:
{ // 99
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_CREATURE_MOUNT_DUNGEON:
{ // 7
AddSystemMessage( SStringDB::ParseString( GetStringMessage(SYS_MSG_CREATURE_MOUNT_DUNGEON) ).c_str(), 7);
break;
}
case SYS_MSG_AUCTION_TENDER:
case SYS_MSG_AUCTION_ATONCE:
case SYS_MSG_AUCTION_HIGHER:
case SYS_MSG_AUCTION_TENDERPRICE:
case SYS_MSG_AUCTION_START:
case SYS_MSG_AUCTION_CANCEL:
case SYS_MSG_AUCTION_SELLING:
case SYS_MSG_AUCTION_RETENDER:
{ // 99
const ItemBaseEx_info* pItemBase = GetItemDB( ).GetItemData( nValue );
if( pItemBase )
{
std::string strItemName = GetItemColor( pItemBase->nRank );
strItemName += "<B>";
strItemName += GetStringDB( ).GetString( pItemBase->nNameId );
strItemName += "</B><#fdddb0>";
AddSystemMessage(SStringDB::ParseString( nMsgType, "#@itemname@#", strItemName.c_str( ) ).c_str(), 99);
}
break;
}
case SYS_MSG_AUCTION_UNREGISTER: // 경매 등록이 불가능한 아이템입니다.
case SYS_MSG_AUCTION_INVALID_ARGUMENT: // 잘못된 요청입니다.
case SYS_MSG_AUCTION_NOT_ACTABLE_WHILE_TRADING:
case SYS_MSG_AUCTION_NOT_ACTABLE_WHILE_USING_STORAGE:
case SYS_MSG_AUCTION_NOT_ENOUGH_MONEY:
case SYS_MSG_AUCTION_ACCESS_DENIED:
case SYS_MSG_AUCTION_TOO_CHEAP:
case SYS_MSG_AUCTION_TOO_MUCH_MONEY:
case SYS_MSG_AUCTION_NOT_EXIST:
case SYS_MSG_AUCTION_NOT_ACTABLE:
case SYS_MSG_AUCTION_INVALID_STORE_PRICE:
case SYS_MSG_AUCTION_INVALID_REGISTER_PRICE:
case SYS_MSG_AUCTION_ALREADY_EXIST:
case SYS_MSG_AUCTION_NOT_OWN:
case SYS_MSG_AUCTION_NOT_EXIST_TIME_OVER:
case SYS_MSG_AUCTION_TOO_HEAVY:
{ // 99
AddSystemMessage(SStringDB::ParseString( nMsgType ).c_str(), 99);
break;
}
case SYS_MSG_PROTECT01: // 게임가드가 실행 중입니다.
case SYS_MSG_PROTECT02: // 게임이 중복 실행되었거나 게임가드가 이미 실행 중입니다.
case SYS_MSG_PROTECT03: // 게임가드 초기화 에러입니다.<BR>재부팅 후 다시 실행하거나 충돌할 수 있는<BR>다른 프로그램들을 종료한 후 실행하시기 바랍니다.
case SYS_MSG_PROTECT04: // 게임가드 파일이 없거나 변조되었습니다.
case SYS_MSG_PROTECT05: //윈도우의 일부 시스템파일이 손상되었습니다.<BR>인터넷 익스플로러를 다시 설치하시기 바랍니다.
case SYS_MSG_PROTECT06: // 게임가드 실행에 실패했습니다.<BR>게임가드 셋업파일을 다시 설치하시기 바랍니다.
case SYS_MSG_PROTECT07: // 불법프로그램이 발견되었습니다.<BR>불필요한 프로그램을 종료한 후 다시 실행하시기 바랍니다.
case SYS_MSG_PROTECT08: // 게임가드 업데이트를 취소하셨습니다.<BR>접속이 되지 않을 경우 인터넷 및 개인 방화벽<BR>설정을 조정하시기 바랍니다.
case SYS_MSG_PROTECT09: // 바이러스나 스파이웨어로 인해 후킹이 실패하였습니다.<BR>최신 백신으로 컴퓨터 전체 검사를 하시기 바립니다.
case SYS_MSG_PROTECT10: // 구버전의 게임가드 파일이거나 게임가드 초기화 에러입니다.<BR>게임가드 셋업파일을 다시 설치하시고 게임을 실행하시기 바랍니다.
case SYS_MSG_PROTECT11: // ini파일이 없거나 변조되었습니다.
case SYS_MSG_PROTECT12: // npgmup.des 초기화 에러입니다.<BR>게임가드 폴더 내에 데이터를 삭제한 후<BR>게임을 다시 실행하시기 바랍니다.
case SYS_MSG_PROTECT13: // 검증되지 않은 WindowXP x64 버전을 실행한 경우입니다.<BR>게임가드를 최신버전으로 설치한 후 게임을 실행하시기 바랍니다.
case SYS_MSG_PROTECT14: // 게임가드 업데이트 서버 접속에 실패하였습니다.<BR>게임가드를 최신버전으로 설치한 후 게임을 실행하시기 바랍니다.
case SYS_MSG_PROTECT15: // 게임가드 업데이트를 완료하지 못했습니다.<BR>바이러스 백신을 일시중지 시킨 후 재시도 하거나,<BR>개인방화벽 설정을 조정하시기 바랍니다.
case SYS_MSG_PROTECT16: // 게임가드 업데이트를 완료하지 못햇습니다.<BR>바이러스 백신을 일시중지 시킨 후 재시도 하거나,<BR>PC관리 프로그램의 설정을 조정하시기 바랍니다.
case SYS_MSG_PROTECT17: // 바이러스 및 해킹툴 검사 모듈로딩에 실패했습니다.<BR>메모리 부족이거나 바이러스에 의한 감염일 수 있습니다.
case SYS_MSG_PROTECT18: // 게임가드와의 통신 채널이 끊어졌습니다.
case SYS_MSG_PROTECT19: // 게임가드 초기화 에러
case SYS_MSG_PROTECT20: // 스피드 핵이 감지되었습니다.
case SYS_MSG_PROTECT21: // 게임 핵이 발견되었습니다.
case SYS_MSG_PROTECT22: // 게임클라이언트 혹은 게임가드가 변조되었습니다.
case SYS_MSG_DETECT_ALREADYHOOKED: //일부 API가 이미 후킹 되어 있는 상태 입니다.
case SYS_MSG_DETECT_AUTOMOUSE: //오토 마우스 행위가 감지되었습니다.
case SYS_MSG_DETECT_HOOKFUNCTION: //보호A PI에 대한 후킹 행위 가 감지되었습니다.
case SYS_MSG_DETECT_DRIVERFAILED: //해킹 차단 드라이버가 로드 되지않았습니다.
case SYS_MSG_DETECT_SPEEDHACK: //스피드핵 류의 프로그램이 감지되었습니다.
case SYS_MSG_DETECT_SPEEDHACK_APP: //스피드핵 류의 프로그램이 감지되었습니다.
case SYS_MSG_DETECT_MESSAGEHOOK: //메시지 후킹 시도가 감지되었습니다.
case SYS_MSG_DETECT_KDTRACE: //클라이언트 디버깅 시도가 감지되었습니다.
case SYS_MSG_DETECT_KDTRACE_CHANGED: //클라이언트 디버깅 시도가 감지되었습니다.
case SYS_MSG_DETECT_GAME_HACK: //게임 해킹 툴의 실행이 발견 되었습니다.
case SYS_MSG_DETECT_GENERAL_HACK: //일반 해킹 툴(트로이목마 종류)이 발견되었습니다.
case SYS_MSG_DETECT_MODULE_CHANGE: //핵 쉴드 관련 모듈이 변경되었습니다.
{ // 99
AddSystemMessage(SStringDB::ParseString( GetStringMessage(nMsgType) ).c_str(), 99);
break;
}
case SYS_MSG_QUEST_UNSELECT:
{ // 99
AddSystemMessage(SStringDB::ParseString(GetStringMessage(SYS_MSG_QUEST_UNSELECT)).c_str(), 99);
break;
}
case SYS_MSG_PK_ITEMDROP:
{ // 99
const ItemBaseEx_info* pItemBase = GetItemDB().GetItemData(nValue);
if (pItemBase)
{
std::string strItemName(GetStringDB().GetString(pItemBase->nNameId));
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@item_name@#", strItemName.c_str()).c_str(), 99);
}
break;
}
case SYS_MSG_USE_GRADE_ERROR:
{ // 99
AddSystemMessage(SStringDB::ParseString(GetStringMessage(SYS_MSG_USE_GRADE_ERROR)).c_str(), 99);
break;
}
case SYS_MSG_CHINA_PLAY_TIME: //당신의 접속 시간이 #@hour@#시간 되었습니다.
{ // 99
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@hour@#", SStringDB::ToString(nValue).c_str()).c_str(), 99);
break;
}
case SYS_MSG_CHINA_GAME_PLAYTIME: //플레이 타임 : #@hour@#시간 #@minute@# 분
{ // 99
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@hour@#", SStringDB::ToString(nValue).c_str(), "#@minute@#", SStringDB::ToString(nValue2).c_str()).c_str(), 99);
break;
}
case SYS_MSG_CHINA_FATIGUE_TIME_START: //당신의 합계 접속 시간이 3시간 되었으니 게임을 종료하고 휴식을 하거나 운동을 하십시오.
case SYS_MSG_CHINA_FATIGUE_TIME_WARNING: //이미 피로 게임 시간이 되었으니 당신의 게임 수익이 정상 수익의 50%로 감소됩니다. 게임을 종료하고 휴식을 하거나 운동을 하십시오. '피로'게임 시간 동안 완료된 퀘스트는 보상이 절반만 지급됩니다.
case SYS_MSG_CHINA_FATIGUE_TIME_QUEST: //피로’ 게임 시간 동안 완료된 퀘스트는 보상이 절반만 지급됩니다.
case SYS_MSG_CHINA_BAD_TIME_WARNING: //당신은 이미 인체에 해로운 게임 시간에 들어섰기에 즉시 게임을 종료하십시오. 만약 게임을 계속 진행한다면 당신의 건강에 해롭게 됩니다. 당신의 게임 수익은 이미 0으로 되었습니다. '인체에 해로운'게임 시간 동안에는 스태미너 세이버를 사용할 수 없습니다. '인체에 해로운'게임 시간 동안에는 퀘스트를 받거나 완료 할 수 없습니다.
case SYS_MSG_CHINA_BAD_TIME_STAMINA: //‘인체에 해로운’ 게임 시간 동안에는 스태미너 세이버를 사용할 수 없습니다.
case SYS_MSG_CHINA_BAD_TIME_QUEST: //‘인체에 해로운’ 게임 시간 동안에는 퀘스트를 받거나 완료 할 수 없습니다.
case SYS_MSG_CHINA_HEALTH_TIME_STATE: //현재 상태 : 건강
case SYS_MSG_CHINA_FATIGUE_TIME_STATE: //현재 상태 : 피로
case SYS_MSG_CHINA_BAD_TIME_STATE: //현재 상태 : 인체에 해로움
case SYS_MSG_CHINA_FATIGUE_TIME_STAMINA: //‘피로’ 게임 시간 동안에는 스태미너 세이버를 사용할 수 없습니다.
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_PUT_BROKEN_ITEM:
case SYS_MSG_SKILLRESULT_ALREADY_TAMING:
{
AddSystemMessage(S(nMsgType), 0);
break;
}
case SYS_MSG_SKILLRESULT_ALREADY_TAMING_MONSTER:
{
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_SKILLRESULT_NOT_TAMABLE:
case SYS_MSG_SKILLRESULT_ATARGET_ALREADY_BEING_TAMED:
case SYS_MSG_SKILLRESULT_NOT_ENOUGH_TARGET_HP:
case SYS_MSG_SKILLRESULT_NOT_ENOUGH_SUMMON_CARD:
case SYS_MSG_SKILLRESULT_NOT_ENOUGH_SOUL_TAMING_CARD:
{
AddSystemMessage(S(nMsgType), 0);
break;
}
case SYS_MSG_BOOTHFILTER_TEXT_1:
{
AddSystemMessage(S(nMsgType), 0);
break;
}
case SYS_MSG_STALL_OPENLEVEL:
{
// 99
AddSystemMessage(SStringDB::ParseString(GetStringMessage(nMsgType), "#@user_level@#", SStringDB::ToString(nValue).c_str()).c_str(), 99);
break;
}
case SYS_MSG_STALL_OPENHERE:
{
// 99
AddSystemMessage(S(nMsgType), 99);
break;
}
case SYS_MSG_MODIFY_TP:
{ // 0
int stringId, tp;
if (0 > nValue) /// 소모
{
stringId = 2504;
tp = abs((int)nValue);
}
else /// 획득
{
stringId = 2503;
tp = nValue;
}
AddSystemMessage(SStringDB::ParseString( GetStringMessage(stringId), "#@featurepoint@#", SStringDB::ToString(tp).c_str() ).c_str(), 0);
break;
}
case SYS_MSG_INVALID_ACT_IN_DUN:
{
// 0
AddSystemMessage(S(SYS_MSG_INVALID_ACT_IN_DUN), 0);
break;
}
}
}
std::string SUIDisplayInfo::GetItemColor( int nRank )
{
// Fraun performance tweak
std::string strItemColor = "<#c0c0c0>"; // Gray
switch (nRank)
{
case 2: strItemColor = "<#00c0ff>"; break; // Light Blue
case 3: strItemColor = "<#00ff00>"; break; // Green
case 4: strItemColor = "<#ffff00>"; break; // Yellow
case 5: strItemColor = "<#c000ff>"; break; // Purple
case 6: strItemColor = "<#ffc040>"; break; // Orange
default:
{
if (nRank > 6) strItemColor = "<#ff00ff>"; // Red
break;
}
}
return strItemColor;
}
std::string SUIDisplayInfo::GetText( const char* szString, ... )
{
char szBuf[1024];
va_list va;
va_start( va, szString );
_vsnprintf( szBuf, _countof(szBuf), szString, va );
va_end( va );
return std::string( szBuf );
}
void SUIDisplayInfo::SetBonusExpJpMsg( int nMsgType, int nPer, __int64 nExp, __int64 nJp )
{
std::string strMsg;
strMsg.clear();
switch( nMsgType )
{
case SYS_MSG_BONUS01:
{
strMsg = SStringDB::ParseString( GetStringMessage(SYS_MSG_BONUS01), "#@bonus@#", SStringDB::ToString( nPer ).c_str(), "#@exp@#", expToString( nExp ).c_str(), "#@jp@#", SStringDB::ToString( nJp ).c_str() );
}
break ;
case SYS_MSG_BONUS02:
{
strMsg = SStringDB::ParseString( GetStringMessage(SYS_MSG_BONUS02), "#@exp@#", expToString( nExp ).c_str(), "#@jp@#", SStringDB::ToString( nJp ).c_str() );
}
break;
case SYS_MSG_BONUS_DOUBLE:
{
// sonador 3.10.1 PC 방 혜택 관련 시스템 메시지 변경
strMsg = SStringDB::ParseString( GetStringMessage(SYS_MSG_BONUS_DOUBLE), "#@bonus@#", SStringDB::ToString( nPer ).c_str(), "#@exp@#", expToString( nExp ).c_str(), "#@jp@#", SStringDB::ToString( nJp ).c_str() );
}
break;
case SYS_MSG_BONUS_OGOK:
{
// 오곡크래커 관련 2009.04.14 sfreer
strMsg = SStringDB::ParseString( GetStringMessage(SYS_MSG_BONUS_OGOK), "#@bonus@#", SStringDB::ToString( nPer ).c_str(), "#@exp@#", expToString( nExp ).c_str() );
}
break;
// 2010.10.01 성장의 물약 - prodongi
case SYS_MSG_BONUS_SUPER_SAVE:
{
strMsg = SStringDB::ParseString( GetStringMessage(SYS_MSG_BONUS_SUPER_SAVE), "#@exp@#", expToString( nExp ).c_str(), "#@jp@#", SStringDB::ToString( nJp ).c_str() );
}
break;
}
if( !strMsg.empty() ) AddSystemMessage( strMsg.c_str(), 99 );
}
//////////////////////////////////////////////////////////////////////////
// 스킬 관련 툴팁
//////////////////////////////////////////////////////////////////////////
std::string SUIDisplayInfo::SkillString( int nID, float OriData, bool bNext, float EnData, const char* pTag/*""*/, const char* pKey/*"#@value@#"*/, bool bPlus/*true*/)
{
std::string strTip( ConvertDBString(nID, OriData, pTag, pKey, bPlus) );
if( EnData )
{
if( bNext ) strTip += ConvertDBString(7002, EnData, pTag, "#@enhance@#", bPlus);
else strTip += ConvertDBString(7001, EnData, pTag, "#@enhance@#", bPlus);
}
return strTip;
}
std::string SUIDisplayInfo::BasePlusDataString( SkillBaseEx* s_data, int nID, int BaseIndex, int EnIndex, int nUseLevel, bool bNext, int nEnhance/*=0*/, const char* pTag/*""*/, const char* pKey/*"#@value@#"*/, bool bRate/*false*/, bool bPlus/*true*/ )
{
std::string str("NULL");
bool bNextChange(true);
if( s_data )
{
float crrData( s_data->GetLvVar(BaseIndex, nUseLevel) );
if( bNext ) //true이면 현재가 아닌 다음 렙을 구하는 것. 다음렙에서 변화하는 내용만 출력하기 때문에 꼭 체크해서 스트링생성
{
float preData( s_data->GetLvVar(BaseIndex, nUseLevel-1) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
float nEnhanceData(0);
if( nEnhance && EnIndex != -1 )
{
nEnhanceData = s_data->GetVar(EnIndex)*nEnhance;
if( bRate ) nEnhanceData *= 100;
}
if( bRate ) crrData *= 100;
str = SkillString(nID, crrData, bNext, nEnhanceData, pTag, pKey, bPlus);
}
}
return str;
}
std::string SUIDisplayInfo::SkillValueString( SkillBaseEx* s_data, int nID, int BaseIndex, int EnIndex, int nUseLevel, bool bNext, int nEnhance/*=0*/, const char* pTag/*""*/, const char* pKey/*"#@value@#"*/, bool bRate/*false*/, bool bPlus/*true*/ )
{
std::string str("NULL");
bool bNextChange(true);
if( s_data )
{
float crrData( s_data->GetVar(BaseIndex) );
if( bNext ) return str;
if( crrData )
{
float nEnhanceData(0);
if( nEnhance && EnIndex != -1 )
{
nEnhanceData = s_data->GetVar(EnIndex)*nEnhance;
if( bRate ) nEnhanceData *= 100;
}
if( bRate ) crrData *= 100;
str = SkillString(nID, crrData, bNext, nEnhanceData, pTag, pKey, bPlus);
}
}
return str;
}
std::string SUIDisplayInfo::EnumSkillString( std::vector<std::string>& vStrList, const char* pTag )
{
std::string SkillString;
int nSize( vStrList.size() );
for( int i(0); i<nSize; ++i )
{
if( !vStrList[i].empty() && vStrList[i] != "NULL" )
{
SkillString += vStrList[i];
if( i>0 ) SkillString = SkillString+pTag;
}
}
return SkillString;
}
std::string SUIDisplayInfo::MagicDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string strMagicRate( BasePlusDataString(s_data, 7038, 0, 2, nUseLevel, bNext, nEnhance, "%", "#@value@#", true, false) );
std::string strMagic( BasePlusDataString(s_data, 7004, 3, 5, nUseLevel, bNext, nEnhance) );
bool bRate(strMagicRate!="NULL"); bool bMagic(strMagic!="NULL");
if( bRate && !bMagic ) return strMagicRate;
else if( !bRate && bMagic ) return strMagic;
else if( bRate && bMagic ) return strMagicRate + " / " + strMagic;
else return "NULL";
}
std::string SUIDisplayInfo::MagicAttackCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return BasePlusDataString(s_data, 7015, 6, -1, nUseLevel, bNext, nEnhance, "", "#@attack_count@#", false, false);
}
std::string SUIDisplayInfo::MagicUseCreatureHP( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return BasePlusDataString(s_data, 7039, 9, 11, nUseLevel, bNext, nEnhance );
}
std::string SUIDisplayInfo::MagicOneShotDead( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return BasePlusDataString(s_data, 7040, 6, -1, nUseLevel, bNext, nEnhance );
}
std::string SUIDisplayInfo::MagicAbsorptionHpMp( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string strMagicRecoveryHp( BasePlusDataString(s_data, 7029, 6, 8, nUseLevel, bNext, nEnhance, "%", "#@value@#", true, false) );
std::string strMagicRecoveryMp( BasePlusDataString(s_data, 7029, 9, 11, nUseLevel, bNext, nEnhance, "%", "#@value@#", true, false) );
bool bHp( strMagicRecoveryHp!="NULL" ); bool bMp( strMagicRecoveryMp!="NULL" );
if( bHp ) strMagicRecoveryHp = SStringDB::ParseString( strMagicRecoveryHp.c_str(), "#@point_name@#", S(7005) );
if( bMp ) strMagicRecoveryMp = SStringDB::ParseString( strMagicRecoveryMp.c_str(), "#@point_name@#", S(7006) );
if( bHp && !bMp ) return strMagicRecoveryHp;
else if( !bHp && bMp ) return strMagicRecoveryMp;
else if( bHp && bMp ) return strMagicRecoveryHp + " / " + strMagicRecoveryMp;
else return "NULL";
}
std::string SUIDisplayInfo::MagicHpRateDamage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return BasePlusDataString(s_data, 7041, 0, 2, nUseLevel, bNext, nEnhance, "%", "#@value@#", true, false );
}
std::string SUIDisplayInfo::MagicMPHpDamage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return BasePlusDataString(s_data, 7040, 6, -1, nUseLevel, bNext, nEnhance );
}
std::string SUIDisplayInfo::MagicAttackRange( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return SkillValueString(s_data, 7037, 9, -1, nUseLevel, bNext, nEnhance, "", "#@value@#", false, false );
}
std::string SUIDisplayInfo::MagicAttackTargetCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return SkillValueString(s_data, 7016, 11, -1, nUseLevel, bNext, nEnhance, "", "#@number_of_mob@#", false, false );
}
std::string SUIDisplayInfo::MagicDamageRate( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
return SkillValueString(s_data, 7044, 10, 11, nUseLevel, bNext, nEnhance, "", "#@value@#", true, false );
}
std::string SUIDisplayInfo::MagicDamageHeal( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string strMagicDamage( SkillValueString(s_data, 7004, 0, 1, nUseLevel, bNext, nEnhance, "%", "#@value@#", true, false) );
std::string strMagicRecoveryHp( BasePlusDataString(s_data, 7029, 2, 4, nUseLevel, bNext, nEnhance ) );
bool bHp( strMagicRecoveryHp != "NULL" );
bool bDamage( strMagicDamage != "NULL" );
if( bHp ) strMagicRecoveryHp = SStringDB::ParseString( strMagicRecoveryHp.c_str(), "#@point_name@#", S(7005) );
if( bDamage && !bHp ) return strMagicDamage;
else if( !bDamage && bHp ) return strMagicRecoveryHp;
else if( bDamage && bHp ) return strMagicDamage + " / " + strMagicRecoveryHp;
else return "NULL";
}
std::string SUIDisplayInfo::PhysicalHitDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7003, crrData);
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetPowerByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::PhysicalHitAbsorb( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( crrData && bNextChange ) Tooltip = ConvertDBString(7003, crrData);
}
return Tooltip;
}
std::string SUIDisplayInfo::PhysicalMultiHitDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7003, crrData);
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetPowerOneByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::PhysicalHitDemageRate( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetPowerRate( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetPowerRate( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7003, crrData, "%");
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetPowerRateByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::PhysicalRealHitDemageRate( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetRealTimePowerRate( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetRealTimePowerRate( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7003, crrData, "%");
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetPowerRateByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::MagicHitDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetMagicPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetMagicPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7004, crrData);
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetMagicByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#" );
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::MagicMultiHitDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetMagicPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetMagicPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7004, crrData);
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetMagicOneByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#" );
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::SpecialMagicHitDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetMagicPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetMagicPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7004, crrData);
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetSpecialMagicByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::MagicRangeStatetDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetMagicPower( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetMagicPower( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7004, crrData);
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetMagicRangeStateDemageByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "", "#@enhance@#" );
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::MagicHitDemageRate( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetMagicPowerRate( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetMagicPowerRate( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = ConvertDBString(7004, crrData, "%");
if( nEnhance )
{
int nEnhancePower(0); nEnhancePower = ( s_data->GetMagicRateByEnhance( nEnhance ) );
if( nEnhancePower )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhancePower, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhancePower, "%", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::Recovery( SkillBaseEx* s_data, int nUseLevel, RecoveryType type, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int nRecovery(0); int nRecoveryStat(0); int nRecoveryPer(0);
nRecovery = s_data->GetRecovery( nUseLevel );
nRecoveryStat = s_data->GetRecoveryStat( nUseLevel );
nRecoveryPer = s_data->GetRecoveryPer( nUseLevel );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int PreRecovery(0); int PreRecoveryStat(0); int PreRecoveryPer(0);
PreRecovery = s_data->GetRecovery( nUseLevel-1 );
PreRecoveryStat = s_data->GetRecoveryStat( nUseLevel-1 );
PreRecoveryPer = s_data->GetRecoveryPer( nUseLevel-1 );
if( PreRecovery == nRecovery && PreRecoveryStat == nRecoveryStat && PreRecoveryPer == nRecoveryPer ) bNextChange = false;
}
if( bNextChange )
{
std::string temp;
if( type == HP ) temp = S(7005);
else if( type == MP ) temp = S(7006);
else temp = S(7007);
if( nRecovery != 0 )
{
Tooltip = SR( 7008, "#@recovery_type@#", temp.c_str(), "#@recovery_amount@#", nRecovery );
if( nEnhance )
{
int nEnhanceRecovery(0); int nEnhanceRecoveryPer(0);
nEnhanceRecovery = s_data->GetRecoveryByEnhance(nEnhance);
nEnhanceRecoveryPer = s_data->GetRecoveryPerByEnhance(nEnhance);
if( nEnhanceRecovery )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecovery, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecovery, "", "#@enhance@#");
}
else if( nEnhanceRecoveryPer )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecoveryPer, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecoveryPer, "%", "#@enhance@#");
}
}
if( nRecoveryStat != 0 ) Tooltip += SR( 7009, "#@recovery_per@#", nRecoveryStat );
}
else if( nRecoveryPer != 0 )
{
Tooltip = SR( 7010, "#@recovery_type@#", temp.c_str(), "#@recovery_per@#", nRecoveryPer );
if( nEnhance )
{
int nEnhanceRecovery(0); int nEnhanceRecoveryPer(0);
nEnhanceRecovery = s_data->GetRecoveryByEnhance(nEnhance);
nEnhanceRecoveryPer = s_data->GetRecoveryPerByEnhance(nEnhance);
if( nEnhanceRecoveryPer )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecoveryPer, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecoveryPer, "%", "#@enhance@#");
}
else if( nEnhanceRecovery )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecovery, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecovery, "", "#@enhance@#");
}
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::RecoveryHPMP( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int nRecoveryHP(0); int nRecoveryHPStat(0); int nRecoveryHPPer(0);
nRecoveryHP = s_data->GetRecoveryHP( nUseLevel );
nRecoveryHPStat = s_data->GetRecoveryStatHP( nUseLevel );
nRecoveryHPPer = s_data->GetRecoveryPerHP( nUseLevel );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preRecoveryHP(0); int preRecoveryHPStat(0); int preRecoveryHPPer(0);
preRecoveryHP = s_data->GetRecoveryHP( nUseLevel-1 );
preRecoveryHPStat = s_data->GetRecoveryStatHP( nUseLevel-1 );
preRecoveryHPPer = s_data->GetRecoveryPerHP( nUseLevel-1 );
if( nRecoveryHP == preRecoveryHP && nRecoveryHPStat == preRecoveryHPStat && nRecoveryHPPer == preRecoveryHPPer ) bNextChange = false;
}
if( bNextChange )
{
if( nRecoveryHP != 0 )
{
Tooltip = SR( 7008, "#@recovery_type@#", S(7005), "#@recovery_amount@#", nRecoveryHP );
if( nRecoveryHPStat != 0 ) Tooltip += SR( 7009, "#@recovery_per@#", nRecoveryHPStat );
}
else if( nRecoveryHPPer != 0 )
{
Tooltip += SR( 7010, "#@recovery_type@#", S(7005), "#@recovery_per@#", nRecoveryHPPer );
}
if( nEnhance )
{
int nEnhanceRecovery(0);
nEnhanceRecovery = s_data->GetRecoveryHPByEnhance(nEnhance);
if( nEnhanceRecovery )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecovery, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecovery, "", "#@enhance@#");
}
}
int nRecoveryMP(0); int nRecoveryMPStat(0); int nRecoveryMPPer(0);
nRecoveryMP = s_data->GetRecoveryMP( nUseLevel );
nRecoveryMPStat = s_data->GetRecoveryStatMP( nUseLevel );
nRecoveryMPPer = s_data->GetRecoveryPerMP( nUseLevel );
if( nRecoveryMP != 0 )
{
if( !Tooltip.empty() ) Tooltip += " / ";
Tooltip += SR( 7008, "#@recovery_type@#", S(7006), "#@recovery_amount@#", nRecoveryMP );
if( nRecoveryHPStat != 0 ) Tooltip += SR( 7009, "#@recovery_per@#", nRecoveryHPStat );
}
else if( nRecoveryMPPer != 0 )
{
if( !Tooltip.empty() ) Tooltip += " / ";
Tooltip += SR( 7010, "#@recovery_type@#", S(7006), "#@recovery_per@#", nRecoveryMPPer );
}
if( nEnhance )
{
int nEnhanceRecovery(0);
nEnhanceRecovery = s_data->GetRecoveryMPByEnhance(nEnhance);
if( nEnhanceRecovery )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecovery, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecovery, "", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::RecoveryHPMPSP( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int nRecoveryHP(0); int nRecoveryMP(0); int nRecoverySP(0);
nRecoveryHP = s_data->GetRecoveryAllHP( nUseLevel );
nRecoveryMP = s_data->GetRecoveryAllMP( nUseLevel );
nRecoverySP = s_data->GetRecoveryAllSP( nUseLevel );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preRecoveryHP(0); int preRecoveryMP(0); int preRecoverySP(0);
preRecoveryHP = s_data->GetRecoveryAllHP( nUseLevel-1 );
preRecoveryMP = s_data->GetRecoveryAllMP( nUseLevel-1 );
preRecoverySP = s_data->GetRecoveryAllSP( nUseLevel-1 );
if( nRecoveryHP == preRecoveryHP && nRecoveryMP == preRecoveryMP && nRecoverySP == preRecoverySP ) bNextChange = false;
}
if( bNextChange )
{
if( nRecoveryHP != 0 ) Tooltip += SR( 7011, "#@recovery_type@#", S(7005), "#@recovery_amount@#", nRecoveryHP );
if( nRecoveryMP != 0 ) Tooltip += SR( 7011, "#@recovery_type@#", S(7006), "#@recovery_amount@#", nRecoveryMP );
if( nRecoverySP != 0 ) Tooltip += SR( 7011, "#@recovery_type@#", S(7007), "#@recovery_amount@#", nRecoverySP );
if( nEnhance )
{
int nEnhanceRecovery(0);
nEnhanceRecovery = s_data->GetRecoveryAllPerByEnhance(nEnhance);
if( nEnhanceRecovery )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceRecovery, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceRecovery, "%", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::RecoveryRange( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //스킬레벨에 따른 추가공격력 값이 변하지 않아서 체크 안한다
{
int Range(0); Range = ( s_data->GetRecoveryAllRange() );
if( Range )
Tooltip = SR(7012, "#@effect_range@#", Range);
}
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", "" );
return Tooltip;
}
std::string SUIDisplayInfo::Absorption( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 흡수율 변화가 없어서 비교체크 안한다
{
int AbsorptionHP(0); int AbsorptionMP(0);
AbsorptionHP = s_data->GetPerAbsorptionHP();
AbsorptionMP = s_data->GetPerAbsorptionMP();
if( AbsorptionHP ) //HP흡수
{
std::string strEnhance;
Tooltip = SR(7013, "#@recovery_type@#", S(7005), "#@damage_per@#", AbsorptionHP);
if( nEnhance )
{
int nEnhanceAbsorptionHP(0); nEnhanceAbsorptionHP = ( s_data->GetAbsorptionHPByEnhance( nEnhance ) );
if( nEnhanceAbsorptionHP ) strEnhance = ConvertDBString(7001, nEnhanceAbsorptionHP, "%", "#@enhance@#");
}
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_recovery_per@#", strEnhance.c_str() );
}
if( AbsorptionMP ) //HP흡수가 없이 MP흡수만 있는 경우
{
std::string strEnhance;
Tooltip = SR(7013, "#@recovery_type@#", S(7006), "#@damage_per@#", AbsorptionMP);
if( nEnhance )
{
int nEnhanceAbsorptionMP(0); nEnhanceAbsorptionMP = ( s_data->GetAbsorptionMPByEnhance( nEnhance ) );
if( nEnhanceAbsorptionMP ) strEnhance = ConvertDBString(7001, nEnhanceAbsorptionMP, "%", "#@enhance@#");
}
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_recovery_per@#", strEnhance.c_str() );
}
}
return Tooltip;
}
std::string SUIDisplayInfo::AmountAbsorption( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int AbsorptionHP(0); int AbsorptionMP(0);
AbsorptionHP = s_data->GetAmountAbsorptionHP(nUseLevel);
AbsorptionMP = s_data->GetAmountAbsorptionMP(nUseLevel);
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preAbsorptionHP(0); int preAbsorptionMP(0);
preAbsorptionHP = s_data->GetAmountAbsorptionHP( nUseLevel-1 );
preAbsorptionMP = s_data->GetAmountAbsorptionMP( nUseLevel-1 );
if( AbsorptionHP == preAbsorptionHP && AbsorptionMP == preAbsorptionMP ) bNextChange = false;
}
if( bNextChange )
{
if( AbsorptionHP ) //HP흡수
{
std::string strEnhance;
Tooltip = ConvertDBString(7029, AbsorptionHP);
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@point_name@#", S(7005) );
if( nEnhance )
{
int nEnhanceAbsorptionHP(0); nEnhanceAbsorptionHP = ( s_data->GetAbsorptionHPPointByEnhance( nEnhance ) );
if( nEnhanceAbsorptionHP ) strEnhance = ConvertDBString(7001, nEnhanceAbsorptionHP, "", "#@enhance@#");
}
Tooltip += strEnhance;
}
if( AbsorptionMP ) //HP흡수가 없이 MP흡수만 있는 경우
{
std::string strEnhance;
Tooltip = ConvertDBString(7029, AbsorptionMP);
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@point_name@#", S(7006) );
if( nEnhance )
{
int nEnhanceAbsorptionMP(0); nEnhanceAbsorptionMP = ( s_data->GetAbsorptionMPPointByEnhance( nEnhance ) );
if( nEnhanceAbsorptionMP ) strEnhance = ConvertDBString(7001, nEnhanceAbsorptionMP, "", "#@enhance@#");
}
Tooltip += strEnhance;
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::AmountAbsorptionRate( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int AmountAbsorptionRate = s_data->GetAmountAbsorptionRate(); // 흡수한 값에 대한 회복률
if( AmountAbsorptionRate )
{
Tooltip = ConvertDBString(7033, AmountAbsorptionRate, "%");
if( nEnhance )
{
int nEnhanceAmountAbsorptionRate(0); nEnhanceAmountAbsorptionRate = s_data->GetAmountAbsorptionRateByEnhance(nEnhance);
if( nEnhanceAmountAbsorptionRate )
{
if( bNext ) Tooltip += ConvertDBString(7002, nEnhanceAmountAbsorptionRate, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nEnhanceAmountAbsorptionRate, "%", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::AddHitDemage( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //스킬레벨에 따른 추가공격력 값이 변하지 않아서 체크 안한다
{
int demage(0); demage = ( s_data->AddAttackDemage() );
if( demage ) Tooltip = ConvertDBString(7014, demage, "", "#@power@#");
}
return Tooltip;
}
std::string SUIDisplayInfo::AttackCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetAttackCount( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetAttackCount( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData ) Tooltip = SR(7015, "#@attack_count@#", crrData);
}
return Tooltip;
}
std::string SUIDisplayInfo::RealtimeAttackCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetRealtimeAttackCount( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetRealtimeAttackCount( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData ) Tooltip = SR(7015, "#@attack_count@#", crrData);
}
return Tooltip;
}
std::string SUIDisplayInfo::AttackRange( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 범위의 변화가 없다
{
int Range(0); Range = ( s_data->GetAttackRange() );
if( Range || nEnhance )
{
Tooltip = SR(7012, "#@effect_range@#", Range);
if( nEnhance )
{
int nEnhanceRange(0);
nEnhanceRange = s_data->GetIncreaseAttackRange(nEnhance);
if( nEnhanceRange ) Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", SStringDB::ToString(nEnhanceRange).c_str() );
else if( !Range ) return "";
else Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", "" );
}
else Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", "" );
}
}
return Tooltip;
}
std::string SUIDisplayInfo::MultiAttackRange( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 범위의 변화가 없다
{
int Range(0); Range = ( s_data->GetMultiAttackRange() );
if( Range || nEnhance )
{
Tooltip = SR(7012, "#@effect_range@#", Range);
if( nEnhance )
{
int nEnhanceRange(0);
nEnhanceRange = s_data->GetIncreaseMultiAttackRange(nEnhance);
if( nEnhanceRange ) Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", SStringDB::ToString(nEnhanceRange).c_str() );
else if( !Range ) return "";
else Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", "" );
}
else Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_range@#", "" );
}
}
return Tooltip;
}
std::string SUIDisplayInfo::SpecialAttackRange( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 범위의 변화가 없다
{
int Range(0); Range = ( s_data->GetSpecialAttackRange() );
if( Range ) Tooltip = SR(7012, "#@enhance_range@#", "", "#@effect_range@#", Range);
}
return Tooltip;
}
std::string SUIDisplayInfo::MultiAttackKnockBackRange( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 범위의 변화가 없다
{
int Range(0); Range = ( s_data->GetMultiAttackKnockBackRange() );
if( Range ) Tooltip = SR(7012, "#@enhance_range@#", "", "#@effect_range@#", Range);
}
return Tooltip;
}
std::string SUIDisplayInfo::TargetCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext )
{
int Cnt(0); Cnt = ( s_data->GetTargetCount() );
if( Cnt ) Tooltip = SR(7016, "#@number_of_mob@#", Cnt);
}
return Tooltip;
}
std::string SUIDisplayInfo::MultiAttackTargetCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext )
{
int Cnt(0); Cnt = ( s_data->GetMultiAttackTargetCount() );
if( Cnt ) Tooltip = SR(7016, "#@number_of_mob@#", Cnt);
}
return Tooltip;
}
std::string SUIDisplayInfo::SpecialMultiAttackTargetCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 범위의 변화가 없다
{
int Range(0); Range = ( s_data->GetSpecialMultiAttackTargetCount() );
if( Range ) Tooltip = SR(7012, "#@enhance_range@#", "", "#@effect_range@#", Range);
}
return Tooltip;
}
std::string SUIDisplayInfo::RangeMagicTargetCount( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext )
{
int Cnt(0); Cnt = ( s_data->GetRangeMagicTargetCount() );
if( Cnt ) Tooltip = SR(7016, "#@number_of_mob@#", Cnt);
}
return Tooltip;
}
std::string SUIDisplayInfo::KnockBack( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetKnockBack( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetKnockBack( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = SR(7017, "#@nuckback_distance@#", crrData);
std::string strEnhance;
if( nEnhance )
{
int nKnockBack(0); nKnockBack = s_data->GetIncreaseKnockBack(nEnhance);
if( nKnockBack )
{
if( bNext ) strEnhance = ConvertDBString(7002, nKnockBack, "", "#@enhance@#");
else strEnhance = ConvertDBString(7001, nKnockBack, "", "#@enhance@#");
}
}
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_distance@#", strEnhance.c_str() );
}
}
return Tooltip;
}
std::string SUIDisplayInfo::MultiAttackKnockBack( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
if( s_data && !bNext ) //렙에 따른 범위의 변화가 없다
{
int KnockBack(0); KnockBack = ( s_data->GetMultiAttackKnockBack( nUseLevel ) );
if( KnockBack ) Tooltip = SR(7017, "#@enhance_distance@#", "", "#@nuckback_distance@#", KnockBack);
}
return Tooltip;
}
std::string SUIDisplayInfo::TamingRate( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int crrData(0); crrData = ( s_data->GetTamingSuccess( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preData(0); preData = ( s_data->GetTamingSuccess( nUseLevel-1 ) );
if( crrData == preData ) bNextChange = false;
}
if( bNextChange && crrData )
{
Tooltip = SR(7018, "#@success_per@#", crrData);
if( nEnhance )
{
int nTaming(0); nTaming = s_data->GetTamingSuccessByEnhance(nEnhance);
if( nTaming )
{
if( bNext ) Tooltip += ConvertDBString(7002, nTaming, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, nTaming, "%", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::Resurrection( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int RestorationEXP(0); RestorationEXP = ( s_data->ResurrectionEXP( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preRestorationEXP(0); preRestorationEXP = ( s_data->ResurrectionEXP( nUseLevel-1 ) );
if( RestorationEXP == preRestorationEXP ) bNextChange = false;
}
if( bNextChange && RestorationEXP )
{
Tooltip = SR(7030, "#@value@#", RestorationEXP);
if( nEnhance )
{
int enhanceRestorationEXP = s_data->GetExpIncreaseByRevival( nEnhance );
if( enhanceRestorationEXP )
{
if( bNext ) Tooltip += ConvertDBString(7002, enhanceRestorationEXP, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, enhanceRestorationEXP, "%", "#@enhance@#");
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::RemoveState( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int Success(0); Success = ( s_data->GetStateSuccess( nUseLevel ) );
int Lv(0); Lv = ( s_data->RemoveStateLv( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preSuccess(0); preSuccess = ( s_data->GetStateSuccess( nUseLevel-1 ) );
int preLv(0); preLv = ( s_data->RemoveStateLv( nUseLevel-1 ) );
if( Success == preSuccess && Lv == preLv ) bNextChange = false;
}
if( bNextChange && Success && Lv )
{
int StateID1 = s_data->RemoveStateID1();
int StateID2 = s_data->RemoveStateID2();
int StateID3 = s_data->RemoveStateID3();
int StateID4 = s_data->RemoveStateID4();
int StateID5 = s_data->RemoveStateID5();
int StateID6 = s_data->RemoveStateID6();
std::vector<std::string> StateNameList;
if( StateID1 ) StateNameList.push_back( GetStringDB().GetString( GetTenacityDB().GetNameID(StateID1) ) );
if( StateID2 ) StateNameList.push_back( GetStringDB().GetString( GetTenacityDB().GetNameID(StateID2) ) );
if( StateID3 ) StateNameList.push_back( GetStringDB().GetString( GetTenacityDB().GetNameID(StateID3) ) );
if( StateID4 ) StateNameList.push_back( GetStringDB().GetString( GetTenacityDB().GetNameID(StateID4) ) );
if( StateID5 ) StateNameList.push_back( GetStringDB().GetString( GetTenacityDB().GetNameID(StateID5) ) );
if( StateID6 ) StateNameList.push_back( GetStringDB().GetString( GetTenacityDB().GetNameID(StateID6) ) );
if( !StateNameList.empty() && Success && Lv )
{
Tooltip = SR(7031, "#@debuff@#", BuildEnumString(StateNameList, " / ").c_str(), "#@success_per@#", Success, "#@value@#", Lv );
int IncreaseRemoveStateLv = s_data->GetRemoveStateLvByEnhance( nEnhance );
if( IncreaseRemoveStateLv )
{
const char* lv = GetStringDB().GetString( 9501 ); // "Lv"
if( bNext ) Tooltip += ConvertDBString(7002, IncreaseRemoveStateLv, lv, "#@enhance@#");
else Tooltip += ConvertDBString(7001, IncreaseRemoveStateLv, lv, "#@enhance@#");
}
}
StateNameList.clear();
}
}
return Tooltip;
}
std::string SUIDisplayInfo::AddAggro( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
if( s_data )
{
int Success(0); Success = ( s_data->GetSuccessRate( nUseLevel ) );
int Aggro(0); Aggro = ( s_data->GetAggro( nUseLevel ) );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preSuccess(0); preSuccess = ( s_data->GetSuccessRate( nUseLevel-1 ) );
int preAggro(0); preAggro = ( s_data->GetAggro( nUseLevel-1 ) );
if( Success == preSuccess && Aggro == preAggro ) bNextChange = false;
}
if( bNextChange && Aggro )
{
Tooltip = SR(7027, "#@aggro_point@#", Aggro);
int IncreaseAggro = s_data->GetAggroByEnhance( nEnhance );
if( IncreaseAggro )
{
if( bNext ) Tooltip += ConvertDBString(7002, IncreaseAggro, "", "#@enhance@#");
else Tooltip += ConvertDBString(7001, IncreaseAggro, "", "#@enhance@#");
}
}
if( bNextChange && Success )
{
std::string strSuccess = "<#ffffff>";
strSuccess += CStringUtil::StringFormat( "%d%%", Success );
strSuccess = SR(9011, "#@value@#", strSuccess.c_str());
if( Tooltip.empty() ) strSuccess.erase(0, 4);
Tooltip += strSuccess;
int IncreaseSuccess = s_data->GetSuccessRateByEnhance( nEnhance );
if( IncreaseSuccess )
{
if( bNext ) Tooltip += ConvertDBString(7002, IncreaseSuccess, "%", "#@enhance@#");
else Tooltip += ConvertDBString(7001, IncreaseSuccess, "%", "#@enhance@#");
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::State( SkillBaseEx* s_data, int nUseLevel, bool bNext, int nEnhance/*=0*/ )
{
std::string Tooltip;
bool bNextChange(true);
bool bToggle(true);
if( s_data )
{
bToggle = s_data->IsToggle();
int Success(0); Success = ( s_data->GetStateSuccess( nUseLevel ) );
int Lv(0); Lv = ( s_data->GetStateLevel( nUseLevel ) );
int ConsumptionMP(0);
if( bToggle ) ConsumptionMP = s_data->GetConsumptionMP( nUseLevel );
if( bNext ) //다음 스킬레벨을 찍는것은 전 스킬에서 변화되는 데이터만 출력해주기 때문에 체크하는 것
{
int preSuccess(0); preSuccess = ( s_data->GetStateSuccess( nUseLevel-1 ) );
int preLv(0); preLv = ( s_data->GetStateLevel( nUseLevel-1 ) );
int preConsumptionMP(0);
if( bToggle ) preConsumptionMP = s_data->GetConsumptionMP( nUseLevel-1 );
if( bToggle && Success == preSuccess && Lv == preLv && ConsumptionMP == preConsumptionMP ) bNextChange = false;
else if( Success == preSuccess && Lv == preLv ) bNextChange = false;
}
if( bNextChange && Success && Lv )
{
int StateNameID(0); StateNameID = GetTenacityDB().GetNameID( s_data->GetStateId() );
if( StateNameID )
{
std::string StateName = GetStringDB().GetString( StateNameID );
std::string strAddStateName = GetAddStateName(s_data);
if( !strAddStateName.empty() )
{
StateName += " / ";
StateName += strAddStateName;
}
/// 2011.03.30 s_data->GetStateType() 삭제에 따른 수정 - prodongi
Tooltip = SR(2057, "#@state_name@#", StateName.c_str());
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@success_per@#", SStringDB::ToString(Success).c_str() );
if( Lv )
{
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@state_lv@#", SStringDB::ToString(Lv).c_str() );
std::string strEnhance;
if( nEnhance )
{
int nLv(0); nLv = s_data->GetStateEnhanceLv(nEnhance);
if( nLv )
{
const char* lv = GetStringDB().GetString( 9501 ); // "Lv"
if( bNext ) strEnhance = ConvertDBString(7002, nLv, lv, "#@enhance@#");
else strEnhance = ConvertDBString(7001, nLv, lv, "#@enhance@#");
}
}
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_lv@#", strEnhance.c_str() );
}
std::string strEnhance;
float ar_StateTime = s_data->GetStateTime( nUseLevel );
if( !s_data->IsToggle() && ar_StateTime )
{
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@state_time@#", GetTimeString( ar_StateTime/100.0f ).c_str() );
if( nEnhance )
{
float fTime(0.0f); fTime = s_data->GetStateEnhanceTime(nEnhance);
if( fTime )
{
std::string strTime;
if( fTime > 0 ) strTime = "+";
strTime += GetTimeString( fTime/100.0f );
if( strTime != "+" )
{
strEnhance += SR(7001, "#@enhance@#", strTime.c_str());
}
}
}
}
else Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@state_time@#", "" );
Tooltip = SStringDB::ParseString( Tooltip.c_str(), "#@enhance_time@#", strEnhance.c_str() );
}
if( bToggle && ConsumptionMP )
{
if( !Tooltip.empty() ) Tooltip += "<BR>";
Tooltip += SR(7032, "#@value@#", ConsumptionMP);
std::string strEnhance;
int nEnhanceConsumptionMP(0); nEnhanceConsumptionMP = s_data->GetConsumptionMPByEnhance(nEnhance);
if( nEnhanceConsumptionMP )
{
if( bNext ) strEnhance = ConvertDBString(7002, nEnhanceConsumptionMP, "", "#@enhance@#");
else strEnhance = ConvertDBString(7001, nEnhanceConsumptionMP, "", "#@enhance@#");
Tooltip += strEnhance;
}
}
}
}
return Tooltip;
}
std::string SUIDisplayInfo::GetStateName( int StateID )
{
if( StateID )
{
int StateNameID(0);
StateNameID = GetTenacityDB().GetNameID( StateID );
if( StateNameID )
return GetStringDB().GetString( StateNameID );
}
return "";
}
std::string SUIDisplayInfo::GetAddStateName( SkillBaseEx* s_data )
{
std::vector<std::string> vecStateNameList;
int nEffectType = s_data->GetEffectType();
std::string StateName;
int StateID(0); int StateNameID(0);
if( nEffectType == SkillBase::EF_ADD_STATE )
{
StateID = s_data->AddStateID1();
StateName = GetStateName(StateID);
if( !StateName.empty() ) vecStateNameList.push_back( StateName );
StateID= s_data->AddStateID2();
StateName = GetStateName(StateID);
if( !StateName.empty() ) vecStateNameList.push_back( StateName );
StateID= s_data->AddStateID3();
StateName = GetStateName(StateID);
if( !StateName.empty() ) vecStateNameList.push_back( StateName );
}
if( nEffectType == SkillBase::EF_ADD_STATE || nEffectType == SkillBase::EF_TOGGLE_AURA)
{
StateID= s_data->AddStateID4();
StateName = GetStateName(StateID);
if( !StateName.empty() ) vecStateNameList.push_back( StateName );
StateID= s_data->AddStateID5();
StateName = GetStateName(StateID);
if( !StateName.empty() ) vecStateNameList.push_back( StateName );
}
if( !vecStateNameList.empty() )
{
std::string ret = BuildEnumString(vecStateNameList, " / ");
vecStateNameList.clear();
return ret;
}
return "";
}
std::string SUIDisplayInfo::SkillEffectTooltipText( int nEffectType, int nSkillID, int nUseLevel, bool bNext, int nEnhance )
{
if( nEffectType == 0 ) return std::string( "" );
std::string strTooltip;// = "<BR>";
SkillBaseEx* s_data = GetSkillDB().GetSkillData( nSkillID );
switch( nEffectType )
{
case SkillBase::EF_PHYSICAL_SINGLE_DAMAGE_T1:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_DAMAGE_T1:
{
std::string strTemp = PhysicalMultiHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_DAMAGE_T2:
{
std::string strTemp = PhysicalHitDemageRate( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_DAMAGE_T2:
{
std::string strTemp = PhysicalHitDemageRate( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_DIRECTIONAL_DAMAGE:
{
std::string strTemp = PhysicalMultiHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_DAMAGE_T3:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_DAMAGE_T3:
{
std::string strTemp = PhysicalMultiHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_DAMAGE_TRIPLE_ATTACK:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = RealtimeAttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_REGION_DAMAGE:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackRange( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = TargetCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_REGION_DAMAGE:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackRange( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = MultiAttackTargetCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SPECIAL_REGION_DAMAGE:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = SpecialAttackRange( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = SpecialMultiAttackTargetCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_ABSORB_DAMAGE:
{
std::string strTemp = PhysicalHitAbsorb( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = Absorption( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_DAMAGE_KNOCK_BACK:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = KnockBack( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_REGION_DAMAGE_KNOCK_BACK:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = KnockBack( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackRange( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = TargetCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_DAMAGE_KNOCK_BACK:
{
std::string strTemp = PhysicalRealHitDemageRate( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = MultiAttackKnockBack( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_MULTIPLE_REGION_DAMAGE_KNOCK_BACK:
{
std::string strTemp = PhysicalRealHitDemageRate( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = MultiAttackKnockBack( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = MultiAttackKnockBackRange( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = MultiAttackTargetCount( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_DAMAGE_WITHOUT_WEAPON_RUSH_KNOCK_BACK:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AddHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = KnockBack( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_PHYSICAL_SINGLE_DAMAGE_RUSH_KNOCK_BACK:
{
std::string strTemp = PhysicalHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = AddHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = KnockBack( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_MAGIC_SINGLE_DAMAGE_T1:
{
strTooltip = MagicDemage( s_data, nUseLevel, bNext, nEnhance );
if(!strTooltip.empty()) strTooltip += "<BR>";
break;
}
case SkillBase::EF_MAGIC_MULTIPLE_DAMAGE_T1:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackCount( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
// case SkillBase::EF_MAGIC_SINGLE_DAMAGE_T2:
// {
// std::string strTemp = MagicHitDemageRate( s_data, nUseLevel, bNext, nEnhance );
// if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
// break;
// }
// case SkillBase::EF_MAGIC_MULTIPLE_DAMAGE_T2:
// {
// std::string strTemp = MagicHitDemageRate( s_data, nUseLevel, bNext, nEnhance );
// if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
//
// strTemp = AttackCount( s_data, nUseLevel, bNext, nEnhance );
// if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
// break;
// }
case SkillBase::EF_MAGIC_MULTIPLE_DAMAGE_T1_DEAL_SUMMON_HP:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackCount( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicUseCreatureHP( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_SINGLE_DAMAGE_DEAD:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicOneShotDead( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_SINGLE_ABSORPTION_DAMAGE:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAbsorptionHpMp( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_SINGLE_HPRATE_DAMAGE:
{
strTooltip = MagicHpRateDamage( s_data, nUseLevel, bNext, nEnhance );
if(!strTooltip.empty()) strTooltip += "<BR>";
break;
}
case SkillBase::EF_MAGIC_SINGLE_MP_HP_DAMAGE:
{
strTooltip = MagicMPHpDamage( s_data, nUseLevel, bNext, nEnhance );
if(!strTooltip.empty()) strTooltip += "<BR>";
break;
}
case SkillBase::EF_MAGIC_REGION_DAMAGE:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackRange( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_SPECIAL_REGION_DAMAGE:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackRange( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackTargetCount( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_MULTIPLE_REGION_DAMAGE:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackRange( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackCount( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackTargetCount( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_MULTIPLE_SINGLE_HPRATE_DAMAGE:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicHpRateDamage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackRange( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackCount( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_SINGLE_WORLD_REGION_DAMAGE:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDemage( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackRange( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicDamageRate( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_MAGIC_SINGLE_WORLD_REGION_DAMAGE_RECOVERY:
{
std::vector<std::string> vStrList;
vStrList.push_back( MagicDamageHeal( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicDamageRate( s_data, nUseLevel, bNext, nEnhance ) );
vStrList.push_back( MagicAttackRange( s_data, nUseLevel, bNext, nEnhance ) );
strTooltip = EnumSkillString(vStrList, "<BR>");
if(!strTooltip.empty()) strTooltip += "<BR>";
vStrList.clear();
break;
}
case SkillBase::EF_ADD_STATE:
{
}
break;
// EF_PHYSICAL_SINGLE_DAMAGE_AND_ADD_STATE
// EF_PHYSICAL_MULTIPLE_DAMAGE_AND_ADD_STATE
// EF_MAGICAL_SINGLE_DAMAGE_AND_ADD_STATE
// EF_MAGICAL_MULTIPLE_DAMAGE_AND_ADD_STATE
case SkillBase::EF_AREA_EFFECT_HEAL:
{
std::string strTemp = RecoveryRange( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
strTemp = RecoveryHPMPSP( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_REMOVE_BAD_STATE:
{
std::string strTemp = RemoveState( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_REMOVE_GOOD_STATE:
{
break;
}
case SkillBase::EF_ADD_HP:
{
std::string strTemp = Recovery( s_data, nUseLevel, HP, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_ADD_MP:
{
std::string strTemp = Recovery( s_data, nUseLevel, MP, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_ADD_SP:
{
std::string strTemp = Recovery( s_data, nUseLevel, SP, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_RESURRECTION:
{
std::string strTemp = Resurrection( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_ADD_HP_MP:
{
std::string strTemp = RecoveryHPMP( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_ADD_HP_MP_BY_SUMMON_DAMAGE:
{
std::string strTemp = RecoveryHPMP( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_ADD_HP_MP_BY_SUMMON_DEAD:
{
std::string strTemp = RecoveryHPMP( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_CORPSE_ABSORB:
{
std::string strTemp = AmountAbsorption( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_ADD_HP_MP_BY_STEAL_SUMMON_HP_MP:
{
std::string strTemp = AmountAbsorption( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
if( !strTooltip.empty() )
{
std::string strTemp = AmountAbsorptionRate( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
}
break;
}
case SkillBase::EF_SUMMON:
{
break;
}
case SkillBase::EF_UNSUMMON:
{
break;
}
case SkillBase::EF_TAMING:
{
std::string strTemp = TamingRate( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
case SkillBase::EF_TOGGLE_AURA:
{
break;
}
case SkillBase::EF_ADD_HATE:
{
std::string strTemp = AddAggro( s_data, nUseLevel, bNext, nEnhance );
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
break;
}
}
// std::string strTest;
// strTest = GetHitDemage( s_data, nUseLevel, bNext, nEnhance );
if( !s_data->IsPassive() )
{
std::string strTemp = State(s_data, nUseLevel, bNext, nEnhance); //지속효과가 없는 스킬효과에도 있어서 걍 여기서 일괄 처리
if( !strTemp.empty() ) strTooltip += (strTemp+"<BR>");
}
return strTooltip;
}
/*
std::string SUIDisplayInfo::SkillEffectTooltipText( int nEffectType, int nSkillID, int nUseLevel, int nEnhance, bool bSkillCard )
{
if( nEffectType == 0 ) return std::string( "" );
std::string strTooltip = "<BR>";
SkillBaseEx* s_data = GetSkillDB().GetSkillData( nSkillID );
switch( nEffectType )
{
// 공격력, 마법 공격력
case ATTACK_POWER:
case ATTACK_POWER_ONE:
// case ATTACK_POWER_DIRECTION:
case MAGIC_POWER:
case MAGIC_POWER_ONE:
// case MAGIC_POWER_AREA:
{
int nPower(0), nEnhancePower(0);
if( nEffectType == ATTACK_POWER )
{
nPower = s_data->GetPowerByEnhance( nUseLevel );
nEnhancePower = s_data->GetPowerByEnhance( nUseLevel );
}
if( nEffectType == ATTACK_POWER_ONE ) nPower = s_data->GetPower( nUseLevel );
// if( nEffectType == ATTACK_POWER_DIRECTION ) nPower = s_data->GetPowerDirectByEnhance( nUseLevel );
if( nEffectType == MAGIC_POWER ) nPower = s_data->GetMagicByEnhance( nUseLevel );
if( nEffectType == MAGIC_POWER_ONE ) nPower = s_data->GetMagicOneByEnhance( nUseLevel );
// if( nEffectType == MAGIC_POWER_AREA ) nPower = s_data->GetMagicAreaByEnhance( nUseLevel );
if( nPower != 0 )
{
if( nEffectType == ATTACK_POWER || nEffectType == ATTACK_POWER_ONE )// || nEffectType == ATTACK_POWER_DIRECTION )
strTooltip += S(9007);//"<BR>공격력 ";
else
strTooltip += S(9010);//"<BR>마법공격력 ";
if( nPower > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d", nPower );
}
}
break;
// 흡수률
case ATTACK_ABSORPTION_HPMP:
case MAGIC_ABSORPTION_HPMP:
{
int nAbsorptionHP = 0;
int nAbsorptionMP = 0;
if( nEffectType == ATTACK_ABSORPTION_HPMP || nEffectType == MAGIC_ABSORPTION_HPMP )
{
nAbsorptionHP = s_data->GetPerAbsorptionHP();
nAbsorptionMP = s_data->GetPerAbsorptionMP();
}
if( nAbsorptionHP != 0 )
{
strTooltip += "<BR>HP 흡수율 ";
// strTooltip += S(9008);//"<BR>HP 흡수율 증가 ";
if( nAbsorptionHP > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d%%", nAbsorptionHP );
}
if( nAbsorptionMP != 0 )
{
strTooltip += "<BR>MP 흡수율 ";
// strTooltip += S(9009);//"<BR>MP 흡수율 증가 ";
if( nAbsorptionMP > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d%%", nAbsorptionMP );
}
}
break;
}
// 지속 시간
AR_TIME ar_StateTime = s_data->GetStateTime( nUseLevel );
if( ar_StateTime != 0 )
{
strTooltip += S(9005);//"<BR>지속시간 ";
if( ar_StateTime > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d", ar_StateTime/100 );
}
// 명중보너스
int nHitBonus = s_data->GetHitBonusByEnhance( nUseLevel );
if( nHitBonus != 0 )
{
strTooltip += S(9006);//"<BR>스킬명중 ";
if( nHitBonus > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d", nHitBonus );
}
switch( nEffectType )
{
case ATTACK_INCREASE:
case ATTACK_INCREASE_ONE:
{
// 증폭
int nIncrease = 0;
if( nEffectType == ATTACK_INCREASE ) s_data->GetIncreaseByEnhance( nUseLevel );
if( nEffectType == ATTACK_INCREASE_ONE ) s_data->GetIncreaseOneByEnhance( nUseLevel );
if( nIncrease != 0 )
{
strTooltip += S(9021);//"<BR>공격력 추가 증폭 ";
if( nIncrease > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d%%", nIncrease );
}
}
break;
case STATE_SUCCESS_BYATTACK:
case STATE_SUCCESS_BYATTACK_ONE:
case STATE_SUCCESS_BYMAGIC:
{
// 지속효과 성공률
int nStateSuccess = 0;
if( nEffectType == STATE_SUCCESS_BYATTACK ) s_data->GetStateSuccessByEnhance( nUseLevel );
if( nEffectType == STATE_SUCCESS_BYATTACK_ONE ) s_data->GetStatePowerOneByEnhance( nUseLevel );
if( nEffectType == STATE_SUCCESS_BYMAGIC ) s_data->GetStateMagicPowerByEnhance( nUseLevel );
if( nStateSuccess != 0 )
{
if( nEffectType == STATE_SUCCESS_BYATTACK ) strTooltip += S(9011);//"<BR>성공률 ";
if( nEffectType == STATE_SUCCESS_BYATTACK_ONE ) strTooltip += S(9007);//"<BR>공격력 ";
if( nEffectType == STATE_SUCCESS_BYMAGIC ) strTooltip += S(9010);//"<BR>마법공격력 ";
if( nStateSuccess > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d", nStateSuccess );
}
}
break;
case DEBUFF_STATE_LEVEL:
case BUFF_STATE_LEVEL:
{
// 버프/디버프 성능
int nStateLevel = s_data->GetStatePowerByEnhance( nUseLevel );
if( nStateLevel != 0 )
{
if( nEffectType == DEBUFF_STATE_LEVEL ) strTooltip += S(9012);//"<BR>디버프성능 ";
else strTooltip += S(9022);//"<BR>버프성능 ";
if( nStateLevel > 0 ) strTooltip += "+";
strTooltip += SStringDB::ParseString( 9024, "#@level@#", SStringDB::ToString( nStateLevel ).c_str() );
}
}
break;
case RECOVERY_HP:
case RECOVERY_MP:
case RECOVERY_SP:
{
// 회복량/획복률
int nRecovery = 0;
int nRecoveryStat = 0;
int nRecoveryPer = 0;
int nEnhanceRecovery = 0;
nRecovery = s_data->GetRecovery( nUseLevel );
nRecoveryStat = s_data->GetRecoveryStat( nUseLevel );
nRecoveryPer = s_data->GetRecoveryPer( nUseLevel );
std::string strValue = S(9013);//"<BR>HP";
if( nEffectType == RECOVERY_HP ) strValue = S(9013);//"<BR>HP";
if( nEffectType == RECOVERY_MP ) strValue = S(9014);//"<BR>MP";
if( nEffectType == RECOVERY_SP ) strValue = S(9015);//"<BR>SP";
// 회복량
if( nRecovery != 0 )
{
strTooltip += strValue;
strTooltip += S(9025);//"회복량 ";
if( nRecovery > 0 ) strTooltip += " +";
strTooltip += CStringUtil::StringFormat( "%d", nRecovery );
nEnhanceRecovery = s_data->GetRecoveryByEnhance(nEnhance);
if( nEnhanceRecovery )
strTooltip += CStringUtil::StringFormat( "<#17f39c>(+%d)<#ffffff>", nEnhanceRecovery );
}
// 회복량(%)
if( nRecoveryPer != 0 )
{
strTooltip += strValue;
strTooltip += S(9026);//"회복 증가 ";
if( nRecoveryPer > 0 ) strTooltip += " +";
strTooltip += CStringUtil::StringFormat( "%d%%", nRecoveryPer );
}
if( nRecoveryStat != 0 )
{
strTooltip += strValue;
strTooltip += S(9025);//"추가회복량 ";
if( nRecovery > 0 ) strTooltip += " +마력의 ";
strTooltip += CStringUtil::StringFormat( "%d%%", nRecoveryStat );
}
}
break;
case EXP_INCREASE_BYREVIVAL:
{
int nExpIncrease = s_data->GetExpIncreaseByRevival( nUseLevel );
if( nExpIncrease != 0 )
{
strTooltip += S(9016);//"<BR>부활시 EXP 복구율 ";
if( nExpIncrease > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d%%", nExpIncrease );
}
}
break;
case BODY_ABSORPTION_HPMP_POINT:
{
// HP흡수량 증가
int nAbsorptionHP = s_data->GetAbsorptionHPPointByEnhance( nUseLevel );
if( nAbsorptionHP != 0 )
{
strTooltip += S(9017);//"<BR>HP흡수량 ";
if( nAbsorptionHP > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d", nAbsorptionHP );
}
// MP흡수량 증가
int nAbsorptionMP = s_data->GetAbsorptionMPPointByEnhance( nUseLevel );
if( nAbsorptionMP != 0 )
{
strTooltip += S(9018);//"<BR>MP흡수량 ";
if( nAbsorptionMP > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d", nAbsorptionMP );
}
}
break;
case TAMING_SUCCESS:
{
// 테이밍 성공 증가율
int nTamingSuccess = s_data->GetTamingSuccessByEnhance( nUseLevel );
if( nTamingSuccess != 0 )
{
strTooltip += S(9019);//"<BR>테이밍 성공률 ";
if( nTamingSuccess > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d%%", nTamingSuccess );
}
}
break;
case MP_COST_PERSECOND:
{
// 추가 MP소모량
int nCostMPPerSec = s_data->GetCostMPPerSecondByEnhance( nUseLevel );
if( nCostMPPerSec != 0 )
{
strTooltip += S(9020);//"<BR>매초 MP소모량 ";
if( nCostMPPerSec > 0 ) strTooltip += "+";
strTooltip += CStringUtil::StringFormat( "%d%%", nCostMPPerSec );
}
}
break;
}
std::vector<int> job_list;
GetSkillTreeDB().GetJobList_hasSkill( nSkillID, job_list );
if( !job_list.empty() )
{
strTooltip += "<BR>";
strTooltip += "<BR>";
strTooltip += S(6393);//[사용 가능 직업]
for( unsigned int i(0); job_list.size()>i; i++ )
{
strTooltip += "<BR>";
strTooltip += GetJobDB().GetJobName(job_list[i]);
}
}
return strTooltip;
}
*/
std::string SUIDisplayInfo::ConvertNumString( int value ) const
{
std::string strTemp;
if( value > 0 )
strTemp = "+";
strTemp += CStringUtil::StringFormat( "%d", value );
return strTemp;
}
std::string SUIDisplayInfo::ConvertDBString( int nId, int value, const char* tag/*NULL*/, const char* c_key/*"#@value@#"*/, bool bPlus/*true*/ ) const
{
std::string strTemp, strDB;
if( value > 0 && bPlus )
strTemp = "+";
if(tag) strTemp += CStringUtil::StringFormat( "%d%s", value, tag );
else strTemp += CStringUtil::StringFormat( "%d", value );
strDB += SR( nId, c_key, strTemp.c_str() );
return strDB;
}
std::string SUIDisplayInfo::ConvertDBString( int nId, float value, int decimal/*1*/, const char* tag/*NULL*/, const char* c_key/*"#@value@#"*/, bool bPlus/*true*/ ) const
{
std::string strTemp, strDB;
if( value > 0.f && bPlus )
strTemp = "+";
std::string strDcm;
if(tag) strDcm = CStringUtil::StringFormat( "%%.%df%s", decimal, tag );
else strDcm = CStringUtil::StringFormat( "%%.%df", decimal );
strTemp += CStringUtil::StringFormat( strDcm.c_str(), value );
strDB += SR( nId, c_key, strTemp.c_str() );
return strDB;
}
std::string SUIDisplayInfo::ConvertDBStringTime( int nId, float value, bool bPlus/*true*/ ) const
{
std::string strTemp, strDB;
if( value > 0.f && bPlus )
strTemp = "+";
strTemp += GetTimeString(value);
strDB += SR( nId, "#@value@#", strTemp.c_str() );
return strDB;
}
std::string SUIDisplayInfo::GetCardSkillTooltip( int nItemID, int nSkillID, bool bDetail, unsigned char byEnhance/* = 0*/, unsigned char byLevel/* = 1*/, XFlag<int> xFlag/* = XFlag<int>()*/ ) const
{
std::string strCardToolTip;
strCardToolTip = CStringUtil::StringFormat( "%s", GetItemName( nItemID, false, byEnhance, byLevel, xFlag ).c_str() );
strCardToolTip += GetEnhanceSkillTooltipText(nItemID, nSkillID, byEnhance, false);
strCardToolTip += GetEnhanceSkillTooltipText(nItemID, nSkillID, byEnhance+1, true);
return strCardToolTip;
}
void SUIDisplayInfo::EraseJobList( std::vector<int>& JobList, int Min, int Max ) const
{
std::vector<int>::iterator it;
it = JobList.begin();
while( it != JobList.end() )
{
if( Min <= (*it) && (*it) <= Max )
{
it = JobList.erase(it);
continue;
}
++it;
}
}
bool SUIDisplayInfo::IsJob( std::vector<int>& JobList, int JobID ) const
{
int size(JobList.size());
for( int i(0); i<size; ++i )
{
if( JobList[i] == JobID )
return true;
}
return false;
}
void SUIDisplayInfo::FillterJobList( std::vector<int>& JobList ) const
{
if( JobList.empty() ) return;
bool bBANGRANGJA = IsJob( JobList, JobInfo::BANGRANGJA );
bool bTUSA(false); bool bJUSULSA(false); bool bYASUSA(false);
bool bJUNSA(false); bool bGUNGSA(false); bool bMADOSA(false); bool bMATUSA(false); bool bMASUSA(false);
if( bBANGRANGJA ) //가이아 기초직업 이면 가이아 해당 모든 직업 삭제
{
EraseJobList( JobList, JobInfo::TUSA, JobInfo::CHOHONSA );
}
else
{
bTUSA = IsJob( JobList, JobInfo::TUSA );
if( bTUSA ) //1차 투사
{
EraseJobList( JobList, JobInfo::JUNSA, JobInfo::GUNGSA );
EraseJobList( JobList, JobInfo::GUMSUNG, JobInfo::DAISASU );
}
else //2차 전사와 궁사
{
bJUNSA = IsJob( JobList, JobInfo::JUNSA );
if( bJUNSA ) EraseJobList( JobList, JobInfo::GUMSUNG, JobInfo::GIGONGSA );
bGUNGSA = IsJob( JobList, JobInfo::GUNGSA );
if( bGUNGSA ) EraseJobList( JobList, JobInfo::DAISASU, JobInfo::DAISASU );
}
bJUSULSA = IsJob( JobList, JobInfo::JUSULSA );
if( bJUSULSA ) //1차 주술사
{
EraseJobList( JobList, JobInfo::MADOSA, JobInfo::MATUSA );
EraseJobList( JobList, JobInfo::BIJUNSULSA, JobInfo::JUNGRYUNGSULSA );
}
else //2차 마도사와 마투사
{
bMADOSA = IsJob( JobList, JobInfo::MADOSA );
if( bMADOSA ) EraseJobList( JobList, JobInfo::JUNGRYUNGSULSA, JobInfo::JUNGRYUNGSULSA );
bMATUSA = IsJob( JobList, JobInfo::MATUSA );
if( bMATUSA ) EraseJobList( JobList, JobInfo::BIJUNSULSA, JobInfo::BIJUNSULSA );
}
bYASUSA = IsJob( JobList, JobInfo::YASUSA );
if( bYASUSA ) //1차 야수사
{
EraseJobList( JobList, JobInfo::MASUSA, JobInfo::MASUSA );
EraseJobList( JobList, JobInfo::CHOHONSA, JobInfo::CHOHONSA );
}
else //2차 마수사
{
bMASUSA = IsJob( JobList, JobInfo::MASUSA );
if( bMASUSA ) EraseJobList( JobList, JobInfo::CHOHONSA, JobInfo::CHOHONSA );
}
}
bool bGAID = IsJob( JobList, JobInfo::GAID );
bool bFIGHTER(false); bool bCLERIC(false); bool bTAMER(false);
bool bNENIGHT(false); bool bWARRIOR(false); bool bMAGE(false); bool bPRIST(false); bool bBAIDER(false);
if( bGAID ) //데바 기초직업 이면 가이아 해당 모든 직업 삭제
{
EraseJobList( JobList, JobInfo::FIGHTER_JOP, JobInfo::PANCER );
}
else
{
bFIGHTER = IsJob( JobList, JobInfo::FIGHTER_JOP );
if( bFIGHTER ) //1차 파이터
{
EraseJobList( JobList, JobInfo::NENIGHT, JobInfo::WARRIOR );
EraseJobList( JobList, JobInfo::PALADIN, JobInfo::PALADIN );
}
else //2차 나이트
{
bNENIGHT = IsJob( JobList, JobInfo::NENIGHT );
if( bNENIGHT ) EraseJobList( JobList, JobInfo::PALADIN, JobInfo::PALADIN );
}
bCLERIC = IsJob( JobList, JobInfo::CLERIC );
if( bCLERIC ) //1차 클래릭
{
EraseJobList( JobList, JobInfo::MAGE, JobInfo::PRIST );
EraseJobList( JobList, JobInfo::MINISTER, JobInfo::SAIGE );
}
else //2차 매이지, 프리스트
{
bMAGE = IsJob( JobList, JobInfo::MAGE );
if( bMAGE ) EraseJobList( JobList, JobInfo::MINISTER, JobInfo::SHAININGRANGER );
bPRIST = IsJob( JobList, JobInfo::PRIST );
if( bPRIST ) EraseJobList( JobList, JobInfo::HIGHTPRIST, JobInfo::HIGHTPRIST );
}
bTAMER = IsJob( JobList, JobInfo::TAMER );
if( bTAMER ) //1차 태이머
{
EraseJobList( JobList, JobInfo::BAIDER, JobInfo::BAIDER );
EraseJobList( JobList, JobInfo::PANCER, JobInfo::PANCER );
}
else //2차 브리더
{
bBAIDER = IsJob( JobList, JobInfo::BAIDER );
if( bBAIDER ) EraseJobList( JobList, JobInfo::PANCER, JobInfo::PANCER );
}
}
bool bSTEPPER = IsJob( JobList, JobInfo::STEPPER );
bool bSTRIDER(false); bool bMAGICIAN(false); bool bSUMMONER(false);
bool bASSASSIN(false); bool bRANGER(false); bool bSORCERER(false); bool bDARKMAGICIAN(false); bool bBATTLESUMMONER(false);
if( bSTEPPER ) //아수라 기초직업 이면 가이아 해당 모든 직업 삭제
{
EraseJobList( JobList, JobInfo::STRIDER, JobInfo::SPIRITSUMMONER );
}
else
{
bSTRIDER = IsJob( JobList, JobInfo::STRIDER );
if( bSTRIDER ) //1차 스트라이더
{
EraseJobList( JobList, JobInfo::ASSASSIN, JobInfo::RANGER );
EraseJobList( JobList, JobInfo::DARKCHAICER, JobInfo::DARKSTRIKER );
}
else //2차 어새신, 래인저
{
bASSASSIN = IsJob( JobList, JobInfo::ASSASSIN );
if( bASSASSIN ) EraseJobList( JobList, JobInfo::DARKSTRIKER, JobInfo::DARKSTRIKER );
bRANGER = IsJob( JobList, JobInfo::RANGER );
if( bRANGER ) EraseJobList( JobList, JobInfo::DARKCHAICER, JobInfo::DARKCHAICER );
}
bMAGICIAN = IsJob( JobList, JobInfo::MAGICIAN_JOP );
if( bMAGICIAN ) //1차 매지션
{
EraseJobList( JobList, JobInfo::SORCERER, JobInfo::DARKMAGICIAN );
EraseJobList( JobList, JobInfo::NECROMANCER, JobInfo::DARKPRIST );
}
else //2차 소서러, 다크매지션
{
bSORCERER = IsJob( JobList, JobInfo::SORCERER );
if( bSORCERER ) EraseJobList( JobList, JobInfo::NECROMANCER, JobInfo::DARKPRIST );
bDARKMAGICIAN = IsJob( JobList, JobInfo::DARKMAGICIAN );
if( bDARKMAGICIAN ) EraseJobList( JobList, JobInfo::ARKSORCERER, JobInfo::ARKSORCERER );
}
bSUMMONER = IsJob( JobList, JobInfo::SUMMONER_JOP );
if( bSUMMONER ) //1차 서모너
{
EraseJobList( JobList, JobInfo::BATTLESUMMONER, JobInfo::BATTLESUMMONER );
}
else //2차 배틀서모너
{
bBATTLESUMMONER = IsJob( JobList, JobInfo::BATTLESUMMONER );
if( bBATTLESUMMONER ) EraseJobList( JobList, JobInfo::ARKSORCERER, JobInfo::SPIRITSUMMONER );
}
}
}
std::string SUIDisplayInfo::GetEnhanceSkillTooltipText( int nItemID, int nSkillID, int nEnhance, bool bNext ) const
{
std::string strTooltip;
SkillBaseEx* s_data = GetSkillDB().GetSkillData( nSkillID );
if( s_data == NULL ) return strTooltip;
//카드 설명 // 나중에 디비에서 찾아서 GetStringDB().GetString(번호) 로 고칠것
if( !bNext )
{
strTooltip = SR( 38, "#@skill_name@#", GetStringDB().GetString( s_data->GetNameID() ) ); /*"<BR>%s 의 성능을 향상 시킨다"*/
//TODO: 테섭 우선 적용
//스킬카드 툴팁 추가
//2009-06-09 : hunee
const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( nItemID );
strTooltip += GetStringDB().GetString( pItemBase->nToolTipID );
//카드 사용직업
std::vector<int> job_list;
GetSkillTreeDB().GetJobList_hasSkill( nSkillID, job_list );
FillterJobList(job_list);
if( !job_list.empty() )
{
// 자신의 이전 직업 현재 직업 얻기
int nMyJobList[SPlayerInfo::JOB_INDEX_MAX+1] = { 0, };
int nLastIdx = 0;
for( ; nLastIdx < SPlayerInfo::JOB_INDEX_MAX; ++nLastIdx )
{
int nJopID = m_PlayerInfoMgr.GetOldJobID(nLastIdx);
if( nJopID )
{
nMyJobList[nLastIdx] = nJopID;
}
else
{
break;
}
}
nMyJobList[nLastIdx] = m_PlayerInfoMgr.GetJobID();
strTooltip += S(6393);//"사용 직업 : "
for( unsigned int i(0); job_list.size()>i; i++ )
{
if( i ) strTooltip += ", ";
// 이전 직업을 포함해서 사용할 수 있는 직업인가?
bool bWearable = false;
for( int j = 0; j < SPlayerInfo::JOB_INDEX_MAX+1; ++j )
{
if( nMyJobList[j] == 0 )
break;
if( nMyJobList[j] == job_list[i] )
{
bWearable = true;
break;
}
}
if( bWearable == false )
{
strTooltip += "<#ff0000>";
}
strTooltip += GetJobDB().GetJobName(job_list[i]);
if( bWearable == false )
{
strTooltip += "<#ffffff>";
}
}
strTooltip += S(9027);
}
job_list.clear();
}
// 카드효과 툴팁
bool bCardEffect = false;
std::string strCardEffectTooltip;
// 반줄 띠우기
// 강화에 따른 기타 정보들 ======================================= 강화정보만..
// 소모 MP
int nCostMP = s_data->GetCostMPByEnhance( nEnhance );
if( nCostMP != 0 )
{
strCardEffectTooltip += ConvertDBString( 9001, nCostMP );//"<BR>MP소모 "
bCardEffect = true;
}
// 캐스팅 딜레이
int nCastDelay = s_data->GetCastDelayByEnhancePer( nEnhance );
float asdf = s_data->GetCastDelayByEnhance( nEnhance );
if( nCastDelay != 0 )
{
strCardEffectTooltip += ConvertDBString( 9002, nCastDelay, "%" );
bCardEffect = true;
}
// 쿨타임
int nCoolTime = s_data->GetCoolTimeByEnhancePer( nEnhance );
if( nCoolTime != 0 )
{
strCardEffectTooltip += ConvertDBString( 9003, nCoolTime, "%" );
bCardEffect = true;
}
// value 에 의한 값 =================================
// 효과 타입 ====================================
int nEffectType = s_data->GetEffectType();
// #2.1.2.12
_STRING_TABLE_INFO* stringTable = GetStringDB().GetStringData( GameRule::SKILL_ENHANCE_TOOLTIP_STRING_OFFSET + nEffectType );
if( stringTable )
{
std::string efx = stringTable->pStrDesc;
if( !efx.empty() )
{
rp::CSkillEx skillEx( s_data );
skillEx.level( 1 );
skillEx.enhance( nEnhance );
skillEx.userAttribute( m_PlayerInfoMgr.GetPlayerInfo().GetAttribute(), m_PlayerInfoMgr.GetPlayerInfo().GetItemAttribute() );
m_pSkillSubject->setSkill( skillEx );
rp::fx_expr::Compiler compiler( *m_pSkillSubject );
compiler.addTokens( "()+-*/&,$" );
compiler.addEscape( "'" );
compiler.compile( efx.begin(), efx.end() );
std::string result( compiler.result()->toString() );
if( !result.empty() )
{
strCardEffectTooltip += "<br><size:10>"; // sonador #2.3.1.32
strCardEffectTooltip += result;
bCardEffect = true;
}
}
else
{
SDEBUGLOG("%s 가 stringTable에 없습니다.",stringTable->pStrDesc);
}
}
// 명중보너스
int nHitBonus = s_data->GetHitBonusByEnhance( nEnhance );
if( nHitBonus != 0 )
{
strCardEffectTooltip += ConvertDBString( 9006, nHitBonus );//"<BR>스킬명중 "
bCardEffect = true;
}
// 부여지속효과레벨
int nStateEffect = s_data->GetStateLevelByEnhance( nEnhance );
if( nStateEffect != 0 )
{
if( nStateEffect > 0 )
{
strCardEffectTooltip += ConvertDBString( 9004, nStateEffect );//"<BR>MP소모 "
bCardEffect = true;
}
}
// 지속 시간
AR_TIME ar_StateTime = s_data->GetStateSecondByEnhance( nEnhance );
if( ar_StateTime != 0 )
{
if( ar_StateTime > 0 )
{
strCardEffectTooltip += ConvertDBStringTime( 9005, (float)(ar_StateTime/100.f) );//"<BR>지속시간
bCardEffect = true;
}
}
if( bCardEffect )
{
if( bNext )
{
strTooltip += S(9023);//<size:12><#ffffff>[다음 강화단계의 효과]<size:10><#ffffff>
}
strTooltip += strCardEffectTooltip;
}
return strTooltip;
}
unsigned char SUIDisplayInfo::GetObjectType( AR_HANDLE handle )
{
SGame* pGame = m_pGameManager->GetActiveGame();
if( !pGame || pGame->GetGameType() != GAME_TYPE_WORLD )
return NULL;
return pGame->GetGameObjectType(handle);
}
// { [sonador][7.7.12] 전투 관련 시스템 메시지 오류 수정 및 추가
// sonador 1.10.3 전투 메시지 출력 처리 구조 개선
namespace rp {
// Identification, caster and target is Friend or foe
namespace ff {
struct FFID
{
enum TYPE { PLAYER, CREATURE, FOE, ANY };
struct Avatar
{
Avatar( ) : type( PLAYER ) { }
bool IsLocal( ) const { return type != FOE; }
bool IsLocalPlayer( ) const { return type == PLAYER; }
bool IsLocalCreature( ) const { return type == CREATURE; }
bool IsFoe( ) const { return type == FOE; }
TYPE type;
};
Avatar caster;
Avatar target;
};
namespace private_ {
struct FFMsgImpl
{
virtual ~FFMsgImpl() {}
int get( const FFID& ffid )
{
int msg = msgMatrix[ ffid.caster.type ][ ffid.target.type ];
if( !msg ) msg = defaultMsg;
return msg;
}
protected:
FFMsgImpl() : defaultMsg( 0 )
{
::memset( msgMatrix, 0, sizeof( msgMatrix ) );
}
void set( FFID::TYPE caster, FFID::TYPE target, int msg )
{
if( caster == FFID::ANY && target == FFID::ANY )
{
for( int i = 0; i < FFID::ANY; ++i )
for( int j = 0; j < FFID::ANY; ++j )
msgMatrix[ i ][ j ] = msg;
}
else if( caster == FFID::ANY )
{
for( int i = 0; i < FFID::ANY; ++i )
msgMatrix[ i ][ target ] = msg;
}
else if( target == FFID::ANY )
{
for( int i = 0; i < FFID::ANY; ++i )
msgMatrix[ caster ][ i ] = msg;
}
else
msgMatrix[ caster ][ target ] = msg;
}
void default( int msg )
{
defaultMsg = msg;
}
protected:
int msgMatrix[ FFID::ANY ][ FFID::ANY ];
int defaultMsg;
};
} // namespace private_
struct FFMsg
{
FFMsg() : impl( 0 ) {}
~FFMsg() { SAFE_DELETE( impl ); }
void set( private_::FFMsgImpl* ffmsg ) { SAFE_DELETE( impl ); impl = ffmsg; }
int get( const FFID& ffid ) { if( impl ) return impl->get( ffid ); return 0; }
private_::FFMsgImpl* operator->() { return impl; }
const private_::FFMsgImpl* operator->() const { return impl; }
private:
private_::FFMsgImpl* impl;
};
// dispatch system message by ffid.
namespace disp {
#define FFMSG_BEGIN( msg )\
struct msg : public private_::FFMsgImpl {\
msg( ) : private_::FFMsgImpl() {
#define FFMSG_END } };
FFMSG_BEGIN( AttackAddDmg )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_BATTLE_DAMAGE_SUPPLEMENT );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_ADDITION_DAMAGE );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_ADDDAMAGE );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_ADDDAMAGE );
FFMSG_END
FFMSG_BEGIN( AttackCritical )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_BATTLE_DAMAGE002 );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_CRITICAL_DAMAGE );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_CRITICAL );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_CRITICAL );
FFMSG_END
FFMSG_BEGIN( AttackBlock )
set( FFID::FOE , FFID::PLAYER , SYS_MSG_SKILL_DEFENSE_DAMAGE );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BLOCK_DEFENSE_DAMAGE );
FFMSG_END
FFMSG_BEGIN( AttackPerfectBlock )
set( FFID::FOE , FFID::PLAYER , SYS_MSG_SKILL_DEFENSE_PERFECT );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BLOCK_DEFENSE_PERPECT );
FFMSG_END
FFMSG_BEGIN( AttackNormal )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_BATTLE_DAMAGE_GENERAL );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_NORMALATTACK );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_GENERAL );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_GENERAL );
FFMSG_END
FFMSG_BEGIN( AttackMiss )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_ATTACK_MISS );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CRAETURE_ATTACK_AVOID );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_ATTACK_AVOID );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_ATTACK_CRAETURE_AVOID );
FFMSG_END
FFMSG_BEGIN( NonAttackDebuff )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_USE_DEBUFF );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_ATTACKDEBUFF );
FFMSG_END
FFMSG_BEGIN( NonAttackBuff )
set( FFID::PLAYER , FFID::CREATURE , SYS_MSG_SKILL_USE_BUFF );
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_USE_BUFF );
FFMSG_END
FFMSG_BEGIN( SkillSummonUnsummon )
set( FFID::PLAYER , FFID::ANY , SYS_MSG_SKILL_USE );
set( FFID::CREATURE , FFID::ANY , SYS_MSG_CREATURE_SKILL_USE );
FFMSG_END
FFMSG_BEGIN( SkillDebuff )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_USE_DEBUFF );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_ATTACKDEBUFF );
FFMSG_END
FFMSG_BEGIN( SkillBuff )
set( FFID::PLAYER , FFID::CREATURE , SYS_MSG_SKILL_USE_BUFF );
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_USE_BUFF );
FFMSG_END
FFMSG_BEGIN( SkillCritical )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_DAMAGE_CRITICAL );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_SKILL_DAMAGE_CRITICAL );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_CRITICAL );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_CRITICAL );
FFMSG_END
// 2010.09.06 - prodongi
FFMSG_BEGIN( SkillCriticalAddDmg )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_DAMAGE_CRITICAL_ADD_DAMAGE );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_SKILL_DAMAGE_CRITICAL_ADD_DAMAGE );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_CRITICAL_ADD_DAMAGE );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_CRITICAL_ADD_DAMAGE );
FFMSG_END
FFMSG_BEGIN( SkillBlock )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_BATTLE_DAMAGE_GENERAL );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_SKILL_DAMAGE );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_SKILL_DEFENSE_DAMAGE );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BLOCK_DEFENSE_DAMAGE );
FFMSG_END
FFMSG_BEGIN( SkillPerfectBlock )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_MONSTER_SKILLPERFECT_BLOCK );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_SKILLPERFECT_BLOCK );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_SKILL_DEFENSE_PERFECT );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BLOCK_DEFENSE_PERPECT );
FFMSG_END
FFMSG_BEGIN( SkillMissPhysical )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_MISS );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_SKILL_MISS );
FFMSG_END
FFMSG_BEGIN( SkillMissMagical )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_MAGIC_MISS );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_MAGIC_MISS );
FFMSG_END
FFMSG_BEGIN( SkillHarmful )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_USE_DAMAGE );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_SKILL_DAMAGE );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_GENERAL );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_GENERAL );
FFMSG_END
// 2010.09.01 - prodongi
FFMSG_BEGIN( SkillHarmfulAddDmg )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_USE_ADD_DAMAGE );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_CREATURE_SKILL_ADD_DAMAGE );
set( FFID::FOE , FFID::PLAYER , SYS_MSG_BATTLE_BEATTACK_ADD_DAMAGE );
set( FFID::FOE , FFID::CREATURE , SYS_MSG_CREATURE_BATTLE_BEATTACK_ADD_DAMAGE );
FFMSG_END
FFMSG_BEGIN( SkillSuccessAddState )
set( FFID::CREATURE , FFID::ANY , SYS_MSG_CREATURE_USE_BUFF );
FFMSG_END
FFMSG_BEGIN( SkillSuccessRmvState )
default( SYS_MSG_DISABLE_DEBUFF );
FFMSG_END
FFMSG_BEGIN( SkillSuccessTurnOn )
default( SYS_MSG_USE_BUFF );
FFMSG_END
FFMSG_BEGIN( SkillSuccessTurnOff )
default( SYS_MSG_DISABLE_BUFF );
FFMSG_END
FFMSG_BEGIN( SkillFailPhysical )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_MISS );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_SKILL_MISS );
FFMSG_END
FFMSG_BEGIN( SkillFailMagical )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_MAGIC_MISS );
set( FFID::CREATURE , FFID::FOE , SYS_MSG_MAGIC_MISS );
FFMSG_END
FFMSG_BEGIN( SkillFailForcechip )
set( FFID::PLAYER , FFID::FOE , SYS_MSG_DEBUFF_FAIL );
FFMSG_END
FFMSG_BEGIN( SkillAddHpSelf )
set( FFID::PLAYER , FFID::PLAYER , SYS_MSG_RECOVER_HP );
FFMSG_END
FFMSG_BEGIN( SkillAddMpSelf )
set( FFID::PLAYER , FFID::PLAYER , SYS_MSG_RECOVER_MP );
FFMSG_END
FFMSG_BEGIN( SkillAddSpSelf )
set( FFID::PLAYER , FFID::PLAYER , SYS_MSG_RECOVER_SP );
FFMSG_END
FFMSG_BEGIN( SkillAddHpMpSpOtherNoRegion )
set( FFID::PLAYER , FFID::CREATURE , SYS_MSG_SKILL_USE );
set( FFID::PLAYER , FFID::FOE , SYS_MSG_SKILL_USE );
FFMSG_END
} // namespace disp
} // namespace ff
// register tag decorator for each system messge.
namespace tag {
const char* SOMEONE_NAME = "#@someone_name@#";
const char* CASTER_NAME = "#@caster_name@#";
const char* TARGET_NAME = "#@target_name@#";
const char* CREATURE_NAME = "#@creature_name@#";
const char* DAMAGE = "#@damage@#";
const char* ADD_DAMAGE = "#@add_damage@#";
const char* SKILL_NAME = "#@skill_name@#";
const char* SKILL_LEVEL = "#@skill_level@#";
const char* HP = "#@hp@#";
const char* MP = "#@mp@#";
const char* SP = "#@sp@#";
// AziaMafia Fix String 96
const char* ST_A = "#@a@#";
const char* ST_D = "#@d@#";
const char* ST_T = "#@t@#";
const char* ST_S = "#@s@#";
#define PIPELINE_MAP_BEGIN \
TagPipe::TagPipe() \
{ \
int msgId = 0; \
worker_team_t* WorkerTeam = 0;
#define PIPELINE( msg ) \
if( msgId != 0 ) \
this->addPipeLine( msgId, WorkerTeam ); \
msgId = msg; \
WorkerTeam = new worker_team_t;
#define WORKER( fn, tag ) \
WorkerTeam->push_back( Worker( &TagPipe::fn, tag ) );
#define PIPELINE_MAP_END \
if( msgId != 0 ) \
this->addPipeLine( msgId, WorkerTeam ); \
}
PIPELINE_MAP_BEGIN
PIPELINE( SYS_MSG_CREATURE_ADDITION_DAMAGE )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onOnlyDamage , DAMAGE )
WORKER( onAddDamage , ADD_DAMAGE )
PIPELINE( SYS_MSG_CREATURE_CRITICAL_DAMAGE )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onTotalDamage , DAMAGE )
// AziaMafia Fix String 96
WORKER(onCasterName , ST_A)
WORKER(onTargetName , ST_T)
WORKER(onTotalDamage , ST_D)
PIPELINE( SYS_MSG_CREATURE_NORMALATTACK )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onTotalDamage , DAMAGE )
// AziaMafia Fix String 96
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
WORKER(onTotalDamage, ST_D)
PIPELINE( SYS_MSG_CREATURE_ATTACKDEBUFF )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
// AziaMafia Fix String 96
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_CREATURE_SKILLDEBUFF )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
PIPELINE( SYS_MSG_CREATURE_SKILLPERFECT_BLOCK )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onTargetName , SOMEONE_NAME )
// AziaMafia Fix String 96
WORKER(onCasterName , ST_A)
WORKER(onTargetName , ST_T)
PIPELINE( SYS_MSG_MONSTER_SKILLDAMAGE_CHARACTER )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamage , DAMAGE )
PIPELINE( SYS_MSG_MONSTER_SKILLDAMAGE_CREATURE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamage , DAMAGE )
PIPELINE( SYS_MSG_MONSTER_SKILLPERFECT_BLOCK )
WORKER( onTargetName , TARGET_NAME )
// AziaMafia Fix String 96
WORKER(onTargetName, ST_T)
PIPELINE( SYS_MSG_BATTLE_DAMAGE_SUPPLEMENT )
WORKER( onTargetName , TARGET_NAME )
WORKER( onOnlyDamage , DAMAGE )
WORKER( onAddDamage , ADD_DAMAGE )
PIPELINE( SYS_MSG_BATTLE_BEATTACK_ADDDAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onOnlyDamage , DAMAGE )
WORKER( onAddDamage , ADD_DAMAGE )
PIPELINE( SYS_MSG_CREATURE_BATTLE_BEATTACK_ADDDAMAGE )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onOnlyDamage , DAMAGE )
WORKER( onAddDamage , ADD_DAMAGE )
PIPELINE( SYS_MSG_BATTLE_DAMAGE002 )
WORKER( onTargetName , TARGET_NAME )
WORKER( onTotalDamage , DAMAGE )
// AziaMafia Fix String 96
WORKER(onTotalDamage, ST_D)
WORKER(onTargetName, ST_T)
PIPELINE( SYS_MSG_BATTLE_BEATTACK_CRITICAL )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
// AziaMafia Fix String 96
WORKER(onTotalDamage, ST_D)
WORKER(onCasterName, ST_A)
PIPELINE( SYS_MSG_CREATURE_BATTLE_BEATTACK_CRITICAL )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
// AziaMafia Fix String 96
WORKER(onTotalDamage, ST_D)
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
PIPELINE( SYS_MSG_SKILL_DEFENSE_DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
PIPELINE( SYS_MSG_CREATURE_BLOCK_DEFENSE_DAMAGE )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
PIPELINE( SYS_MSG_SKILL_DEFENSE_PERFECT )
WORKER( onCasterName , SOMEONE_NAME )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
PIPELINE( SYS_MSG_CREATURE_BLOCK_DEFENSE_PERPECT )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
PIPELINE( SYS_MSG_BATTLE_DAMAGE_GENERAL )
WORKER( onTargetName , TARGET_NAME )
WORKER( onTotalDamage , DAMAGE )
//Azia Mafia Fix String 96
WORKER(onTargetName, ST_T)
WORKER(onTotalDamage, ST_D)
PIPELINE( SYS_MSG_BATTLE_BEATTACK_GENERAL )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
//Azia Mafia Fix String 96
WORKER(onTargetName, ST_A)
WORKER(onTotalDamage, ST_D)
PIPELINE( SYS_MSG_CREATURE_BATTLE_BEATTACK_GENERAL )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
//Azia Mafia Fix String 96
WORKER(onTotalDamage, ST_D)
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
//PIPELINE( SYS_MSG_ATTACK_MISS )
PIPELINE( SYS_MSG_CRAETURE_ATTACK_AVOID )
WORKER( onCasterName , CREATURE_NAME )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
PIPELINE( SYS_MSG_ATTACK_AVOID )
WORKER( onCasterName , SOMEONE_NAME )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
PIPELINE( SYS_MSG_ATTACK_CRAETURE_AVOID )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
PIPELINE( SYS_MSG_USE_DEBUFF )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
//Azia Mafia Fix String 96
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_SKILL_USE_BUFF )
WORKER( onTargetName , SOMEONE_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
//Azia Mafia Fix String 96
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_SKILL_USE )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
//Azia Mafia Fix String 96
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_CREATURE_SKILL_USE )
WORKER( onCasterName , CREATURE_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_SKILL_DAMAGE_CRITICAL )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamage , DAMAGE )
//Azia Mafia Fix String 96
WORKER(onSkillDamage, ST_D)
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_CREATURE_SKILL_DAMAGE_CRITICAL )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamage , DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
//Azia Mafia Fix String 96
WORKER(onSkillDamage, ST_D)
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
//PIPELINE( SYS_MSG_SKILL_MISS )
//PIPELINE( SYS_MSG_MAGIC_MISS )
PIPELINE( SYS_MSG_SKILL_USE_DAMAGE )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamage , DAMAGE )
//Azia Mafia Fix String 96
WORKER(onSkillDamage, ST_D)
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_CREATURE_SKILL_DAMAGE )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamage , DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
//Azia Mafia Fix String 96
WORKER(onSkillDamage, ST_D)
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_CREATURE_USE_BUFF )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onCasterName , CREATURE_NAME )
//Azia Mafia Fix String 96
WORKER(onCasterName, ST_A)
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_DISABLE_DEBUFF )
WORKER( onSkillName , SKILL_NAME )
//Azia Mafia Fix String 96
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_USE_BUFF )
WORKER( onSkillName , SKILL_NAME )
//Azia Mafia Fix String 96
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_DISABLE_BUFF )
WORKER( onSkillName , SKILL_NAME )
//Azia Mafia Fix String 96
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_DEBUFF_FAIL )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
//Azia Mafia Fix String 96
WORKER(onTargetName, ST_T)
WORKER(onSkillName, ST_S)
PIPELINE( SYS_MSG_RECOVER_HP )
WORKER( onIncreaseHp , HP )
//Azia Mafia Fix String 96
WORKER(onIncreaseHp, ST_D)
PIPELINE( SYS_MSG_RECOVER_MP )
WORKER( onIncreaseMp , MP )
//Azia Mafia Fix String 96
WORKER(onIncreaseMp, ST_D)
PIPELINE( SYS_MSG_RECOVER_SP )
WORKER( onIncreaseSp , SP )
//Azia Mafia Fix String 96
WORKER(onIncreaseSp, ST_D)
// 2010.09.01 - prodongi
PIPELINE( SYS_MSG_SKILL_USE_ADD_DAMAGE )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamageSubAddDmg, DAMAGE )
WORKER( onSkillAddDamage, ADD_DAMAGE )
PIPELINE( SYS_MSG_CREATURE_SKILL_ADD_DAMAGE )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamageSubAddDmg , DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillAddDamage, ADD_DAMAGE )
PIPELINE( SYS_MSG_BATTLE_BEATTACK_ADD_DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
WORKER( onSkillAddDamage, ADD_DAMAGE )
PIPELINE( SYS_MSG_CREATURE_BATTLE_BEATTACK_ADD_DAMAGE )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
WORKER( onSkillAddDamage, ADD_DAMAGE )
// 2010.09.06 - prodongi
PIPELINE( SYS_MSG_SKILL_DAMAGE_CRITICAL_ADD_DAMAGE )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamageSubAddDmg, DAMAGE )
WORKER( onSkillAddDamage, ADD_DAMAGE)
PIPELINE( SYS_MSG_CREATURE_SKILL_DAMAGE_CRITICAL_ADD_DAMAGE )
WORKER( onSkillLevel , SKILL_LEVEL )
WORKER( onSkillDamageSubAddDmg, DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTargetName , TARGET_NAME )
WORKER( onSkillName , SKILL_NAME )
WORKER( onSkillAddDamage, ADD_DAMAGE)
PIPELINE( SYS_MSG_BATTLE_BEATTACK_CRITICAL_ADD_DAMAGE )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
WORKER( onSkillAddDamage, ADD_DAMAGE )
PIPELINE( SYS_MSG_CREATURE_BATTLE_BEATTACK_CRITICAL_ADD_DAMAGE )
WORKER( onTargetName , CREATURE_NAME )
WORKER( onCasterName , SOMEONE_NAME )
WORKER( onTotalDamage , DAMAGE )
WORKER( onSkillAddDamage, ADD_DAMAGE )
PIPELINE_MAP_END
TagPipe::~TagPipe()
{
rp::wipe_assoc( mPipeLine );
}
void TagPipe::addPipeLine( int msg, worker_team_t* workerTeam )
{
pipeline_t::iterator found = mPipeLine.find( msg );
if( found != mPipeLine.end() )
{
assert( 0 && "Message is duplicated!!" );
rp::safe_delete( workerTeam );
}
else
{
mPipeLine.insert( std::make_pair( msg, workerTeam ) );
}
}
void TagPipe::run( int msg, DecoArg& arg )
{
pipeline_t::iterator found = mPipeLine.find( msg );
if( found != mPipeLine.end() )
{
worker_team_t& WorkerTeam = *found->second;
worker_team_t::iterator end = WorkerTeam.end();
for( worker_team_t::iterator it = WorkerTeam.begin(); it != end; ++it )
(this->*((*it).Fn))( (*it).Tag, arg );
}
}
void TagPipe::onCasterName( const char* tag, DecoArg& arg )
{
if( arg.damage )
XStringUtil::Replace( arg.msg, tag, arg.damage->strCasterName.c_str( ) );
}
void TagPipe::onTargetName( const char* tag, DecoArg& arg )
{
if( arg.damage )
XStringUtil::Replace( arg.msg, tag, arg.damage->strTargetName.c_str( ) );
}
void TagPipe::onTotalDamage( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
std::string dmg;
int dmgAmount = arg.damage->skillresult.GetDamage() > arg.damage->nDamage ? arg.damage->skillresult.GetDamage() : arg.damage->nDamage;
XStringUtil::Format( dmg, "%d", dmgAmount );
XStringUtil::Replace( arg.msg, tag, dmg.c_str( ) );
}
}
void TagPipe::onAddDamage( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
int addDmg = 0;
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
addDmg += arg.damage->elemental_damage[ n ];
std::string dmg;
XStringUtil::Format( dmg, "%d", addDmg );
XStringUtil::Replace( arg.msg, tag, dmg.c_str( ) );
}
}
void TagPipe::onOnlyDamage( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
int addDmg = 0;
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
addDmg += arg.damage->elemental_damage[ n ];
std::string dmg;
XStringUtil::Format( dmg, "%d", arg.damage->nDamage - addDmg ); // sonador #2.3.1.3 데미지 출력 메시지 오류 수정
XStringUtil::Replace( arg.msg, tag, dmg.c_str( ) );
}
}
void TagPipe::onSkillDamage( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
std::string dmg;
XStringUtil::Format( dmg, "%d", arg.damage->skillresult.GetDamage( ) );
XStringUtil::Replace( arg.msg, tag, dmg.c_str( ) );
}
}
void TagPipe::onSkillName( const char* tag, DecoArg& arg )
{
if( arg.skill )
XStringUtil::Replace( arg.msg, tag, S( arg.skill->GetNameID( ) ) );
}
void TagPipe::onSkillLevel( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
std::string lv;
XStringUtil::Format( lv, "%d", arg.damage->nSkillLevel );
XStringUtil::Replace( arg.msg, tag, lv.c_str( ) );
}
}
void TagPipe::onIncreaseHp( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
std::string inc;
if( arg.damage->skillresult.GetType( ) == SkillResult::ADD_HP_MP_SP )
{
XStringUtil::Format( inc, "%d", arg.damage->skillresult.add_hp_mp_sp.nIncHP );
}
else
{
XStringUtil::Format( inc, "%d", arg.damage->skillresult.add_hp.nIncHP );
}
XStringUtil::Replace( arg.msg, tag, inc.c_str( ) );
}
}
void TagPipe::onIncreaseMp( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
std::string inc;
if( arg.damage->skillresult.GetType( ) == SkillResult::ADD_HP_MP_SP )
{
XStringUtil::Format( inc, "%d", arg.damage->skillresult.add_hp_mp_sp.nIncMP );
}
else
{
XStringUtil::Format( inc, "%d", arg.damage->skillresult.add_hp.nIncHP );
}
XStringUtil::Replace( arg.msg, tag, inc.c_str( ) );
}
}
void TagPipe::onIncreaseSp( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
std::string inc;
if( arg.damage->skillresult.GetType( ) == SkillResult::ADD_HP_MP_SP )
{
XStringUtil::Format( inc, "%d", arg.damage->skillresult.add_hp_mp_sp.nIncSP );
}
else
{
XStringUtil::Format( inc, "%d", arg.damage->skillresult.add_hp.nIncHP );
}
XStringUtil::Replace( arg.msg, tag, inc.c_str( ) );
}
}
// 2010.09.01 - prodongi
void TagPipe::onSkillAddDamage( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
int addDmg = 0;
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
addDmg += arg.damage->skillresult.damage.elemental_damage[ n ];
std::string dmg;
XStringUtil::Format( dmg, "%d", addDmg );
XStringUtil::Replace( arg.msg, tag, dmg.c_str( ) );
}
}
// 2010.09.01 - prodongi
void TagPipe::onSkillDamageSubAddDmg( const char* tag, DecoArg& arg )
{
if( arg.damage )
{
int addDmg = 0;
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
addDmg += arg.damage->skillresult.damage.elemental_damage[ n ];
std::string dmg;
XStringUtil::Format( dmg, "%d", arg.damage->skillresult.GetDamage( ) - addDmg );
XStringUtil::Replace( arg.msg, tag, dmg.c_str( ) );
}
}
} // namespace tag
} // namespace rp
// }
void SUIDisplayInfo::DamageSysMsg( SMSG_DAMAGE* pDamage )
{
// Fraun performance tweak
SkillResult* pSkillResult = &pDamage->skillresult;
SkillBaseEx* s_data = GetSkillDB().GetSkillData( pDamage->nSkillID );
if( pSkillResult->GetType() != SkillResult::NOT_USE )
{
if( s_data == NULL || (s_data->IsSystemSkill() && ISNT_AUTO_ATTACK_CHIP_SKILL_ID(pDamage->nSkillID)))
{
AddSystemMessage(CStringUtil::StringFormat("[Error] Skill data is NULL! Skill ID: %d!\n", pDamage->nSkillID).c_str(), 255);
_oprint("[Error] Skill data is NULL! Skill ID: %d!\n", pDamage->nSkillID);
return;
}
}
bool bCasterIsPlayer = GetObjectType(pDamage->attacker_handle) == TS_ENTER::GAME_PLAYER;
bool bCasterIsCreature = GetObjectType(pDamage->attacker_handle) == TS_ENTER::GAME_SUMMON;
bool bTargetIsPlayer = GetObjectType(pDamage->target_handle) == TS_ENTER::GAME_PLAYER;
bool bTargetIsCreature = GetObjectType(pDamage->target_handle) == TS_ENTER::GAME_SUMMON;
bool bChainCasterPlayer = GetObjectType(pDamage->chainCaster) == TS_ENTER::GAME_PLAYER; /// 2011.05.16 - prodongi
bool bChainCasterCreature = GetObjectType(pDamage->chainCaster) == TS_ENTER::GAME_SUMMON; /// 2011.05.16 - prodongi
// [sonador][7.7.12] 전투 관련 시스템 메시지 오류 수정 및 추가
using rp::ff::FFID;
using rp::ff::FFMsg;
using namespace rp::ff::disp;
FFID ffid;
FFMsg ffmsg;
std::string strDecoArg;
rp::tag::DecoArg arg(strDecoArg);
arg.damage = pDamage;
arg.skill = s_data;
// identification, friend or foe...
{
if( bCasterIsPlayer )
{
if( m_PlayerInfoMgr.IsLocalPlayer( pDamage->attacker_handle ) )
ffid.caster.type = FFID::PLAYER;
else
ffid.caster.type = FFID::FOE;
}
else if( bCasterIsCreature )
{
if( m_CreatureSlotMgr.IsExistSummonedCreature( pDamage->attacker_handle ) )
ffid.caster.type = FFID::CREATURE;
else
ffid.caster.type = FFID::FOE;
}
else if (bChainCasterPlayer)
{
if( m_PlayerInfoMgr.IsLocalPlayer( pDamage->chainCaster ) )
ffid.caster.type = FFID::PLAYER;
else
ffid.caster.type = FFID::FOE;
}
else if( bChainCasterCreature )
{
if( m_CreatureSlotMgr.IsExistSummonedCreature( pDamage->chainCaster ) )
ffid.caster.type = FFID::CREATURE;
else
ffid.caster.type = FFID::FOE;
}
else
{
ffid.caster.type = FFID::FOE;
}
if( bTargetIsPlayer )
{
if( m_PlayerInfoMgr.IsLocalPlayer( pDamage->target_handle ) )
ffid.target.type = FFID::PLAYER;
else
ffid.target.type = FFID::FOE;
}
else if( bTargetIsCreature )
{
if( m_CreatureSlotMgr.IsExistSummonedCreature( pDamage->target_handle ) )
ffid.target.type = FFID::CREATURE;
else
ffid.target.type = FFID::FOE;
}
else
{
ffid.target.type = FFID::FOE;
}
}
switch( pSkillResult->GetType() )
{
case SkillResult::NOT_USE:
{
int nDamage = pDamage->nDamage;
int nAddDamage = 0;
if( pDamage->attack_action & TS_ATTACK_EVENT::ATTACK_ATTACK )
{
if( nDamage > 0 )
{
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
nAddDamage += pDamage->elemental_damage[ n ];
//추가 뎀지
if( nAddDamage > 0 )
{
ffmsg.set( new AttackAddDmg );
goto _SHOWMSG_;
}
//크리티컬 공격
if( pDamage->flag & TS_ATTACK_EVENT::FLAG_CRITICAL )
{
ffmsg.set( new AttackCritical );
}
//블럭
else if( pDamage->flag & TS_ATTACK_EVENT::FLAG_BLOCK )
{
ffmsg.set( new AttackBlock );
}
//일반 공격
else
{
ffmsg.set( new AttackNormal );
}
goto _SHOWMSG_;
}
// sonador 7.7.12 전투 관련 시스템 메시지 오류 수정 및 추가
else if( pDamage->flag & TS_ATTACK_EVENT::FLAG_PERFECT_BLOCK ) //퍼팩트 블럭
{
ffmsg.set( new AttackPerfectBlock );
}
else
{
//그룹핑 작업 되야 함.
//공격 미스
ffmsg.set( new AttackMiss );
}
}
else
{
if( s_data )
{
// 데미지 지속효과 스킬일 경우 : // %s에게 %s %dLv을 부여했습니다.
if( s_data->IsHarmful() && s_data->GetStateId() > 0 )
{
ffmsg.set( new NonAttackDebuff );
}
// 좋은 지속효과 스킬일 경우
else if( !s_data->IsHarmful() && s_data->GetStateId() > 0 )
{
ffmsg.set( new NonAttackBuff );
}
}
}
}
break;
case SkillResult::DAMAGE:
case SkillResult::MAGIC_DAMAGE:
case SkillResult::DAMAGE_WITH_KNOCK_BACK:
case SkillResult::CHAIN_DAMAGE:
case SkillResult::CHAIN_MAGIC_DAMAGE:
{
if( !s_data ) return;
// 소환 스킬(서먼/언서먼) : // %s 스킬 %dLv을 사용했습니다.
if( pDamage->nSkillID == c_nSummonSkillID || pDamage->nSkillID == c_nUnSummonSkillID )
{
ffmsg.set( new SkillSummonUnsummon );
}
// 기타 : 크리티컬/블락/정상 데미지
else
{
// 데미지 지속효과 스킬일 경우 : // %s에게 %s %dLv을 부여했습니다.
if( s_data->IsHarmful() && s_data->GetStateId() > 0 )
{
ffmsg.set( new SkillDebuff );
}
// 좋은 지속효과 스킬일 경우
else if( !s_data->IsHarmful() && s_data->GetStateId() > 0 )
{
ffmsg.set( new SkillBuff );
}
int msgid = ffmsg.get( ffid );
if( msgid )
{
AddSystemMessage(S(msgid));
m_BattleMsgPipeLine.run( msgid, arg ); // sonador 1.10.3 전투 메시지 출력 처리 구조 개선
}
if( pSkillResult->damage.flag & SkillResult::CRITICAL )
{
// 2010.09.06 - prodongi
//ffmsg.set( new SkillCritical );
int addDamage = 0;
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
addDamage += pDamage->skillresult.damage.elemental_damage[ n ];
if (0 < addDamage)
ffmsg.set(new SkillCriticalAddDmg);
else
ffmsg.set(new SkillCritical);
}
else if( pSkillResult->damage.flag & SkillResult::BLOCK )
{
// 일반 블럭 : 공격을 블럭해서 %d의 데미지를 입었습니다
ffmsg.set( new SkillBlock );
}
else if( pSkillResult->damage.flag & SkillResult::PERFECT_BLOCK )
{
ffmsg.set( new SkillPerfectBlock );
}
// 스킬 실패
else if( pSkillResult->damage.flag & SkillResult::MISS )
{
// 전투스킬
if( s_data->IsPhysicalSkill() )
{
ffmsg.set( new SkillMissPhysical );
}
// 마법스킬
else
{
ffmsg.set( new SkillMissMagical );
}
}
else if( s_data->IsHarmful() ) // 데미지를 주는 스킬
{
int addDamage = 0;
for( int n = 0; n < CreatureElemental::ElementalType::COUNT; ++n )
addDamage += pDamage->skillresult.damage.elemental_damage[ n ];
if (0 < addDamage)
{
ffmsg.set( new SkillHarmfulAddDmg );
}
else
ffmsg.set( new SkillHarmful );
}
}
}
break;
case SkillResult::RESULT:
{
if( !s_data ) return;
if( pSkillResult->result.bResult ) // 성공
{
switch(pSkillResult->result.success_type)
{
case SkillResult::ADD_STATE:
ffmsg.set( new SkillSuccessAddState );
break;
case SkillResult::REMOVE_STATE:
ffmsg.set( new SkillSuccessRmvState );
break;
case SkillResult::TURN_ON:
ffmsg.set( new SkillSuccessTurnOn );
break;
case SkillResult::TURN_OFF:
ffmsg.set( new SkillSuccessTurnOff );
break;
}
}
else // 실패
{
// 2010.06.15 - prodongi
//if( pDamage->nSkillID == FORCE_CHIP_SKILL_ID )
if( IS_AUTO_ATTACK_CHIP_SKILL_ID(pDamage->nSkillID))
{
ffmsg.set( new SkillFailForcechip );
break;
}
if( s_data->IsPhysicalSkill() )
{
ffmsg.set( new SkillFailPhysical );
}
else
{
ffmsg.set( new SkillFailMagical );
}
}
}
break;
case SkillResult::ADD_HP:
case SkillResult::CHAIN_HEAL: /// 2011.03.24 - prodongi
{
if( pSkillResult->add_hp.nIncHP > 0 )
{
// 자신한테 사용
ffmsg.set( new SkillAddHpSelf );
if( !ffmsg.get( ffid ) && pDamage->skill_type != SMSG_DAMAGE::REGION_FIRE_SKILL )
{ // 대상에게 사용
ffmsg.set( new SkillAddHpMpSpOtherNoRegion );
}
}
}
break;
case SkillResult::ADD_MP:
{
if( pSkillResult->add_hp.nIncHP > 0 )
{
ffmsg.set( new SkillAddMpSelf );
if( !ffmsg.get( ffid ) && pDamage->skill_type != SMSG_DAMAGE::REGION_FIRE_SKILL )
{
ffmsg.set( new SkillAddHpMpSpOtherNoRegion );
}
}
}
break;
case SkillResult::ADD_HP_MP_SP:
{
// 기획팀에 추가해달라고 요청해야함
if( pSkillResult->add_hp_mp_sp.nIncHP > 0 )
{
ffmsg.set( new SkillAddHpSelf );
}
if( pSkillResult->add_hp_mp_sp.nIncMP > 0 )
{
ffmsg.set( new SkillAddMpSelf );
}
if( pSkillResult->add_hp_mp_sp.nIncSP > 0 )
{
ffmsg.set( new SkillAddSpSelf );
}
if( !ffmsg.get( ffid ) && pDamage->skill_type != SMSG_DAMAGE::REGION_FIRE_SKILL )
ffmsg.set( new SkillAddHpMpSpOtherNoRegion );
}
break;
}
_SHOWMSG_:
int msgid = ffmsg.get( ffid );
if( msgid )
{
AddSystemMessage(GetStringDB().GetString( msgid ));
m_BattleMsgPipeLine.run( msgid, arg ); // sonador 1.10.3 전투 메시지 출력 처리 구조 개선
}
}
void SUIDisplayInfo::StateDamageSysMsg( SIMSG_UI_DISPLAY_STATE_DMG_SYS_MSG* pStateDmg )
{
// Fraun performance tweak
switch( pStateDmg->nSystemMsg )
{
case SYS_MSG_SKILL_DAMAGE_DOT:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@target_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@damage@#", pStateDmg->nValue ).c_str(), 6);
break;
case SYS_MSG_BATTLE_BEATTACK_DOT:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@damage@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_CREATURE_BATTLE_BEATTACK_DOT:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@creature_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@damage@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_TOTAL_DAMAGE_MP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@damage@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_CREATURE_TOTAL_DAMAGEL_MP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@creature_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@damage@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_BATTLE_TOTAL_DAMAGE_MP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@target_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@damage@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_TOTAL_RECOVERY_HP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@hp@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_TOTAL_RECOVERY_MP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@mp@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_CREATURE_TOTAL_RECOVERY_HP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@creature_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@hp@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_CREATURE_TOTAL_RECOVERY_MP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@creature_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@mp@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_TARGET_TOTAL_RECOVERY_HP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@target_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@hp@#", pStateDmg->nValue ).c_str(), 4);
break;
case SYS_MSG_TARGET_TOTAL_RECOVERY_MP:
AddSystemMessage(SR( pStateDmg->nSystemMsg, "#@target_name@#", pStateDmg->strTargetNamme.c_str(), "#@skill_name@#", pStateDmg->strStateName.c_str(), "#@skill_level@#", pStateDmg->nLevel, "#@mp@#", pStateDmg->nValue ).c_str(), 4);
break;
}
}
const char* SUIDisplayInfo::GetStringMessage( int nTextID )
{
return GetStringDB().GetString(nTextID);
}