199 lines
5.0 KiB
C++
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
|
|
|
|
|
|
|
|
|
|
|