407 lines
9.8 KiB
C++
407 lines
9.8 KiB
C++
|
|
#include "stdafx.h"
|
|
#include "SUIWorldMapMonsterRegion.h"
|
|
#include "SUIWorldMapWnd.h"
|
|
#include "SQuestMgr.h"
|
|
//#include "KUIControl.h"
|
|
#include "SMonsterDB.h"
|
|
#include "SFieldPropResourceDB.h"
|
|
#include "SItemDB.h"
|
|
#include "SQuestLinkDB.h"
|
|
#include <toolkit/bits_scramble.h>
|
|
#include <toolkit/XStringUtil.h>
|
|
#include "SQuestDB.h"
|
|
#include "PropRespawnRegionExtractor.h"
|
|
|
|
void sMonsterRegionInfo::sNpcList::clear()
|
|
{
|
|
m_npcId.clear();
|
|
m_wnd.clear();
|
|
}
|
|
|
|
void sMonsterRegionInfo::sNpcList::clearNpcId()
|
|
{
|
|
m_npcId.clear();
|
|
}
|
|
|
|
void sMonsterRegionInfo::sNpcList::hide()
|
|
{
|
|
std::vector<KUIControl*>::iterator it = m_wnd.begin();
|
|
for (; it != m_wnd.end(); ++it)
|
|
(*it)->SetShow(false);
|
|
}
|
|
|
|
/// m_wnd의 유효한 개수 체크
|
|
void sMonsterRegionInfo::sNpcList::checkValidWnd(SUIWorldMapWnd* parentWnd)
|
|
{
|
|
if (m_npcId.size() > m_wnd.size())
|
|
{
|
|
std::string strId;
|
|
size_t npcSize = m_npcId.size();
|
|
size_t i = m_wnd.size();
|
|
for (; i < npcSize; ++i)
|
|
{
|
|
XStringUtil::Format(strId, "questTargetNpc%d", i);
|
|
KUIControl* wnd = dynamicCast<KUIControl*>(parentWnd->createQuestMarkNpcControl(strId.c_str()));
|
|
if (wnd)
|
|
m_wnd.push_back(wnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sMonsterRegionInfo::sNpcList::apply(SUIWorldMapWnd* parentWnd)
|
|
{
|
|
if (m_npcId.empty())
|
|
return ;
|
|
|
|
checkValidWnd(parentWnd);
|
|
|
|
/// hide wnd
|
|
for (size_t i = 0; i < m_wnd.size(); ++i)
|
|
{
|
|
m_wnd[i]->SetShow(false);
|
|
}
|
|
|
|
KRect r;
|
|
size_t count = m_npcId.size();
|
|
for (size_t i = 0; i < count; ++i)
|
|
{
|
|
if (parentWnd->getQuestMarkNpcUIRect(m_npcId[i], r))
|
|
{
|
|
m_wnd[i]->SetRect(r);
|
|
m_wnd[i]->UpdateBack();
|
|
m_wnd[i]->SetShow(true);
|
|
parentWnd->SetChildAsTop(m_wnd[i]->GetID());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
sMonsterRegionInfo::sMonsterRegionInfo() : m_questCode(0)
|
|
{
|
|
}
|
|
|
|
sMonsterRegionInfo::~sMonsterRegionInfo()
|
|
{
|
|
m_monsterMaxRegionList.clear();
|
|
m_monsterMinRegionList.clear();
|
|
m_itemMaxRegionList.clear();
|
|
m_itemMinRegionList.clear();
|
|
m_childList.clear();
|
|
m_mobList.clear();
|
|
m_itemList.clear();
|
|
m_npcList.clear();
|
|
}
|
|
|
|
void sMonsterRegionInfo::initialize(SUIWorldMapWnd* parentWnd)
|
|
{
|
|
cPropRespawnRegionExtractor propExtractor;
|
|
//propExtractor.extract(); /// 2011.08.26 item 리젠 지역 추출(추출후 주석처리 해야 됨) - prodongi
|
|
propExtractor.readData("itemMaxRegion.lst", m_itemMaxRegionList);
|
|
propExtractor.readData("itemMinRegion.lst", m_itemMinRegionList);
|
|
|
|
cMonsterRespawnRegionExtractor extractor;
|
|
//extractor.extract(); /// 2011.08.26 몬스터 리젠 지역 추출(추출후 주석처리 해야 됨) - prodongi
|
|
extractor.readData("monsterMaxRegion.lst", m_monsterMaxRegionList);
|
|
extractor.readData("monsterMinRegion.lst", m_monsterMinRegionList);
|
|
}
|
|
|
|
void sMonsterRegionInfo::clearChild(SUIWorldMapWnd *parentWnd)
|
|
{
|
|
v_childWnd::iterator it_child = m_childList.begin();
|
|
for (; it_child != m_childList.end(); ++it_child)
|
|
{
|
|
parentWnd->addRemoveWndList(it_child->m_wnd);
|
|
}
|
|
m_childList.clear();
|
|
m_npcList.hide();
|
|
|
|
/// npc를 지우기 전에 디테일 월드맵에 완료로 바뀐 npc 아이콘을 복구해준다
|
|
parentWnd->restoreNpcIconToOriginal(m_npcList.m_npcId);
|
|
m_npcList.clearNpcId();
|
|
}
|
|
|
|
void sMonsterRegionInfo::process(DWORD t)
|
|
{
|
|
v_childWnd::iterator it_child = m_childList.begin();
|
|
for (; it_child != m_childList.end(); ++it_child)
|
|
{
|
|
it_child->m_wnd->Process(t);
|
|
}
|
|
}
|
|
|
|
template <typename T, typename MAX_T, typename MIN_T>
|
|
void sMonsterRegionInfo::apply(int id, SUIWorldMapWnd *parentWnd, bool isMax, MAX_T* maxList, MIN_T* minList, int type)
|
|
{
|
|
std::map<int, T>* regionList;
|
|
if (isMax) regionList = maxList;
|
|
else regionList = minList;
|
|
|
|
std::map<int, T>::iterator it_mr = regionList->find(id);
|
|
if (it_mr == regionList->end())
|
|
return ;
|
|
|
|
KRect uiRect;
|
|
KPoint worldPos, uiPos;
|
|
|
|
T::it_region it_r = it_mr->second.m_regionList.begin();
|
|
for (; it_r != it_mr->second.m_regionList.end(); ++it_r)
|
|
{
|
|
worldPos.x = it_r->m_rect.left;
|
|
worldPos.y = it_r->m_rect.top;
|
|
parentWnd->convertWorldToUiPos(worldPos, uiPos);
|
|
uiRect.left = uiPos.x;
|
|
uiRect.top = uiPos.y;
|
|
|
|
worldPos.x = it_r->m_rect.right;
|
|
worldPos.y = it_r->m_rect.bottom;
|
|
parentWnd->convertWorldToUiPos(worldPos, uiPos);
|
|
uiRect.right = uiPos.x;
|
|
uiRect.bottom = uiPos.y;
|
|
|
|
if (uiRect.top > uiRect.bottom)
|
|
std::swap(uiRect.top, uiRect.bottom);
|
|
|
|
/// 최소 크기 설정
|
|
if (MIN_RECT_LEN > uiRect.GetWidth())
|
|
{
|
|
int s = (MIN_RECT_LEN - uiRect.GetWidth()) >> 1;
|
|
uiRect.left -= s;
|
|
uiRect.right += s;
|
|
}
|
|
if (MIN_RECT_LEN > uiRect.GetHeight())
|
|
{
|
|
int s = (MIN_RECT_LEN - uiRect.GetHeight()) >> 1;
|
|
uiRect.top -= s;
|
|
uiRect.bottom += s;
|
|
}
|
|
|
|
KRect newR;
|
|
if (!parentWnd->convertInvalidMonsterRegion(uiRect, newR))
|
|
continue;
|
|
|
|
if (!checkIncludeRegion(newR, id))
|
|
{
|
|
KUIWnd* child = parentWnd->createMonsterRegionControl(newR, it_r->m_theta);
|
|
if (child)
|
|
{
|
|
sChildWnd childWnd(child, id, type);
|
|
m_childList.push_back(childWnd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool sMonsterRegionInfo::checkIncludeRegion(KRect const& uiRect, int id)
|
|
{
|
|
struct sCheckRegion
|
|
{
|
|
bool isIn(KRect const& r, KRect const& c_r)
|
|
{
|
|
if (isIn(r, c_r.left, c_r.top) && isIn(r, c_r.right, c_r.top) &&
|
|
isIn(r, c_r.left, c_r.bottom) && isIn(r, c_r.right, c_r.bottom))
|
|
return true;
|
|
return false;
|
|
}
|
|
bool isIn(KRect const& r, int x, int y)
|
|
{
|
|
if (r.left <= x && r.right >= x && r.top <= y && r.bottom >= y)
|
|
return true;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
sCheckRegion check;
|
|
v_childWnd::iterator it_child = m_childList.begin();
|
|
for (; it_child != m_childList.end(); ++it_child)
|
|
{
|
|
KUIWnd* wnd = it_child->m_wnd;
|
|
if (check.isIn(wnd->GetRect(), uiRect))
|
|
{
|
|
it_child->addToolTipList(id);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool sMonsterRegionInfo::setQuestCode(int code, SUIWorldMapWnd *parentWnd)
|
|
{
|
|
m_mobList.clear();
|
|
m_itemList.clear();
|
|
clearChild(parentWnd);
|
|
|
|
m_questCode = code;
|
|
SQuestMgr::GetInstance().getMonsterList(code, m_mobList);
|
|
SQuestMgr::GetInstance().getItemList(code, m_itemList);
|
|
setNpcList(code, parentWnd);
|
|
setQuestMarkTarget(code); /// 맨 마지막에 호출 되어야 한다
|
|
|
|
return true;
|
|
}
|
|
|
|
void sMonsterRegionInfo::setQuestMarkTarget(int code)
|
|
{
|
|
int type, id;
|
|
bool hide;
|
|
|
|
if (!SQuestMgr::GetInstance().getMarkProp((QuestBase::QuestCode)code, type, id, hide))
|
|
return ;
|
|
|
|
if (hide)
|
|
return ;
|
|
if (QuestBase::QUEST_MARK_TARGET_DEFAULT == type)
|
|
return ;
|
|
if (0 == id)
|
|
return;
|
|
|
|
if (QuestBase::QUEST_MARK_TARGET_MOB == type)
|
|
{
|
|
m_mobList.push_back(id);
|
|
}
|
|
else if (QuestBase::QUEST_MARK_TARGET_NPC == type)
|
|
{
|
|
m_npcList.m_npcId.push_back(id);
|
|
}
|
|
else if (QuestBase::QUEST_MARK_TARGET_PROP == type)
|
|
{
|
|
FieldPropResource* res = GetFieldPropResourceDB().GetFieldPropResource(id);
|
|
if (res)
|
|
{
|
|
if (res->drop_item_id_00)
|
|
m_itemList.push_back(res->drop_item_id_00);
|
|
if (res->drop_item_id_01)
|
|
m_itemList.push_back(res->drop_item_id_01);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sMonsterRegionInfo::setNpcList(int code, SUIWorldMapWnd *parentWnd)
|
|
{
|
|
if (0 == code)
|
|
return ;
|
|
|
|
int progress = SQuestMgr::GetInstance().GetQuestProgress(code);
|
|
if (SQuestMgr::STARTABLE == progress)
|
|
return ;
|
|
|
|
QuestLinkEx* ex = GetQuestLinkDB().GetQuestLinkData(code);
|
|
if (!ex)
|
|
return ;
|
|
|
|
if (SQuestMgr::FINISHABLE == progress)
|
|
{
|
|
m_npcList.m_npcId = ex->endNpcId;
|
|
parentWnd->changeNpcIconToFinish(m_npcList.m_npcId);
|
|
}
|
|
else if (SQuestMgr::IN_PROGRESS == progress)
|
|
{
|
|
QuestBase* quest = GetQuestDB().GetQuestData(code);
|
|
if (!quest)
|
|
return ;
|
|
|
|
int type = quest->nType;
|
|
if (QuestBase::QuestType::QUEST_LEARN_SKILL == type ||
|
|
QuestBase::QuestType::QUEST_UPGRADE_ITEM == type ||
|
|
QuestBase::QuestType::QUEST_CONTACT == type ||
|
|
QuestBase::QuestType::QUEST_JOB_LEVEL == type ||
|
|
QuestBase::QuestType::QUEST_PARAMETER == type ||
|
|
QuestBase::QuestType::QUEST_OUT_OF_CONTROL == type)
|
|
{
|
|
m_npcList.m_npcId = ex->startNpcId;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sMonsterRegionInfo::apply(SUIWorldMapWnd* parentWnd, bool maxList)
|
|
{
|
|
if (0 == m_questCode)
|
|
return ;
|
|
if (!checkValidQuestCode(parentWnd))
|
|
return ;
|
|
|
|
std::vector<int>::iterator it;
|
|
for (it = m_mobList.begin(); it != m_mobList.end(); ++it)
|
|
{
|
|
apply<ex_sMonsterRegion>(*it, parentWnd, maxList, &m_monsterMaxRegionList, &m_monsterMinRegionList, MOB);
|
|
}
|
|
for (it = m_itemList.begin(); it != m_itemList.end(); ++it)
|
|
{
|
|
apply<ex_sItemRegion>(*it, parentWnd, maxList, &m_itemMaxRegionList, &m_itemMinRegionList, ITEM);
|
|
}
|
|
|
|
m_npcList.apply(parentWnd);
|
|
|
|
setToolTip();
|
|
}
|
|
|
|
void sMonsterRegionInfo::refresh(SUIWorldMapWnd* parentWnd, bool maxList)
|
|
{
|
|
if (!setQuestCode(m_questCode, parentWnd))
|
|
return ;
|
|
apply(parentWnd, maxList);
|
|
}
|
|
|
|
bool sMonsterRegionInfo::checkValidQuestCode(SUIWorldMapWnd* parentWnd)
|
|
{
|
|
if (!SQuestMgr::GetInstance().IsAddQuest(m_questCode))
|
|
{
|
|
setQuestCode(0, parentWnd);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void sMonsterRegionInfo::setToolTip()
|
|
{
|
|
std::string name;
|
|
v_childWnd::iterator it_child = m_childList.begin();
|
|
for (; it_child != m_childList.end(); ++it_child)
|
|
{
|
|
name.clear();
|
|
std::vector<int>::iterator it_id;
|
|
|
|
if (MOB == it_child->m_type)
|
|
{
|
|
if (!it_child->m_toolTipList.empty())
|
|
{
|
|
it_id = it_child->m_toolTipList.begin();
|
|
int nameId = GetMonsterDB().GetTextID(bits_scramble<int, 3>(*it_id));
|
|
name += S(nameId);
|
|
++it_id;
|
|
}
|
|
for (; it_id != it_child->m_toolTipList.end(); ++it_id)
|
|
{
|
|
name += "<br>";
|
|
int nameId = GetMonsterDB().GetTextID(bits_scramble<int, 3>(*it_id));
|
|
name += S(nameId);
|
|
}
|
|
}
|
|
else if (ITEM == it_child->m_type)
|
|
{
|
|
if (!it_child->m_toolTipList.empty())
|
|
{
|
|
it_id = it_child->m_toolTipList.begin();
|
|
ItemBaseEx_info const* itemInfo = GetItemDB().GetItemData(*it_id);
|
|
if (itemInfo)
|
|
{
|
|
name += S(itemInfo->nNameId);
|
|
}
|
|
++it_id;
|
|
}
|
|
for (; it_id != it_child->m_toolTipList.end(); ++it_id)
|
|
{
|
|
name += "<br>";
|
|
ItemBaseEx_info const* itemInfo = GetItemDB().GetItemData(*it_id);
|
|
if (itemInfo)
|
|
{
|
|
name += S(itemInfo->nNameId);
|
|
}
|
|
}
|
|
}
|
|
|
|
KUIControl* control = dynamicCast<KUIControl*>(it_child->m_wnd);
|
|
if (control)
|
|
control->SetTooltip(name.c_str());
|
|
}
|
|
} |