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

699 lines
19 KiB
C++

#include "stdafx.h"
#include <toolkit/XStringUtil.h>
#include "KUIControlGauge.h"
#include "KUIControlExpGauge.h"
#include "KUIControlFuryGauge.h"
#include "KUIControlStatic.h"
#include "SUIMainFrameWnd.h"
#include "SUIDisplayInfo.h"
#include "SGameManager.h"
#include "SGameMessage.h"
//#include "SGameMessageUI.h"
#include "SGameAvatarEx.h"
#include "SGameSystem.h"
#include "Util.h"
#include "SGame.h"
#include "SJobDB.h"
//#include "SUIUtil.h"
#include "SStringDB.h"
#include "SPlayerInfoMgr.h"
#include "Arena\\ArenaSystem.h"
#include "ContentStruct.h"
#include "SGameLobbyDefine.h"
extern SGameSystem * g_pCurrentGameSystem;
using namespace CStringUtil;
namespace
{
const DWORD c_dwGaugeFillTime = 1000;
const char* c_szFURY_BAR = "mainframe_furybar";
const char* c_szHP_BAR = "mainframe_hpbar";
const char* c_szMP_BAR = "mainframe_mpbar";
const char* c_szEXP_BAR = "mainframe_expbar";
const char* c_szPlayName = "static_name";
const char* c_szLevel = "mainframe_level";
const char* c_szJLV_NUM = "mainframe_jlv_number";
const char* c_szJOB_NAME = "player_text_job_01";
const char* c_szK_FONT = "mainframe_k_font";
const char* c_szJP = "mainframe_jp";
const char* c_szHP_VALUE = "static_hp_value";
const char* c_szMP_VALUE = "static_mp_value";
const char* c_szClan = "playert_text_clan_01";
const char* c_szServerName = "static_server_text_01";
#ifdef _COUNTRY_CN_
const char * c_szGage_Stress = "static_gage_stress";
const char * c_szGageOff01 = "gage_off_01";
const char * c_szGage_green_01 = "gage_green_01";
const char * c_szGage_em_01 = "gage_em_01";
const unsigned short c_nMaxGageOff = 20;
const char * c_szGageOff[c_nMaxGageOff] =
{
"gage_off_02",
"gage_off_03",
"gage_off_04",
"gage_off_05",
"gage_off_06",
"gage_off_07",
"gage_off_08",
"gage_off_09",
"gage_off_10",
"gage_off_11",
"gage_off_12",
"gage_off_13",
"gage_off_14",
"gage_off_15",
"gage_off_16",
"gage_off_17",
"gage_off_18",
"gage_off_19",
"gage_off_20",
"gage_off_21",
};
const AR_TIME c_arLimitTime_LV1 = 1080000;
const AR_TIME c_arLimitTime_LV2 = 1800000;
#endif
};
//-----------------------------------------------------------------------------------------------------------------
// 생성자
//-----------------------------------------------------------------------------------------------------------------
SUIMainFrameWnd::SUIMainFrameWnd( SGameManager* pGameManager, SUIDisplayInfo* pDisplayInfo )
: SUIWnd( pGameManager )
, m_pDisplayInfo( pDisplayInfo )
, m_pMarkState( NULL )
, m_pPlayerClan( NULL )
, m_strPlayerClanPropertyTag( "" )
, m_bIsInFreePassMarkIcon( false )
{
}
//-----------------------------------------------------------------------------------------------------------------
// 파괴자
//-----------------------------------------------------------------------------------------------------------------
SUIMainFrameWnd::~SUIMainFrameWnd()
{
SAFE_DELETE(m_pMarkState);
}
//-----------------------------------------------------------------------------------------------------------------
// 컨트롤 초기화
//-----------------------------------------------------------------------------------------------------------------
bool SUIMainFrameWnd::InitControls(KPoint kPos)
{
m_pMarkState = new sui::sMarkState;
if( m_pMarkState )
{
hideAllMark();
m_pMarkState->hideAll();
}
return SUIWnd::InitControls(kPos);
}
//-----------------------------------------------------------------------------------------------------------------
// 데이터 초기화
//-----------------------------------------------------------------------------------------------------------------
bool SUIMainFrameWnd::InitData( bool bReload /*= false*/ )
{
m_pPlayerClan = dynamicCast<KUIControlStatic*>( GetChild( c_szClan ) );
if( NULL == m_pPlayerClan )
{
SDEBUGLOG( "[캐릭터 정보 메인 윈도우] 컨트롤 정보 얻기 실패 - Name[%s]", c_szClan );
assert( m_pPlayerClan );
}
else
{
string strCaption( m_pPlayerClan->GetCaption() );
GetTextDecoration( strCaption.c_str(), m_strPlayerClanPropertyTag );
}
return SUIWnd::InitData(bReload);
}
//-----------------------------------------------------------------------------------------------------------------
// 메시지 처리
//-----------------------------------------------------------------------------------------------------------------
void SUIMainFrameWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch(nMessage)
{
case KUI_MESSAGE::KGENWND_RIGHT_CLICK:
{
//메뉴 활성화 하자
m_pGameManager->StartSound( "ui_button_click.wav" );
}
break;
case KUI_MESSAGE::KBUTTON_CLICK:
{
if( 0 == ::_stricmp( "mainframe_name", lpszControlID ) )
{
SIMSG_UI_ACT_TARGET msg;
msg.m_nTargetHandle = m_PlayerInfoMgr.GetPlayerHandle();
m_pGameManager->ProcMsgAtStatic(&msg);
}
else if( 0 == ::_stricmp( "button_jobinfohide", lpszControlID ) )
{ //Job Info 숨기기
KUIWnd * pButtonView = GetChild( lpszControlID );
if( pButtonView ) pButtonView->SetShow(false);
KUIWnd * pButtonHide = GetChild( "button_jobinfoview" );
if( pButtonHide ) pButtonHide->SetShow(true);
}
else if( 0 == ::_stricmp( "button_jobinfoview", lpszControlID ) )
{ //Job Info 보이기
KUIWnd * pButtonView = GetChild( lpszControlID );
if( pButtonView ) pButtonView->SetShow(false);
KUIWnd * pButtonHide = GetChild( "button_jobinfohide" );
if( pButtonHide ) pButtonHide->SetShow(true);
}
}
break;
case KUI_MESSAGE::KFOCUS_ACTIVATED:
{
if( GetRect().IsInRect( static_cast<int>(lparam), static_cast<int>(wparam) ) )
{
SIMSG_UI_ACT_TARGET msg;
msg.m_nTargetHandle = m_PlayerInfoMgr.GetPlayerHandle();
m_pGameManager->ProcMsgAtStatic(&msg);
}
}
break;
}
SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
//-----------------------------------------------------------------------------------------------------------------
// 시쿠르트 이용권 ( FREEPASS )의 남은 시간 툴팁 갱신
// - 시쿠르트의 남은 시간은 서버에서 특정 상황에만 시간 갱신 패킷을 보내준다 ( 캐쉬 아이템 사용, PK 모드 변경 등... )
// 이에 시쿠르트 남은 시간을 서버로 부터 받았을 때로 부터 시간을 계산하여 클라이언트에서 출력해준다.
//-----------------------------------------------------------------------------------------------------------------
void SUIMainFrameWnd::UpdateFreePassEndTimeTooltip()
{
if( NULL == m_pMarkState )
return ;
m_pMarkState->UpdateFreePassEndTimeTooltip( this, m_pDisplayInfo );
}
//-----------------------------------------------------------------------------------------------------------------
// Idle 처리
//-----------------------------------------------------------------------------------------------------------------
void SUIMainFrameWnd::Process( DWORD dwTime )
{
if( m_bIsInFreePassMarkIcon )
UpdateFreePassEndTimeTooltip();
SUIWnd::Process( dwTime );
}
//-----------------------------------------------------------------------------------------------------------------
// 마우스 메시지 처리
//-----------------------------------------------------------------------------------------------------------------
DWORD SUIMainFrameWnd::OnMouseMessage(DWORD dwMessage, int x, int y)
{
if( m_pMarkState )
m_bIsInFreePassMarkIcon = m_pMarkState->IsInRectFreePass( this, KPoint( x, y ) ); ;
return SUIWnd::OnMouseMessage(dwMessage, x, y);
}
//-----------------------------------------------------------------------------------------------------------------
// 정적 메시지 처리
//-----------------------------------------------------------------------------------------------------------------
void SUIMainFrameWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
if( NULL == pMsg )
{
SDEBUGLOG( "[캐릭터 메인 윈도우] 메시지가 유효하지 않습니다." );
assert( NULL );
return ;
}
switch(pMsg->nType)
{
case MSG_CHANGE_NAME :
{
updateName();
pMsg->bUse = true;
}
break;
case MSG_LOGIN:
{
SMSG_LOGIN* pLoginMsg( dynamicCast<SMSG_LOGIN*>(pMsg) );
if( pLoginMsg )
{
updateName();
RefreshHP( pLoginMsg->hp, pLoginMsg->max_hp );
RefreshMP( pLoginMsg->mp, pLoginMsg->max_mp );
updateMarkStateList();
SetClan();
pMsg->bUse = true;
}
}
break;
case IMSG_UI_TARGET_STAT:
{
SIMSG_UI_TARGET_STAT* pUIMsg( dynamicCast<SIMSG_UI_TARGET_STAT*>(pMsg) );
if( pUIMsg )
{
RefreshHP( pUIMsg->m_nVar1, pUIMsg->m_nVar3 );
RefreshMP( pUIMsg->m_nVar2, pUIMsg->m_nVar4 );
pMsg->bUse = true;
}
}
break;
case MSG_LEVEL_UPDATE:
{
SetClan();
SetLevel();
SetJLevel();
RefreshExp();
pMsg->bUse = true;
}
break;
case MSG_EXP_UPDATE:
{
RefreshExp();
SetJP();
pMsg->bUse = true;
}
break;
case MSG_PROPERTY:
{
SMSG_PROPERTY* pPropertyMsg = (SMSG_PROPERTY*)pMsg;
switch( pPropertyMsg->nPropertyType )
{
case SMSG_PROPERTY::PROPERTY_NAME:
{
updateName();
}
break;
case SMSG_PROPERTY::PROPERTY_JOB:
case SMSG_PROPERTY::PROPERTY_JOB_LEVEL:
{
SetJLevel();
SetClan();
}
break;
case SMSG_PROPERTY::PROPERTY_EXP: RefreshExp(); break;
case SMSG_PROPERTY::PROPERTY_LEVEL: SetLevel(); break;
case SMSG_PROPERTY::PROPERTY_JP: SetJP(); break;
case SMSG_PROPERTY::PROPERTY_STAMINA: RefreshExp(); break;
case SMSG_PROPERTY::PROPERTY_STAMINA_REGEN_RATE: RefreshExp(); break;
case SMSG_PROPERTY::PROPERTY_PLAYTIME:
case SMSG_PROPERTY::PROPERTY_PLAYTIME_LIMIT1:
case SMSG_PROPERTY::PROPERTY_PLAYTIME_LIMIT2:
{
RefreshGageStress();
}
break;
}
pMsg->bUse = true;
}
break;
/// 2011.01.14 - prodongi
case IMSG_UI_STATE_LIST_UPDATE:
{
SIMSG_UI_STATE_LIST_UPDATE* pStateMsg = (SIMSG_UI_STATE_LIST_UPDATE*)pMsg;
if (SIMSG_UI_STATE_LIST_UPDATE::STATE_UPDATE_MARK == pStateMsg->nUpdateType)
{
updateMarkStateList();
pMsg->bUse = true;
}
}
break;
/// 2011.01.17 - prodongi
case IMSG_MARK_STATUS_CHANGE:
{
SMSG_MARK_STATUS_CHANGE* pStatusMsg = dynamicCast<SMSG_MARK_STATUS_CHANGE*>(pMsg);
if( pStatusMsg )
{
updateMarkStatusList( pStatusMsg->m_status );
pMsg->bUse = true;
}
}
break;
case MSG_BATTLE_ARENA_BATTLE_INFO:
case MSG_BATTLE_ARENA_LEAVE:
{
updateName();
pMsg->bUse = true;
}
break;
}
}
extern struct USER_INFO g_UserInfo;
void SUIMainFrameWnd::SetName(char const* name)
{
/// 2011.01.12 - prodongi
SetChildCaption( c_szPlayName, CStringUtil::StringFormat("<font:font_02><size:10><hcenter><#ffffff><vcenter>%s", name ).c_str() );
// gmpbigsun( 20130614 )
SetChildCaption( c_szServerName, CStringUtil::StringFormat("<font:font_01><size:8><#a1826b><hcenter><vcenter>%s", g_UserInfo.GetSelServerName() ).c_str() );
}
void SUIMainFrameWnd::SetLevel()
{
std::string str;
/// 2011.01.12 - prodongi
XStringUtil::Format( str, "<font:font_02><size:9><#FFFFFF><hcenter><vcenter>%d", m_PlayerInfoMgr.GetLevel() );
SetChildCaption( c_szLevel, str.c_str() );
}
void SUIMainFrameWnd::SetJLevel()
{
/// 2011.01.12 - prodongi
SetChildCaption( c_szJLV_NUM , CStringUtil::StringFormat( "<font:font_01><size:9><right>%d", m_PlayerInfoMgr.GetJLv() ).c_str() );
//기존 size:10 에서 기획팀 요청으로 9로 줄임
SetChildCaption( c_szJOB_NAME, CStringUtil::StringFormat( "<font:font_01><size:9><#ffffff><left>%s", m_PlayerInfoMgr.GetJobName() ).c_str() );
// 잡 아이콘
KUIControlIconStatic* pJobIcon = dynamicCast<KUIControlIconStatic*>(GetChild( "icon_job" ));
if( pJobIcon )
{
pJobIcon->SetIcon( c_szDEF_SPR_NAME, GetJobDB().GetJobIconName(m_PlayerInfoMgr.GetJobID()) );
pJobIcon->SetTooltip(NULL);
}
}
//-----------------------------------------------------------------------------------------------------------------
// 종족 설정
//-----------------------------------------------------------------------------------------------------------------
void SUIMainFrameWnd::SetClan()
{
if( NULL == m_pGameManager )
return ;
SGame* pGame( m_pGameManager->GetActiveGame() );
if( NULL == pGame )
return ;
SGameAvatarEx* pPlayer( dynamicCast<SGameAvatarEx*>( pGame->GetGameObject( m_PlayerInfoMgr.GetPlayerHandle() ) ) );
if( NULL == pPlayer )
{
SDEBUGLOG( "[캐릭터 정보 메인 윈도우] 플레이어 포인터가 유효하지 않습니다." );
assert( pPlayer );
return ;
}
if( NULL == m_pPlayerClan )
{
SDEBUGLOG( "[캐릭터 정보 메인 윈도우] 종족 컨트롤 정보가 유효하지 않습니다.." );
assert( m_pPlayerClan );
return ;
}
string strPlayerClan( m_strPlayerClanPropertyTag );
CLAN eClan( (CLAN)pPlayer->GetRace() );
switch( eClan )
{
case CLAN::GCLAN_GAIA:
strPlayerClan.append( S( 1 ) );
break;
case CLAN::GCLAN_DEVA:
strPlayerClan.append( S( 2 ) );
break;
case CLAN::GCLAN_ASURA:
strPlayerClan.append( S( 3 ) );
break;
default:
strPlayerClan.append( "Unknown Race" );
break;
};
strPlayerClan.append( " : " );
BYTE byJobClass( static_cast<BYTE>( GetJobDB().GetJobClass( m_PlayerInfoMgr.GetJobID() ) ) );
switch( byJobClass )
{
case JobInfo::FIGHTER:
strPlayerClan.append( S( 690000043 ) );
break;
case JobInfo::HUNTER:
strPlayerClan.append( S( 690000044 ) );
break;
case JobInfo::MAGICIAN:
strPlayerClan.append( S( 690000045 ) );
break;
case JobInfo::SUMMONER:
strPlayerClan.append( S( 690000046 ) );
break;
default:
strPlayerClan.append( "Unknown Job Class" );
break;
};
m_pPlayerClan->SetCaption( strPlayerClan.c_str() );
}
void SUIMainFrameWnd::SetJP()
{
std::string jpStr;
jpToString(m_PlayerInfoMgr.GetJP(), jpStr);
SetChildCaption( c_szJP, jpStr.c_str());
}
void SUIMainFrameWnd::RefreshExp() // 소수점 둘째 자리
{
double fPer = ((double)(m_PlayerInfoMgr.GetCurExp())/m_PlayerInfoMgr.GetMaxExp())*100.f;
SetChildCaption( "static_exp_value", CStringUtil::StringFormat( "<font:font_01><b><size:8>%02.02f%s", fPer, "%" ).c_str() );
/// 2011.01.12 - prodongi
KUIControlGauge* pGauge = dynamicCast<KUIControlGauge*>(GetChild( c_szEXP_BAR ));
if( pGauge )
{
int nStringID = -1;
std::string strGuageName;
/// 2010.11.24 - prodongi
if( m_PlayerInfoMgr.GetStamina() >= 130000 )
{
strGuageName = "common_gauge_titanium_player_stamina5000";
nStringID = 6338;
}
else if( m_PlayerInfoMgr.GetStamina() >= 10000 && m_PlayerInfoMgr.GetStamina() < 130000 )
{
strGuageName = "common_gauge_titanium_player_stamina1300";
nStringID = 6339;
}
else
{
strGuageName = "common_gauge_titanium_player_stamina100";
nStringID = 6340;
}
#ifdef _COUNTRY_CN_
if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_arLimitTime_LV1 )
{
strGuageName = "guage_creature_sp00";
}
#endif
if( stricmp( pGauge->GetAniName(), strGuageName.c_str() ) != 0 )
pGauge->SetBack( c_szDEF_SPR_NAME, strGuageName.c_str() );
std::string strTooltip = SR( nStringID, "#@regen_rate@#", m_PlayerInfoMgr.GetStaminaRegen(), "#@stamina@#", (m_PlayerInfoMgr.GetStamina()/100), "#@max_stamina@#", (m_PlayerInfoMgr.GetMax_stamina()/100) );
pGauge->SetTooltip( strTooltip.c_str() );
m_pDisplayInfo->RefreshGaugeAndStaticByPercentage( pGauge, (int)fPer, 0 );
}
}
void SUIMainFrameWnd::RefreshHP( int nHP, int nMaxHP )
{
// per
int nPer = static_cast<int>(m_pDisplayInfo->GetPercent( nHP, nMaxHP ));
std::string str;
XStringUtil::Format( str, "<font:font_01><b><size:8><right><vcenter>%d/%d", nHP, nMaxHP );
SetChildCaption( c_szHP_VALUE, str.c_str() );
KUIControlGauge* pGaugeHP = dynamicCast<KUIControlGauge*>(GetChild( c_szHP_BAR ));
if( pGaugeHP )
{
m_pDisplayInfo->RefreshGaugeAndStatic( pGaugeHP, nHP, nMaxHP, nPer, c_dwGaugeFillTime );
{
// 게이지 남은 양에 따라 텍스처 바꿔줌 // 2012.02.03 - servantes
setHPGaugeTexture( nPer, pGaugeHP, 11 );
}
}
}
void SUIMainFrameWnd::RefreshMP( int nMP, int nMaxMP )
{
int nPer = static_cast<int>(m_pDisplayInfo->GetPercent( nMP, nMaxMP ));
std::string str;
XStringUtil::Format( str, "<font:font_01><b><size:8><right><vcenter>%d/%d", nMP, nMaxMP );
SetChildCaption( c_szMP_VALUE, str.c_str() );
KUIControlGauge* pGaugeMP = dynamicCast<KUIControlGauge*>(GetChild( c_szMP_BAR ));
if( pGaugeMP )
m_pDisplayInfo->RefreshGaugeAndStatic( pGaugeMP, nMP, nMaxMP, nPer, c_dwGaugeFillTime );
}
void SUIMainFrameWnd::RefreshGageStress()
{
#ifdef _COUNTRY_CN_
AR_TIME arCurTime = m_PlayerInfoMgr.GetContinuousPlayTime();
AR_TIME arMaxTime = m_PlayerInfoMgr.GetMaxContinuousPlayTime();
if( arMaxTime == 0 )
{
// assert( false ); //서버팀에 문의 해야 한다
return;
}
float fPer = (float)arCurTime / arMaxTime;
int nShowGageOff = c_nMaxGageOff - (int)(fPer * c_nMaxGageOff);
if( nShowGageOff > c_nMaxGageOff )
{
assert( false );
return;
}
KUIControlStatic* pGageGreen = dynamicCast<KUIControlStatic*>(GetChild( c_szGage_green_01 ));
KUIControlStatic* pGageEm = dynamicCast<KUIControlStatic*>(GetChild( c_szGage_em_01 ));
if( pGageGreen ) pGageGreen->SetShow( false );
if( pGageEm ) pGageEm->SetShow( false );
for( int i = 0; i < c_nMaxGageOff; ++i )
{
KUIControlStatic* pGageOffStatic = dynamicCast<KUIControlStatic*>(GetChild( c_szGageOff[i] ));
if( pGageOffStatic )
{
if( (i+1) == nShowGageOff )
{
const KRect& rc = pGageOffStatic->GetRect();
pGageOffStatic->SetShow( false );
//3시간 경과시 에메랄드 색 표시
if( arCurTime >= c_arLimitTime_LV1 )
{
if( pGageEm )
{
pGageEm->SetShow( true );
SetMovePos( c_szGage_em_01, rc.left-1, rc.top-1 );
}
}
else
{
if( pGageGreen )
{
pGageGreen->SetShow( true );
SetMovePos( c_szGage_green_01, rc.left-1, rc.top-1 );
}
}
}
else if( i < nShowGageOff )
pGageOffStatic->SetShow( false );
else
pGageOffStatic->SetShow( true );
}
}
KUIControlStatic* pGageOffStatic = dynamicCast<KUIControlStatic*>(GetChild( c_szGageOff01 ));
if( pGageOffStatic )
{
if( nShowGageOff == 0 )
pGageOffStatic->SetShow( false );
else
pGageOffStatic->SetShow( true );
}
KUIControlStatic* pGageStressStatic = dynamicCast<KUIControlStatic*>(GetChild( c_szGage_Stress ));
if( pGageStressStatic )
{
AR_TIME hour = arCurTime / 360000; //100*60*60 1/100초 기준
AR_TIME minute = 0;
if( hour > 0 )
{
minute = arCurTime - ( hour * 360000 );
minute = minute / 6000;
}
else
{
minute = arCurTime / 6000;
}
// sonador 3.4.2 소지금 최대 한도 증가 관련 시스템 변경
std::string str = SR(550, "#@hour@#", static_cast< int >( hour ), "#@minute@# ", static_cast< int >( minute ) );
if( arCurTime >= c_arLimitTime_LV2 ) //5시간 경과시 플레이 타임 미 표시
str = CStringUtil::StringFormat( "%s", S( 549 ) );
else if( arCurTime >= c_arLimitTime_LV1 ) //3시간 경과
str += CStringUtil::StringFormat( "<BR>%s", S( 548 ) );
else
str += CStringUtil::StringFormat( "<BR>%s", S( 547 ) );
pGageStressStatic->SetTooltip( str.c_str() );
}
RefreshExp();
#endif
}
/// 2011.01.13 - prodongi
void SUIMainFrameWnd::hideAllMark()
{
m_pMarkState->hideAllControl(this);
}
/// 2011.01.14 - prodongi
void SUIMainFrameWnd::updateMarkStateList()
{
m_pMarkState->updateMarkStateList(this, m_pDisplayInfo, g_pCurrentGameSystem->GetLocalPlayer());
}
/// 2011.01.17 - prodongi
void SUIMainFrameWnd::updateMarkStatusList(int status)
{
m_pMarkState->updateMarkStatusList(this, m_pDisplayInfo, status);
}
void SUIMainFrameWnd::updateName()
{
sArenaSystem* arenaSystem = g_pCurrentGameSystem->getArenaSystem();
SetName(arenaSystem->getPlayerName(&m_PlayerInfoMgr));
}