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

502 lines
14 KiB
C++

/// 2011.02.08 - prodongi
#include "stdafx.h"
#include "KUIControlStatic.h"
#include "KUIControlGauge.h"
#include "CreatureBase.h"
#include "SGameManager.h"
#include "CharacterInfo/SUICharacterInfoWnd.h"
#include "CharacterInfo/SUICharacterInfoSubBasicWnd.h"
#include "CharacterInfo/SUICharacterInfoSubAddedWnd.h"
#include "SUIDisplayInfo.h"
#include "SGameMessage.h"
//#include "SGameMessageUI.h"
#include "SJobDB.h"
#include "SStringDB.h"
#include "SSummonSlotMgr.h"
#include "SPlayerInfoMgr.h"
#include "SMessengerMgr.h"
#include "SChatType.h"
#include "SUISysMsgDefine.h"
#include "SDebug_Util.h"
//#include "SUIUtil.h"
#include "KUITabControl.h"
#include "Arena\\ArenaSystem.h"
#include "SGameSystem.h"
extern SGameSystem* g_pCurrentGameSystem;
namespace
{
// const int c_nSysMenu = 56; // 왼쪽 메뉴 바 width
const DWORD c_dwGaugeFillTime = 1000;
};
SUICharacterInfoWnd::SUICharacterInfoWnd( SGameManager* pGameManager, SUIDisplayInfo* pDisplayInfo )
: SUIWnd( pGameManager ), m_pDisplayInfo(pDisplayInfo), m_curSubWnd(SUB_BASIC)
{
};
SUIWnd* SUICharacterInfoWnd::CreateWnd(const char *szFile, KUIWndManager *pWndManager, KPoint kPos, int nWindowID)
{
SUIWnd::CreateWnd(szFile, pWndManager, kPos, nWindowID);
/// create sub windows
createSubWnd<SUICharacterInfoSubBasicWnd>(pWndManager, SUB_BASIC, "window_player_character_info_sub_basic.nui", SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHARINFO_SUB_BASIC);
createSubWnd<SUICharacterInfoSubAddedWnd>(pWndManager, SUB_ADDED, "window_player_character_info_sub_added.nui", SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHARINFO_SUB_ADDED);
return this;
}
bool SUICharacterInfoWnd::InitControls( KPoint kPos )
{
SetCustomMovingRect( GetChild("titlebar")->GetRect() ); // 타이틀 바 선택 영역, 이동위해 클릭 Area
return SUIWnd::InitControls( kPos );
}
bool SUICharacterInfoWnd::InitData( bool bReload )
{
refreshGuildName();
initFrameHeightData();
return SUIWnd::InitData(bReload);
}
void SUICharacterInfoWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd )
{
SUIWnd::OnNotifyUIWindowOpen(bOpen);
if( bOpen )
{
m_pGameManager->StartSound( "ui_popup_window01.wav" );
setCurSubWnd(m_curSubWnd);
m_subWnd[SUB_BASIC]->refreshExpand(true);
m_subWnd[SUB_ADDED]->refreshAll();
}
}
void SUICharacterInfoWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch( nMessage )
{
case KUI_MESSAGE::KBUTTON_CLICK:
{
if( ::_stricmp( lpszControlID, "button_close" ) == 0 )
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHARINFO, false) );
}
if (_stricmp(lpszControlID, "tab_basic_01") == 0)
{
setCurSubWnd(SUB_BASIC);
}
else if (_stricmp(lpszControlID, "tab_added_01") == 0)
{
setCurSubWnd(SUB_ADDED);
}
else if (_stricmp(lpszControlID, "button_equip") == 0)
{
/// 장비창에서 y축 위치를 장비창의 높이만큼 빼주기 때문에(왜 이런가??), 여시서는 bottom을 넣어준다(+2는 임시,,,)
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_MOVE( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_EQUIPMENT, GetBoundingRect().right-1, GetBoundingRect().bottom + 2) );
m_pGameManager->PostMsgAtDynamic( new SIMSG_TOGGLE_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_EQUIPMENT));
}
}
break;
case KUI_MESSAGE::KGENWND_MOVE: // 윈도우 이동
{
LimitMoveWnd(); // 게임 외부로 나가지 못하게 제한
}
break;
}
SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
void SUICharacterInfoWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
switch( pMsg->nType )
{
case MSG_CHANGE_NAME :
{
refreshJobName();
}
break;
case IMSG_UI_SEND_DATA:
{
SIMSG_UI_SEND_DATA *pData = (SIMSG_UI_SEND_DATA *)pMsg;
if( pData->m_strString == "guild_update" )
{
pMsg->bUse = true;
refreshGuildName();
}
else if( pData->m_dwData == IMSG_GUILD_ICON || pData->m_dwData == IMSG_GUILD_ICON_REFRESH )
{
pMsg->bUse = true;
if( m_GuildMgr.GetGuildID() == (int)pData->m_nNumber.getAmount() )
{
refreshGuildMark(pData->m_strText);
}
}
}
break;
case IMSG_GUILD_ICON_DESTROY :
{
pMsg->bUse = true;
refreshGuildMark("");
}
break;
case IMSG_GUILD_ICON_LEAVE :
{
pMsg->bUse = true;
refreshGuildMark("");
}
case MSG_LOGIN:
{
SMSG_LOGIN* pLoginMsg = dynamicCast<SMSG_LOGIN*>(pMsg);
refreshHP( pLoginMsg->hp, pLoginMsg->max_hp );
refreshMP( pLoginMsg->mp, pLoginMsg->max_mp );
pMsg->bUse = true;
}
break;
case IMSG_UI_TARGET_STAT:
{
SIMSG_UI_TARGET_STAT* pUISyncMsg = dynamicCast<SIMSG_UI_TARGET_STAT*>(pMsg);
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
if( pUISyncMsg->handle != m_PlayerInfoMgr.GetPlayerHandle() )
return;
if( pUISyncMsg->m_nMode == SIMSG_UI_TARGET_STAT::USE_DEF ||
pUISyncMsg->m_nMode == SIMSG_UI_TARGET_STAT::USE_HPMP )
{
refreshHP ( pUISyncMsg->m_nVar1, pUISyncMsg->m_nVar3 );
refreshMP ( pUISyncMsg->m_nVar2, pUISyncMsg->m_nVar4 );
}
else if( pUISyncMsg->m_nMode == SIMSG_UI_TARGET_STAT::USE_EXP )
{
refreshExp ();
}
}
break;
case IMSG_UI_FOCUS:
{
m_pManager->SetFocus(this);
pMsg->bUse = true;
}
break;
case MSG_PROPERTY:
{
SMSG_PROPERTY* pPropertyMsg = (SMSG_PROPERTY*)pMsg;
switch( pPropertyMsg->nPropertyType )
{
case SMSG_PROPERTY::PROPERTY_JOB_LEVEL:
case SMSG_PROPERTY::PROPERTY_NAME:
case SMSG_PROPERTY::PROPERTY_LEVEL:
case SMSG_PROPERTY::PROPERTY_JOB: refreshJobName(); break;
case SMSG_PROPERTY::PROPERTY_EXP:
case SMSG_PROPERTY::PROPERTY_JP: refreshExp(); break;
case SMSG_PROPERTY::PROPERTY_PK_COUNT:
case SMSG_PROPERTY::PROPERTY_DK_COUNT:
case SMSG_PROPERTY::PROPERTY_MORAL: m_subWnd[SUB_ADDED]->refreshPropensity(); break;
}
pMsg->bUse = true;
}
break;
case MSG_STATUS_CHANGE:
{
m_subWnd[SUB_ADDED]->refreshPropensity();
pMsg->bUse = true;
}
break;
case IMSG_INSTANCE_GAME_SCORE:
{
m_subWnd[SUB_ADDED]->refreshGameScore((SMSG_INSTANCE_GAME_SCORE *)pMsg);
pMsg->bUse = true;
}
break;
case MSG_INSTANCE_GAME_SCORE_REQUEST:
{
SMSG_INSTANCE_GAME_SCORE_REQUEST* msg = dynamicCast<SMSG_INSTANCE_GAME_SCORE_REQUEST*>(pMsg);
if (msg)
{
if (msg->activeAddedWnd)
{
if (SUB_ADDED != m_curSubWnd)
{
setCurSubWnd(SUB_ADDED, true);
}
else
{
m_subWnd[SUB_ADDED]->refreshGameScore(NULL);
}
}
else
{
m_subWnd[SUB_ADDED]->refreshGameScore(NULL);
}
}
pMsg->bUse = true;
}
break;
case MSG_LEVEL_UPDATE:
{
refreshJobName();
pMsg->bUse = true;
}
break;
case MSG_STAT_INFO:
{
SMSG_STAT_INFO* pStatInfoMsg = (SMSG_STAT_INFO*)pMsg;
if( pStatInfoMsg->type == TS_SC_STAT_INFO::TOTAL )
{
refreshBaseStat();
refreshBattleStat();
}
else if( pStatInfoMsg->type == TS_SC_STAT_INFO::BY_ITEM )
{
refreshBaseStat();
refreshBattleStat();
refreshBaseItemStat( pStatInfoMsg->stat );
refreshBattleItemStat( pStatInfoMsg->attribute );
}
pMsg->bUse = true;
}
break;
case IMSG_UI_TITLE_SET_MAIN: // 2012. 5. 21 - marine 주 호칭 이름 갱신
{
SIMSG_UI_TITLE_SET_MAIN *pTitle = dynamicCast<SIMSG_UI_TITLE_SET_MAIN *>(pMsg);
GetChild("character_title_text")->SetCaption(CStringUtil::StringFormat("<font:font_01><#7b2e00><vcenter><hcenter><size:9>%s",pTitle->strName.c_str()).c_str());
}
break;
case MSG_BATTLE_ARENA_BATTLE_INFO:
case MSG_BATTLE_ARENA_LEAVE:
updateName();
break;
}
}
void SUICharacterInfoWnd::refreshHP( int nHP, int nMaxHP )
{
int nPer = static_cast<int>(m_pDisplayInfo->GetPercent( nHP, nMaxHP ));
/// 2011.07.22 - prodongi
SetChildCaption( "static_hp_value" , CStringUtil::StringFormat( "<font:font_01><b><hcenter><vcenter><size:8>%d / %d", nHP, nMaxHP ).c_str() );
SetChildCaption( "static_hp_percent", CStringUtil::StringFormat( "<font:font_01><size:8><left><#ffffff><shadow>%d%s", nPer, "%" ).c_str() );
KUIControlGauge* pGaugeHP = dynamicCast<KUIControlGauge*>(GetChild( "gauge_hp" ));
if( pGaugeHP )
{
m_pDisplayInfo->RefreshGaugeAndStatic( pGaugeHP, nHP, nMaxHP, nPer, c_dwGaugeFillTime );
// 게이지 남은 양에 따라 텍스처 바꿔줌 // 2012.02.03 - servantes
setHPGaugeTexture( nPer, pGaugeHP, 11 );
}
}
void SUICharacterInfoWnd::refreshMP( int nMP, int nMaxMP )
{
int nPer = static_cast<int>(m_pDisplayInfo->GetPercent( nMP, nMaxMP ));
/// 2011.07.22 - prodongi
SetChildCaption( "static_mp_value" , CStringUtil::StringFormat( "<font:font_01><b><hcenter><vcenter><size:8>%d / %d", nMP, nMaxMP ).c_str() );
SetChildCaption( "static_mp_percent", CStringUtil::StringFormat( "<font:font_01><size:8><left><#ffffff><shadow>%d%s", nPer, "%" ).c_str() );
KUIControlGauge* pGaugeMP = dynamicCast<KUIControlGauge*>(GetChild( "gauge_mp" ));
if( pGaugeMP )
m_pDisplayInfo->RefreshGaugeAndStatic( pGaugeMP, nMP, nMaxMP, nPer, c_dwGaugeFillTime );
}
void SUICharacterInfoWnd::refreshJP()
{
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
std::string jpStr;
jpToString(info.GetJP(), jpStr);
SetChildCaption( "mainframe_jp" , CStringUtil::StringFormat("<font:font_01><size:9><left>%s", jpStr.c_str()).c_str());
}
void SUICharacterInfoWnd::refreshExp()
{
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
refreshJP();
double fPer = ((double)(info.GetCurExp())/info.GetMaxExp())*100.f;
/// 2011.07.22 - prodongi
SetChildCaption( "static_exp_value" , CStringUtil::StringFormat( "<font:font_01><b><hcenter><vcenter><size:8>%I64d / %I64d", info.GetCurExp(), info.GetMaxExp() ).c_str() );
SetChildCaption( "static_exp_percent", CStringUtil::StringFormat( "<font:font_01><size:8><left><#ffffff><shadow>%02.02f%s", fPer, "%" ).c_str() );
KUIControlGauge* pGauge = dynamicCast<KUIControlGauge*>(GetChild( "gauge_exp" ));
if( pGauge )
m_pDisplayInfo->RefreshGaugeAndStaticByPercentage( pGauge, (int)fPer, 0 ); // #2.3.1.31
}
// 잡
void SUICharacterInfoWnd::refreshJobName()
{
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
SetChildCaption( "static_lv_value" , CStringUtil::StringFormat( "<font:font_01><size:9><left>%d", info.GetLevel() ).c_str() );
SetChildCaption( "mainframe_jlv_number", CStringUtil::StringFormat( "<font:font_01><size:9><left>%d", info.GetJLv() ).c_str() );
refreshJP();
updateName();
SetChildCaption( "character_jobname_text", CStringUtil::StringFormat( "<font:font_01><hcenter><#ffffff><size:9><vcenter>%s", info.GetJobName() ).c_str() );
/// 칭호는 아직 작업 전이므로 빈 공백으로 해 놓는다
SetChildCaption( "character_title_text", CStringUtil::StringFormat( "<font:font_01><#7b2e00><vcenter><hcenter><size:9>%s", "" ).c_str());
//EXP
refreshExp();
// 잡 아이콘
KUIControlIconStatic* pJobIcon = dynamicCast<KUIControlIconStatic*>(GetChild( "character_job_icon" ));
if( pJobIcon )
{
pJobIcon->SetIcon( c_szDEF_SPR_NAME, GetJobDB().GetJobIconName(info.GetJobID()) );
pJobIcon->SetTooltip(NULL);
}
}
// 길드
void SUICharacterInfoWnd::refreshGuildName()
{
SetChildCaption( "character_placeguildname_text", CStringUtil::StringFormat( "<font:font_01><vcenter><hcenter><size:9>%s", m_GuildMgr.GetGuildName() ).c_str() );
}
void SUICharacterInfoWnd::refreshGuildMark(std::string const& iconName)
{
KUIControlIconStatic* wnd = dynamicCast<KUIControlIconStatic*>(GetChild("character_guild_icon"));
if (iconName.empty())
{
wnd->SetIcon("ui_frame.spr", "common_mark_icon_none");
}
else
{
wnd->SetIcon("ui_frame.spr", iconName.c_str());
}
}
void SUICharacterInfoWnd::refreshBaseStat()
{
m_subWnd[SUB_BASIC]->refreshBaseStat();
}
void SUICharacterInfoWnd::refreshBaseItemStat(CreatureStat const& stat)
{
m_subWnd[SUB_BASIC]->refreshBaseItemStat(stat);
}
void SUICharacterInfoWnd::refreshBattleStat()
{
m_subWnd[SUB_BASIC]->refreshBattleStat();
}
void SUICharacterInfoWnd::refreshBattleItemStat(CreatureAttribute const& attribute)
{
m_subWnd[SUB_BASIC]->refreshBattleItemStat(attribute);
}
void SUICharacterInfoWnd::setCurSubWnd(int type, bool updateHead)
{
m_subWnd[SUB_BASIC]->SetShow(false);
m_subWnd[SUB_ADDED]->SetShow(false);
/// 2011.05.26 - prodongi
if (updateHead && m_curSubWnd != type)
{
KUITabControlSheet* tabSheet = dynamicCast<KUITabControlSheet*>(GetChild("tab_character_01"));
if (tabSheet) tabSheet->SetSelectHead((DWORD)type);
}
m_curSubWnd = type;
m_subWnd[type]->SetShow(true);
///
if (SUB_BASIC == type)
{
SetChildAsTop("tab_added_01");
SetChildAsTop("window_player_character_info_sub_basic");
SetChildAsTop("tab_basic_01");
setExpand(m_subWnd[SUB_BASIC]->isExpand());
}
else if (SUB_ADDED == type)
{
SetChildAsTop("tab_basic_01");
SetChildAsTop("window_player_character_info_sub_added");
SetChildAsTop("tab_added_01");
setExpand(m_subWnd[SUB_ADDED]->isExpand());
m_pGameManager->PostMsgAtDynamic( new SMSG_INSTANCE_GAME_SCORE_REQUEST() );
}
}
void SUICharacterInfoWnd::setExpand(bool expand)
{
KRect r;
int fhType = (!expand) ? FH_ORI : FH_EXPAND;
sFrameHeight fh;
memcpy(&fh, m_frameHeight + fhType, sizeof (fh));
KUIWnd* wnd;
/// inframe
wnd = GetChild("inframe");
r = wnd->GetRect();
r.bottom = r.top + fh.m_in;
wnd->Resize(r);
/// outframe
wnd = GetChild("outframe");
r = wnd->GetRect();
r.bottom = r.top + fh.m_out - 2; /// 왜 -2만큼 해야 이미지가 안 짤리는지 잘 모르겠음,,,
wnd->Resize(r);
/// wnd
r = GetRect();
r.bottom = r.top + fh.m_wnd;
Resize(r);
if (expand)
LimitMoveWnd();
}
void SUICharacterInfoWnd::initFrameHeightData()
{
KUIWnd* wnd;
wnd = GetChild("inframe");
m_frameHeight[FH_ORI].m_in = wnd->GetRect().GetHeight();
wnd = GetChild("outframe");
m_frameHeight[FH_ORI].m_out = wnd->GetRect().GetHeight();
m_frameHeight[FH_ORI].m_wnd = GetRect().GetHeight();
wnd = GetChild("inframe_01");
m_frameHeight[FH_EXPAND].m_in = wnd->GetRect().GetHeight();
wnd = GetChild("outframe_01");
m_frameHeight[FH_EXPAND].m_out = wnd->GetRect().GetHeight();
m_frameHeight[FH_EXPAND].m_wnd = GetRect().GetHeight() + (m_frameHeight[FH_EXPAND].m_out - m_frameHeight[FH_ORI].m_out);
}
void SUICharacterInfoWnd::updateName()
{
sArenaSystem* arenaSystem = g_pCurrentGameSystem->getArenaSystem();
SetName(arenaSystem->getPlayerName(&m_PlayerInfoMgr));
}
void SUICharacterInfoWnd::SetName(char const* name)
{
SetChildCaption( "static_character_name", CStringUtil::StringFormat( "<font:font_01><left><size:9><#ffffff><hcenter>%s", name ).c_str() );
}