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

629 lines
14 KiB
C++

#include "stdafx.h"
#include "SUIMissionWnd.h"
#include "SGameManager.h"
#include "SGameOption.h"
#include <toolkit/XStringUtil.h>
#include "KUIControlButton.h"
#include "SGameMessage.h"
#include "SChatType.h"
#include "SStringDB.h"
extern void MsgSplit( const char* szMsg, std::vector<std::string>& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false );
void SUIMissionWnd::sTransparency::initialize(SUIWnd* parentWnd)
{
addAllList(parentWnd);
setMode(NONE);
m_alpha = 1.0f;
m_updateV = 4.0f;
m_transparencyButton = dynamicCast<KUIControlSimpleButton*>(parentWnd->GetChild("button_mission_opacity_01"));
}
void SUIMissionWnd::sTransparency::addAllList(SUIWnd* parentWnd)
{
addList(parentWnd->GetChild("title_deco_01"));
addList(parentWnd->GetChild("titlebar"));
addList(parentWnd->GetChild("deco_01"));
addList(parentWnd->GetChild("outframe"));
addList(parentWnd->GetChild("inframe01"));
}
void SUIMissionWnd::sTransparency::addList(KUIWnd* wnd)
{
if (!wnd)
return ;
m_list.push_back(wnd);
}
void SUIMissionWnd::sTransparency::setTransparency(bool transparency)
{
m_transparency = transparency;
setMode(m_transparency ? FADE_OUT : FADE_IN);
if (m_transparencyButton)
m_transparencyButton->SetAniName(m_transparency ? "common_button_titanium_lock" : "common_button_titanium_unlock");
}
void SUIMissionWnd::sTransparency::toggleTransparency()
{
setTransparency(!m_transparency);
}
void SUIMissionWnd::sTransparency::setMode(int mode)
{
m_mode = mode;
m_updateTime = 0.0f;
}
void SUIMissionWnd::sTransparency::update(float elapsedtime)
{
if (NONE == m_mode)
return ;
float s = m_updateV * elapsedtime;
if (FADE_IN == m_mode)
{
setAlpha(m_alpha + s);
}
else if (FADE_OUT == m_mode)
{
setAlpha(m_alpha - s);
}
}
void SUIMissionWnd::sTransparency::updateAlpha()
{
setAlpha(m_alpha);
}
void SUIMissionWnd::sTransparency::setAlpha(float alpha)
{
m_alpha = alpha;
if (0.0f > m_alpha)
{
m_alpha = 0.0f;
setMode(NONE);
}
else if (1.0f < m_alpha)
{
m_alpha = 1.0f;
setMode(NONE);
}
struct sUpdateAlpha
{
sUpdateAlpha(float alpha) : m_alpha(alpha) {}
void operator ()(KUIWnd* wnd)
{
wnd->ChangeAlpha(m_alpha);
}
float m_alpha;
};
std::for_each(m_list.begin(), m_list.end(), sUpdateAlpha(m_alpha));
}
bool SUIMissionWnd::sObject::operator == (int index)
{
return m_index == index;
}
void SUIMissionWnd::sObject::set(SUIMissionWnd::sObject const& object)
{
m_index = object.m_index;
m_max = object.m_max;
m_cur = object.m_cur;
m_text = object.m_text;
}
void SUIMissionWnd::sObjectList::insert(SUIMissionWnd::sObject const& object)
{
std::vector<sObject>::iterator it = std::find(m_list.begin(), m_list.end(), object.m_index);
if (it != m_list.end())
{
it->set(object);
}
else
{
m_list.push_back(object);
}
}
void SUIMissionWnd::sObjectList::erase(int index)
{
std::vector<sObject>::iterator it = std::find(m_list.begin(), m_list.end(), index);
if (it != m_list.end())
{
m_list.erase(it);
}
}
void SUIMissionWnd::sObjectList::update(SUIWnd* parentWnd)
{
struct sUpdate
{
sUpdate(SUIWnd* wnd) : m_count(0), m_wnd(wnd) {}
void operator ()(sObject const& object)
{
bool isCompleted = (object.m_cur == object.m_max) ? true : false;
char const* color = (isCompleted) ? "<#898989>" : "<#ffffff>";
KUIWnd* wnd;
/// text
XStringUtil::Format(m_id, "target_text_%02d", m_count);
wnd = m_wnd->GetChild(m_id.c_str());
if (wnd)
{
XStringUtil::Format(m_temp, "<font:font_01><size:9><b><hcenter><left>%s%s", color, object.m_text.c_str());
wnd->SetCaption(m_temp.c_str());
}
/// progress
XStringUtil::Format(m_id, "target_count_%02d", m_count);
wnd = m_wnd->GetChild(m_id.c_str());
if (wnd)
{
XStringUtil::Format(m_temp, "<font:font_01><size:9><b><hcenter><left>%s%d/%d", color, object.m_cur, object.m_max);
wnd->SetCaption(m_temp.c_str());
}
/// background
XStringUtil::Format(m_id, "target_list_on_%02d", m_count);
wnd = m_wnd->GetChild(m_id.c_str());
if (wnd)
{
wnd->SetAniName((isCompleted) ? "game_panel_mission_list_off" : "game_panel_mission_list_on");
}
++m_count;
}
SUIWnd* m_wnd;
std::string m_temp;
std::string m_id;
int m_count;
};
std::for_each(m_list.begin(), m_list.end(), sUpdate(parentWnd));
}
void SUIMissionWnd::sObjectList::setObject(int slotIndex, int maxProgress, const char* text, SUIWnd* parentWnd)
{
if (!text)
{
erase(slotIndex);
}
else
{
insert(sObject(slotIndex, maxProgress, 0, text));
}
update(parentWnd);
}
bool SUIMissionWnd::sObjectList::setProgress(int index, int curProgress, SUIWnd *parentWnd, std::string& progressNotice)
{
std::vector<sObject>::iterator it = std::find(m_list.begin(), m_list.end(), index);
if (it == m_list.end())
{
return false;
}
it->m_cur = curProgress;
makeProgressNotice(*it, progressNotice);
update(parentWnd);
return true;
}
void SUIMissionWnd::sObjectList::makeProgressNotice(SUIMissionWnd::sObject const& object, std::string& progressNotice)
{
XStringUtil::Format(progressNotice, "<#00FFFC>%s %d/%d", object.m_text.c_str(), object.m_cur, object.m_max);
}
SUIMissionWnd::SUIMissionWnd(SGameManager* pGameManager) : SUIWnd(pGameManager)
{
}
SUIMissionWnd::~SUIMissionWnd()
{
}
bool SUIMissionWnd::InitControls(KPoint kPos)
{
bool ret = SUIWnd::InitControls(kPos);
KUIWnd* wnd = GetChild("titlebar");
if (wnd)
{
SetCustomMovingRect(KRect(0, 0, wnd->GetRect().GetWidth(), wnd->GetRect().GetHeight()));
SetResizeUnit(0, 1, KSize(GetRect().GetWidth(), wnd->GetRect().GetHeight()), KSize(GetRect().GetWidth(), GetRect().GetHeight()));
}
return ret;
}
bool SUIMissionWnd::InitData(bool bReload)
{
bool ret = SUIWnd::InitData(bReload);
m_elapsedtime = 0;
m_time = 0;
m_rewardCtrl = dynamicCast<KUIControl*>(GetChild("mission_reward_01"));
if( m_rewardCtrl != NULL )
{
// 보상은 없을 수 있으므로 기본적으로 보이지 않게 한다.
m_rewardCtrl->SetShow( false );
}
initBackup();
m_transparency.initialize(this);
setTransparency(false);
return ret;
}
void SUIMissionWnd::initBackup()
{
KUIWnd* wnd;
m_backup.m_wndHeight = GetRect().GetHeight();
wnd = GetChild("inframe01");
if (wnd) m_backup.m_inframeHeight = wnd->GetRect().GetHeight();
wnd = GetChild("outframe");
if (wnd) m_backup.m_outframeHeight = wnd->GetRect().GetHeight();
if (m_rewardCtrl) m_backup.m_rewardOffsetTop = m_rewardCtrl->GetRect().top - GetRect().top;
}
void SUIMissionWnd::setObjectCount(int objectCount)
{
modifyObjectControls(objectCount);
modifySize(objectCount);
m_transparency.updateAlpha();
}
void SUIMissionWnd::modifyObjectControls(int objectCount)
{
int i;
for (i = 0; i < objectCount; ++i)
{
showObjectLineControls(i, true);
}
for (; i < MAX_OBJECT_COUNT; ++i)
{
showObjectLineControls(i, false);
}
}
void SUIMissionWnd::showObjectLineControls(int objectNum, bool show)
{
KUIWnd* wnd;
std::string controlName;
/// list
XStringUtil::Format(controlName, "target_list_on_%02d", objectNum);
wnd = GetChild(controlName.c_str());
if (wnd) wnd->SetShow(show);
/// object name
XStringUtil::Format(controlName, "target_text_%02d", objectNum);
wnd = GetChild(controlName.c_str());
if (wnd) wnd->SetShow(show);
/// object progress count
XStringUtil::Format(controlName, "target_count_%02d", objectNum);
wnd = GetChild(controlName.c_str());
if (wnd) wnd->SetShow(show);
}
void SUIMissionWnd::modifySize(int objectCount)
{
KRect r;
int height;
KUIWnd* wnd;
int totalDecLineHeight = (MAX_OBJECT_COUNT - objectCount) * OBJECT_LINE_HEIGHT;
if( m_rewardCtrl != NULL )
{
if( m_rewardCtrl->IsShow() == false )
{
totalDecLineHeight += OBJECT_LINE_HEIGHT;
}
}
/// wnd
int oldBottom = GetRect().bottom;
r = GetRect();
height = m_backup.m_wndHeight - totalDecLineHeight;
/// 줄어든 실제 bottom을 설정
r.bottom = r.top + height;
Resize(r);
/// oldBottom을 기준으로 하는 새로운 top, bottom을 설정
MovePos(GetRect().left, oldBottom - height);
LimitMoveWnd();
if (m_rewardCtrl)
{
int top = GetRect().top + m_backup.m_rewardOffsetTop - totalDecLineHeight;
m_rewardCtrl->MovePos(m_rewardCtrl->GetRect().left, top);
}
wnd = GetChild("inframe01");
if (wnd)
{
r = wnd->GetRect();
height = m_backup.m_inframeHeight - totalDecLineHeight;
r.bottom = r.top + height;
wnd->Resize(r);
}
wnd = GetChild("outframe");
if (wnd)
{
r = wnd->GetRect();
height = m_backup.m_outframeHeight - totalDecLineHeight;
r.bottom = r.top + height;
wnd->Resize(r);
}
}
void SUIMissionWnd::OnNotifyUIWindowOpen(bool bOpen, bool bLimitWnd)
{
if (bOpen)
{
/// 임시 위치
int width = GetGameOption().GetResolution_Width();
MovePos(width - GetRect().GetWidth(), 300);
if (!m_title.empty())
{
refresh();
}
else
{
// 보상은 없을 수 있으므로 기본적으로 보이지 않게 한다.
if( m_rewardCtrl != NULL )
{
m_rewardCtrl->SetShow( false );
}
SetShow(false);
}
}
else
{
// 보상은 없을 수 있으므로 기본적으로 보이지 않게 한다.
if( m_rewardCtrl != NULL )
{
m_rewardCtrl->SetShow( false );
}
}
}
void SUIMissionWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch (nMessage)
{
case KUI_MESSAGE::KBUTTON_CLICK:
{
toggleTransparency();
}
break;
case KUI_MESSAGE::KGENWND_MOVE:
{
LimitMoveWnd();
}
break;
}
SUIWnd::PumpUpMessage(lpszControlID, nMessage, lparam, wparam);
}
void SUIMissionWnd::ProcMsgAtStatic(SGameMessage* pMsg)
{
switch (pMsg->nType)
{
case MSG_CHATTING:
{
SMSG_CHATTING* msg = dynamicCast<SMSG_CHATTING*>(pMsg);
if (CHAT_DUNGEON_SYSTEM == msg->nChatType)
{
if ("@DUNGEON" == msg->szSender)
{
std::vector<std::string> strList;
MsgSplit(msg->strText.c_str(), strList, L"|");
procChatMsg(strList);
strList.clear();
}
}
}
break;
}
SUIWnd::ProcMsgAtStatic(pMsg);
}
void SUIMissionWnd::procChatMsg(std::vector<std::string> const& strList)
{
if (strList.empty())
return ;
std::string type = strList[0];
std::string::size_type strLen = strList.size();
/// title
if ("MTITLE" == type)
{
/// hide
if (1 == strLen)
{
if (IsShow())
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MISSION, false) );
setTitle(NULL);
}
else
{
if (!IsShow())
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MISSION, true) );
clearData();
setTitle(strList[1].c_str());
}
}
/// 보상
else if ("MREWARD" == type)
{
if (1 < strLen)
{
setReward(strList[1].c_str());
}
else
{
setReward( NULL );
}
}
/// 목표
else if ("MOBJECTIVE" == type)
{
if (2 < strLen)
{
/// add
if (3 < strLen)
{
setObject(atoi(strList[1].c_str()), atoi(strList[2].c_str()), strList[3].c_str());
}
/// erase
else
{
setObject(atoi(strList[1].c_str()), atoi(strList[2].c_str()), NULL);
}
}
}
/// 목표 진행률
else if ("MPROGRESS" == type)
{
if (2 < strLen)
{
setProgress(atoi(strList[1].c_str()), atoi(strList[2].c_str()));
}
}
}
DWORD SUIMissionWnd::OnMouseMessage(DWORD dwMessage, int x, int y)
{
if (m_transparency.m_transparency)
{
KUIControlSimpleButton* button = m_transparency.m_transparencyButton;
if (button && m_rewardCtrl)
{
if (!button->IsInRect(x, y) && !m_rewardCtrl->IsInRect(x, y))
{
OffToolTipWnd();
button->SetButtonState(KUIControlSimpleButton::KBUTTON_NORMAL);
return 0;
}
}
}
return SUIWnd::OnMouseMessage(dwMessage, x, y);
}
void SUIMissionWnd::Process(DWORD dwTime)
{
SUIWnd::Process(dwTime);
DWORD elapsedtime = dwTime - m_time;
m_time = dwTime;
m_elapsedtime += elapsedtime;
m_transparency.update((float)elapsedtime/1000.0f);
}
void SUIMissionWnd::toggleTransparency()
{
m_transparency.toggleTransparency();
}
void SUIMissionWnd::setTransparency(bool transparency)
{
m_transparency.setTransparency(transparency);
}
void SUIMissionWnd::setTitle(char const* title)
{
if (!title)
{
m_title.clear();
return ;
}
m_title = title;
KUIWnd* wnd = GetChild("title_text_01");
if (wnd)
{
std::string str;
XStringUtil::Format(str, "<font:font_02><hcenter><vcenter><#1d8ae7f><out><@292929><size:9>%s", title);
wnd->SetCaption(str.c_str());
m_pGameManager->ProcMsgAtStatic( &SIMSG_MISSION_TITLE(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MISSION_TITLE_WND, title));
}
}
void SUIMissionWnd::setReward(char const* reward)
{
if( reward == NULL )
{
m_reward.clear();
}
else
{
m_reward = reward;
}
if (m_rewardCtrl)
{
m_rewardCtrl->SetTooltip(m_reward.c_str());
if( m_reward.empty() == true )
{
// 보상이 없다면 보이지 않게 한다.
m_rewardCtrl->SetShow( false );
}
else
{
m_rewardCtrl->SetShow( true );
}
}
}
void SUIMissionWnd::setObject(int slotIndex, int maxProgress, const char* text)
{
m_objects.setObject(slotIndex, maxProgress, text, this);
setObjectCount(m_objects.m_list.size());
}
void SUIMissionWnd::setProgress(int slotIndex, int curProgress)
{
std::string progressNotice;
if (m_objects.setProgress(slotIndex, curProgress, this, progressNotice))
{
if (0 < curProgress)
{
/// 진행률 공지 출력
m_pGameManager->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NOTICE, true ) );
m_pGameManager->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NOTICE, "questupdate", progressNotice.c_str() ) );
}
}
}
void SUIMissionWnd::refresh()
{
setTitle(m_title.c_str());
setReward(m_reward.c_str());
m_objects.update(this);
setObjectCount(m_objects.m_list.size());
}
void SUIMissionWnd::clearData()
{
m_objects.clear();
m_title.clear();
m_reward.clear();
setObjectCount(0);
}