Files
Leviathan/Client/Game/game/Utility/MonsterRespawnRegionExtractor.h
T
2026-06-01 12:46:52 +02:00

199 lines
5.0 KiB
C++

#ifndef _MonsterRespawnRegionExtractor_h_
#define _MonsterRespawnRegionExtractor_h_
#include <map>
//#include <vector>
#include "KTypes.h"
#include "ScriptDefine.h"
class KStream;
/* 몬스터 리젠 지역 추출 클래스
실행 될 때마다 뽑는건 비효율적이기 때문에
데이타가 변결될 때, 호출해서 관련 데이타를 뽑아야 한다.
*/
class cMonsterRespawnRegionExtractor
{
private:
struct sEventMonster
{
~sEventMonster() { m_monsterList.clear(); }
bool add(int id);
int m_eventId;
std::vector<int> m_monsterList;
};
struct sEventRegion
{
~sEventRegion() { m_regionList.clear(); }
bool add(int regionIndex, SCRIPTFUNC_LIST const& scriptList, std::vector<KRect> const& regionList);
int getEventId(SCRIPTFUNC_LIST const& scriptList);
int m_eventId;
std::vector<KRect> m_regionList;
};
struct sCorMatrix
{
private:
struct sCenter
{
sCenter() {}
sCenter(float x, float y) { v[0] = x; v[1] = y; }
float v[2];
};
public:
void make(std::vector<KRect> const& rectList)
{
// 중점
std::vector<sCenter> centerList;
makeCenter(rectList, centerList);
// 평균
float ave[2];
makeAverage(centerList, ave);
float x_ij, x_ik;
int n = rectList.size();
float f_n = (float)n;
for (int j = 0; j < 2; ++j)
{
for (int k = 0; k < 2; ++k)
{
float value = 0;
for (int i = 0; i < n; ++i)
{
x_ij = centerList[i].v[j];
x_ik = centerList[i].v[k];
value += (x_ij - ave[j]) * (x_ik - ave[k]);
}
value /= f_n;
v[j][k] = value;
}
}
centerList.clear();
}
private:
void makeAverage(std::vector<sCenter> const& centerList, float* ave)
{
float _ave[2] = {0.0f, 0.0f};
int n = centerList.size();
for (int i = 0; i < n; ++i)
{
_ave[0] += centerList[i].v[0];
_ave[1] += centerList[i].v[1];
}
_ave[0] /= (float)n;
_ave[1] /= (float)n;
ave[0] = _ave[0];
ave[1] = _ave[1];
};
void makeCenter(std::vector<KRect> const& rectList, std::vector<sCenter>& centerList)
{
std::vector<KRect>::const_iterator it = rectList.begin();
for (; it != rectList.end(); ++it)
{
int x = (it->left + it->right) >> 1;
int y = (it->top + it->bottom) >> 1;
centerList.push_back(sCenter((float)x, (float)y));
}
}
public:
float v[2][2];
};
public:
struct sMonsterRegionRect
{
sMonsterRegionRect() {}
sMonsterRegionRect(KRect const& rect, bool isAddGroup = true)
{
setRect(rect);
if (isAddGroup)
addGroup(rect);
}
~sMonsterRegionRect()
{
m_groupRectList.clear();
}
void addGroup(KRect const& rect)
{
m_groupRectList.push_back(rect);
}
void setRect(KRect const& rect)
{
m_rect = rect;
}
void reSize(int w, int h)
{
int cx = (m_rect.right + m_rect.left) >> 1;
int cy = (m_rect.bottom + m_rect.top) >> 1;
int hw = w >> 1;
int hh = h >> 1;
m_rect.left = cx - hw;
m_rect.right = cx + hw;
m_rect.top = cy - hh;
m_rect.bottom = cy + hh;
}
std::vector<KRect> m_groupRectList; /// 그룹된 rect들
KRect m_rect;
float m_theta;
};
struct sMonsterRegion
{
typedef std::vector<sMonsterRegionRect> v_region;
typedef std::vector<sMonsterRegionRect>::iterator it_region;
typedef std::vector<sMonsterRegionRect>::const_iterator cit_region;
~sMonsterRegion() { m_regionList.clear(); }
int m_monsterId;
std::vector<sMonsterRegionRect> m_regionList;
};
public:
~cMonsterRespawnRegionExtractor();
bool extract();
bool readData(char const* filename, std::map<int, sMonsterRegion>& monsterRegionList);
private:
/// *.nfs 파일에서 이벤트 id별 지역 정보를 구함
bool extractNfs();
/// monster_respawn.lua 파일에서 이벤트 id별 리젠되는 몬스터 id를 구함
bool extractLua();
std::string assignString(char const* buffer, char* openStr, char* closeStr);
void LoadScriptFileForVer01(KStream* pStream, int nMapX, int nMapY );
void LoadScriptFileForVer02(KStream* pStream, int nMapX, int nMapY );
int LoadEvLocScriptFuncListForV01( KStream* pStream, SCRIPTFUNC_LIST& rScriptFuncList );
bool getSeamlessWorldInfo();
void addEventRegion(sEventRegion const& eventRegion);
/// m_eventMonsterList와 m_eventRegionList를 통합해서 m_monsterRegionList를 만듬
bool unifyData();
bool writeData(char const* filename, std::map<int, sMonsterRegion> const& monsterRegionList);
/// 일정한 거리로 그룹화
void grouping(std::map<int, sMonsterRegion>& monsterRegionList, int groupLength);
int getRectLength(KRect const& r1, KRect const& r2);
KRect getGroupRect(KRect const& r1, KRect const& r2);
void calcCovariance(std::map<int, sMonsterRegion>& monsterRegion);
private:
std::map<int, sEventMonster> m_eventMonsterList; /// map<eventId, sEventMonster>
std::map<int, sEventRegion> m_eventRegionList; /// map<eventId, sEventRegion>
std::map<int, sMonsterRegion> m_monsterRegionList; /// map<monsterId, sMonsterRegion>
int m_segmentCountPerMap;
int m_tileCountPerSegment;
int m_tileCountPerMap;
float m_tileLength;
};
#endif