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

551 lines
16 KiB
C++

#include "stdafx.h"
#include "KUIControlStatic.h"
#include "KUIControlScroll.h"
#include "SGameManager.h"
//#include "SGameMessageUI.h"
#include "SUIQuestReward.h"
#include "SQuestMgr.h"
#include "SPlayerInfoMgr.h"
#include "SInventoryMgr.h"
#include "SQuestDB.h"
#include "SItemDB.h"
#include "SStringDB.h"
#include "SkillBaseFile.h"
#include "SGame.h"
#include "GameRule.h"
#include "ErrorCode/ErrorCode.h"
#include "SUIDisplayInfo.h"
#include <toolkit/XStringUtil.h>
#include "SUISysMsgDefine.h"
#include "SUILazyTooltip.h"
static const size_t MAX_ICON_COUNT = 3; // 보상 아이템 갯수
static const size_t MAX_SLOT_COUNT = 5; // 한 다이얼로그에 보이는 퀘스트 갯수
static const size_t CONTROL_PER_SLOT = 5; // 한개의 슬롯이 사용하는 UI 컨트롤 갯수
static const int SLOT_Y_DELTA = 58; // 슬롯당 거리
static const int c_nSysMenu = 56; // 왼쪽 메뉴 바 width
// { 각 슬롯의 컨트롤에 편하게 접근하기 위해 만든 것들
namespace SLOT_CONTROL_INDEX
{
static const size_t BACK = 0;
static const size_t NAMEBACK = 1;
static const size_t SUBTITLE = 2;
static const size_t PROGRESS = 3;
static const size_t NAME = 4;
};
namespace
{
static char *s_szSlotControlName[ CONTROL_PER_SLOT ]
= {
"quest_back_%02d",
"quest_nameback_%02d",
"quest_subtitle_%02d",
"quest_progress_%02d",
"quest_name_%02d",
};
// }
const char* c_szStaticExp = "static_exp";
const char* c_szStaticJp = "static_jp";
const char* c_szStaticRupy = "static_rupy";
const char* c_szQuestConfirmButton = "quest_button_confirm";
};
static int GetIconControlNum( const char* szSlotControlID )
{
for( int nSlotIndex( 0 ); nSlotIndex < MAX_ICON_COUNT; ++nSlotIndex )
{
if( 0 == ::_stricmp( CStringUtil::StringFormat( "quest_selectitem_itemback_%02d", nSlotIndex ).c_str(), szSlotControlID ) )
return nSlotIndex;
}
return (-1);
}
static int GetSlotControlNum( const char* szSlotControlID )
{
for( int nSlotIndex( 0 ); nSlotIndex < MAX_SLOT_COUNT; ++nSlotIndex )
{
if( 0 == ::_stricmp( CStringUtil::StringFormat( s_szSlotControlName[ SLOT_CONTROL_INDEX::NAME ], nSlotIndex ).c_str(), szSlotControlID ) )
return nSlotIndex;
}
return (-1);
}
int SUIQuestRewardWnd::GetSlotControlNum( int x, int y )
{
for( int nSlotIndex( 0 ); nSlotIndex < MAX_SLOT_COUNT; ++nSlotIndex )
{
for( int nIndex( 0 ); nIndex < CONTROL_PER_SLOT; ++nIndex )
{
KUIWnd* pWnd = GetChild( CStringUtil::StringFormat( s_szSlotControlName[ nIndex ], nSlotIndex ).c_str() );
if( pWnd == NULL ) continue;
KRect rect = pWnd->GetRect();
if( rect.IsInRect( x, y ) ) return nSlotIndex;
}
}
return (-1);
}
void SUIQuestRewardWnd::IconFocus( int nIndex )
{
KUIWnd *pWnd = GetChild( "quest_selectitem" );
if( !pWnd ) return;
QuestBase::QuestCode code = m_nQuestCode;
QuestBase *pBase = GetQuestDB().GetQuestData( code );
if( !pBase )
{
pWnd->SetShow( false );
return;
}
int nOptionalRewardCount = 0;
for( nOptionalRewardCount = QuestBase::MAX_OPTIONAL_REWARD; nOptionalRewardCount > 0; --nOptionalRewardCount )
{
if( pBase->OptionalReward[ nOptionalRewardCount-1 ].nItemCode ) break;
}
if( nIndex < 0 || nIndex >= nOptionalRewardCount )
{
pWnd->SetShow( false );
return;
}
m_nRewardFocus = nIndex;
pWnd->SetShow( true );
KUIWnd * pItemIcon = GetChild( CStringUtil::StringFormat( "quest_selectitem_itemback_%02d", nIndex ).c_str() );
if( pItemIcon )
{
pWnd->MovePos( pItemIcon->GetRect().left, pItemIcon->GetRect().top );
}
}
void SUIQuestRewardWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch(nMessage)
{
case KUI_MESSAGE::KICON_CLICK:
{
int nSlotIndex = GetIconControlNum( lpszControlID );
if( nSlotIndex >= 0 )
{
m_pGameManager->StartSound( "ui_button_click.wav" );
IconFocus( nSlotIndex );
break;
}
}
break;
case KUI_MESSAGE::KBUTTON_CLICK:
{
if( ::_stricmp( lpszControlID, "button_close" ) == 0 )
{
//m_pGameManager->PostMsgAtDynamic( new SIMSG_TOGGLE_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_LIST ) );
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD, false) );
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NPCDIALOG, false) );
break;
}
//TODO : 하드 코딩
if( ::_stricmp( lpszControlID, c_szQuestConfirmButton ) == 0 )
{
bool bSendResult = false;
if( IsQuestNeedRewardItem() )
{
if( m_nRewardFocus >= 0 )
bSendResult = true;
}
else
{
bSendResult = true;
m_nRewardFocus = -1;
}
if( bSendResult )
{
m_pGameManager->StartSound( "ui_click_complete01.wav" ); //퀘스트 완료
std::string strTrigger;
XStringUtil::Format( strTrigger, "end_quest( %d, %d )", m_nQuestCode, m_nRewardFocus );
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_ACT_NPCDIALOG( strTrigger.c_str() ) );
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD, false) );
m_nQuestCode = -1;
m_nRewardFocus = -1;
}
else
{
m_pDisplayInfo->AddSystemMessage( S(512), 99 ); // Please select a quest reward
}
}
Refresh();
}
break;
case KUI_MESSAGE::KGENWND_MOVE: // 윈도우 이동
{
LimitMoveWnd(); // 게임 외부로 나가지 못하게 제한
//KUIWnd *pInfoWnd = m_pManager->FindWnd( "window_quest_sub" );
//if( pInfoWnd ) pInfoWnd->MovePos( GetRect().right, GetRect().top );
//if( pInfoWnd )
//{
// KUIWnd *pRewardWnd = m_pManager->FindWnd( "quest_compensation" );
// if( pRewardWnd ) pRewardWnd->MovePos( pInfoWnd->GetRect().right, pInfoWnd->GetRect().top );
//}
// 좌측 메뉴도 이동시켜 준다
//m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_MOVE( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_SYSMENU, GetRect().left, GetRect().top ) );
break;
}
//case KUI_MESSAGE::KFOCUS_ACTIVATED:
//{
// if( GetRect().IsInRect( static_cast<int>(lparam), static_cast<int>(wparam) ) )
// m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_FOCUS(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_SYSMENU) );
//}
break;
}
return SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
void* SUIQuestRewardWnd::Perform( KID id, KArg& msg )
{
return SUIWnd::Perform( id, msg );
}
void SUIQuestRewardWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
switch( pMsg->nType )
{
case IMSG_SHOW_UIWINDOW:
{
if( m_nSysMenuPosX > -99 && m_nSysMenuPosY > -99 )
{
MovePos(m_nSysMenuPosX, m_nSysMenuPosY);
}
pMsg->bUse = true;
}
break;
case IMSG_UI_MOVE:
{
SIMSG_UI_MOVE* pMoveMsg = ( SIMSG_UI_MOVE* )pMsg;
m_nSysMenuPosX = pMoveMsg->m_nX;
m_nSysMenuPosY = pMoveMsg->m_nY;
MovePos(m_nSysMenuPosX, m_nSysMenuPosY);
pMsg->bUse = true;
}
break;
case IMSG_HOTKEY_EX: //servantes 2010.10.19
{
SIMSG_HOTKEY_EX* pHotKey = dynamicCast<SIMSG_HOTKEY_EX*>(pMsg);
if( pHotKey->wParam == VK_SHIFT )
m_bShiftKey = (pHotKey->bUp == 0); //servantes 2010.10.15
if( pHotKey->wParam == VK_CONTROL ) //servantes 2010.10.15
m_bControlKey = (pHotKey->bUp == 0);
if( pHotKey->wParam == VK_MENU )
{
bool bPreState = m_bAltKey;
m_bAltKey = (pHotKey->bUp == 0);
if( bPreState != m_bAltKey && IsShow() )
{
Refresh();
}
}
}
break;
}
if( pMsg->nType == IMSG_UI_SEND_DATA )
{
SIMSG_UI_SEND_DATA *pData = dynamicCast< SIMSG_UI_SEND_DATA * >( pMsg );
//보상 관련
if( pData->m_strString == "select_reward" )
{
m_nQuestCode = pData->m_nNumber.getAmount();
pMsg->bUse = true;
Refresh();
}
}
return SUIWnd::ProcMsgAtStatic( pMsg );
}
void SUIQuestRewardWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd )
{
m_nRewardFocus = -1;
if( bOpen )
{
m_pGameManager->StartSound( "ui_popup_window01.wav" );
//KUIWnd *pWnd = m_pManager->FindWnd( "sys_menu" );
//if( pWnd )
//{
// MovePos( pWnd->GetRect().right, pWnd->GetRect().top );
//}
Refresh();
}
else
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_INFO, false ) );
}
return SUIWnd::OnNotifyUIWindowOpen( bOpen );
}
bool SUIQuestRewardWnd::InitControls( KPoint kPos )
{
// 슬롯 컨트롤들 복사
CreateControls();
// 커스텀 윈도우 move 영역 설정
SetCustomMovingRect( KRect( 0, 0, 312, 20 ) );
SetChildCaption( c_szStaticExp, GetStringDB().GetString( STRING_EXP ) );
SetChildCaption( c_szStaticJp, GetStringDB().GetString( STRING_QUEST_REWORD_JP ) );
SetChildCaption( c_szStaticRupy, GetStringDB().GetString( STRING_QUEST_REWORD_R ) );
SetChildShow( c_szQuestConfirmButton, true );
SetChildCaption( c_szQuestConfirmButton, S(10) );
return true;
}
void SUIQuestRewardWnd::SetSlotShowMode( size_t idx, bool bShow )
{
assert( idx < MAX_SLOT_COUNT );
for( size_t x = 0; x < CONTROL_PER_SLOT; ++x )
{
bool bTmpShow = bShow;
std::string strControlName( CStringUtil::StringFormat( s_szSlotControlName[x], idx ) );
if( !bTmpShow )
{
KUIWnd* pWnd = GetChild( strControlName.c_str() );
if( pWnd ) pWnd->SetCaption( "" );
}
SetChildShow( strControlName.c_str(), bTmpShow );
}
}
std::string SUIQuestRewardWnd::CoordinateQuestName( int nDifficulty, int nLimitLevel, const std::string & strQuestName )
{
std::string color;
m_pDisplayInfo->getQuestDifficultyColor(nDifficulty, nLimitLevel, color);
return color + strQuestName;
}
void SUIQuestRewardWnd::Refresh()
{
SetQuestRewardItem( false );
MoveFocus( 0 );
}
void SUIQuestRewardWnd::MoveFocus( int idx )
{
extern std::string ParseQuestText( const char *szQuestString, int nQuestCode ); // GameVM.cpp
KUIWnd *pWnd = GetChild( "static_quest_selectbar" );
//if( !pWnd ) return;
size_t quest_cnt = SQuestMgr::GetInstance().GetQuestCount();
m_strQuestSummary = "";
//RefreshSummaryText();
SetChildCaption( "static_quest_base" , CStringUtil::StringFormat( "<#797979><vcenter><hcenter>%s", S(6201) ).c_str() );
SetChildCaption( "static_quest_select", CStringUtil::StringFormat( "<#797979><vcenter><hcenter>%s", S(6202) ).c_str() );
SetChildCaption( "quest_compens_expnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
SetChildCaption( "quest_compens_jpnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
SetChildCaption( "quest_compens_rpnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
SetItemSlot( 0, 0, "quest_baseitem_itemback", "quest_baseitem_itemnumber" );
for( size_t slot_idx = 0; slot_idx < QuestBase::MAX_OPTIONAL_REWARD; ++slot_idx )
SetItemSlot( 0, 0, CStringUtil::StringFormat( "quest_selectitem_itemback_%02d", slot_idx ).c_str(), CStringUtil::StringFormat( "quest_selectitem_itemnumber%02d", slot_idx ).c_str() );
// int nFocus = m_nFocus - m_nTopSlotIndex;
QuestBase::QuestCode qcode = m_nQuestCode;
m_nQuestCode = qcode;
//m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_INFO, qcode, "set_quest_code" ) );
KUIWnd *pTopIcon = GetChild( "quest_name_00" );
// KUIWnd *pLeftIcon = GetChild( "quest_nameback_00" );
SQuestMgr::GetInstance().SetCurrentQuest( qcode );
QuestBase::QuestCode code = qcode;
QuestBase *pBase = GetQuestDB().GetQuestData( code );
if( !pBase ) return;
//// 퀘스트 제목
//SetChildCaption( "quest_name", ParseQuestText( GetStringDB().GetQuestString( pBase->nQuestTextId ), code ).c_str() );
// 요약
m_strQuestSummary = GetStringDB().GetQuestString( pBase->nSummaryTextId );
if( pBase->nStatusTextId )
{
m_strQuestSummary += "<BR><BR>";
m_strQuestSummary += GetStringDB().GetQuestString( pBase->nStatusTextId );
}
m_strQuestSummary = ParseQuestText( m_strQuestSummary.c_str(), code );
// #2.3.1.8 sonador
c_fixed10 fRwdFct = GameRule::GetQuestRewardFactor( pBase );
// 보상
// EXP
if( pBase->nExp )
{
int nRewardExp = pBase->nExp * fRwdFct;
SetChildCaption( "quest_compens_expnumber", CStringUtil::StringFormat( "<right>%d", nRewardExp ).c_str() );
}
else
SetChildCaption( "quest_compens_expnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
// JP
if( pBase->nJP )
{
int nRewardJP = pBase->nJP * fRwdFct;
SetChildCaption( "quest_compens_jpnumber", CStringUtil::StringFormat( "<right>%d", nRewardJP ).c_str() );
}
else
SetChildCaption( "quest_compens_jpnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
// RP
if( pBase->nGold )
{
int nRewardGold = pBase->nGold * fRwdFct;
SetChildCaption( "quest_compens_rpnumber", CStringUtil::StringFormat( "<right>%d", nRewardGold ).c_str() );
}
else
SetChildCaption( "quest_compens_rpnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
// 2009. 2. 13 hunee 은신감지 관련 추가, 기획쪽 담당자 김동민
// P
if( pBase->nHolicPoint )
{
int nRewardP = pBase->nHolicPoint * fRwdFct;
SetChildCaption( "quest_compens_pointnumber", CStringUtil::StringFormat( "<right>%d", nRewardP ).c_str() );
}
else
SetChildCaption( "quest_compens_pointnumber", CStringUtil::StringFormat( "<right>%d", 0 ).c_str() );
// 기본아이템
if( pBase->DefaultReward.nItemCode )
{
SetChildCaption( "static_quest_base", CStringUtil::StringFormat( "<#FFFFFFFF><hcenter><vcenter>%s", S(6201) ).c_str() );
SetItemSlot( pBase->DefaultReward.nItemCode, pBase->DefaultReward.nQuantity, "quest_baseitem_itemback", "quest_baseitem_itemnumber" );
}
else
{
SetChildCaption( "static_quest_base", CStringUtil::StringFormat( "<#797979><hcenter><vcenter>%s", S(6201) ).c_str() );
SetItemSlot( 0, 0, "quest_baseitem_itemback", "quest_baseitem_itemnumber" );
}
// 옵셔널 아이템
if( pBase->OptionalReward[0].nItemCode )
{
SetChildCaption( "static_quest_select", CStringUtil::StringFormat( "<hcenter><vcenter><#FFFFFFFF>%s", S(6202) ).c_str() );
for( size_t slot_idx = 0; slot_idx < QuestBase::MAX_OPTIONAL_REWARD; ++slot_idx )
{
ItemBase::ItemCode code = pBase->OptionalReward[slot_idx].nItemCode;
int nCount = pBase->OptionalReward[slot_idx].nQuantity;
SetItemSlot( code, nCount, CStringUtil::StringFormat( "quest_selectitem_itemback_%02d", slot_idx ).c_str(), CStringUtil::StringFormat( "quest_selectitem_itemnumber%02d", slot_idx ).c_str() );
}
SetQuestRewardItem( true );
}
else
{
SetChildCaption( "static_quest_select", CStringUtil::StringFormat( "<hcenter><vcenter><#797979>%s", S(6202) ).c_str() );
for( size_t slot_idx = 0; slot_idx < QuestBase::MAX_OPTIONAL_REWARD; ++slot_idx )
SetItemSlot( 0, 0, CStringUtil::StringFormat( "quest_selectitem_itemback_%02d", slot_idx ).c_str(), CStringUtil::StringFormat( "quest_selectitem_itemnumber%02d", slot_idx ).c_str() );
SetQuestRewardItem( false );
}
}
void SUIQuestRewardWnd::SetItemSlot( ItemBase::ItemCode code, int nCount, const char *szIconControl, const char *szNumberControl )
{
// 아이콘 설정
KUIControlIconStatic *pIcon = dynamicCast< KUIControlIconStatic* >( GetChild( szIconControl ) );
if( pIcon )
{
if( code )
{
const ItemBaseEx_info * base = GetItemDB().GetItemData( code );
pIcon->SetIcon( "ui_frame.spr", base->pIcon_name );
pIcon->SetTooltip( m_pDisplayInfo->GetItemTooltipText( code, true, 0, 1, XFlag<int>(), 0, 0, 0, 0, 0, 0, 0, 0, 0, false, -1, -1, 0, base->nSummonId, 0 ).c_str() );
pIcon->SetTooltipSprite( "ui_frame.spr" );
if( m_bAltKey )
{
m_pDisplayInfo->SetComparableEquipItemSubTooltip( pIcon, code );
}
}
else
{
pIcon->SetIcon( "ui_frame.spr", "static_common_itemslot" );
pIcon->SetTooltip( "" );
}
}
// 수량 설정
KUIWnd* pNum = GetChild( szNumberControl );
if( pNum )
{
if( code )
{
pNum->SetCaption( CStringUtil::StringFormat( "%s<shadow><right><size:8>%d", S(6425), nCount ).c_str() );
pNum->SetShow( true );
}
else pNum->SetShow( false );
}
}
void SUIQuestRewardWnd::CreateControls()
{
/* size_t i;
RECT rc = { 0, 20, 0, 20 };*/
}
DWORD SUIQuestRewardWnd::OnMouseMessage(DWORD dwMessage, int x, int y)
{
if( dwMessage == KLBUTTON_DOWN )
{
}
if( dwMessage == KLBUTTON_DBLCLK )
{
}
return SUIWnd::OnMouseMessage( dwMessage, x, y );
}