#include "stdafx.h" #include "SUIMissionWnd.h" #include "SGameManager.h" #include "SGameOption.h" #include #include "KUIControlButton.h" #include "SGameMessage.h" #include "SChatType.h" #include "SStringDB.h" extern void MsgSplit( const char* szMsg, std::vector& 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(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::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::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, "%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, "%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::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(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(pMsg); if (CHAT_DUNGEON_SYSTEM == msg->nChatType) { if ("@DUNGEON" == msg->szSender) { std::vector strList; MsgSplit(msg->strText.c_str(), strList, L"|"); procChatMsg(strList); strList.clear(); } } } break; } SUIWnd::ProcMsgAtStatic(pMsg); } void SUIMissionWnd::procChatMsg(std::vector 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, "<#1d8ae7f><@292929>%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); }