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

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());
}
}