1029 lines
29 KiB
C++
1029 lines
29 KiB
C++
#include "stdafx.h"
|
|
#include "SSkillDB.h"
|
|
|
|
#include <Windows.h>
|
|
#include <kfile/KStream.h>
|
|
#include "KTypes.h"
|
|
#include <kfile/KFileManager.h>
|
|
#include <toolkit/XStringUtil.h>
|
|
#include "SkillBaseFile.h"
|
|
#include "SNetMessage.h"
|
|
#include <toolkit/IRecordSet.h>
|
|
//#include "Util.h"
|
|
|
|
#include "KResourceManager.h"
|
|
#include "Slog.h"
|
|
#include "SJobDB.h"
|
|
|
|
#include "SDebug_Util.h"
|
|
#include "AR_DIFF.h"
|
|
extern HWND g_hWnd;
|
|
|
|
|
|
SSkillDB::SSkillDB()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SSkillDB::~SSkillDB()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
/// 2011.05.27 AR_TIME -> long - prodongi
|
|
long SSkillDB::GetCastingTime( int nSkillID, int nSkill_lv )
|
|
{
|
|
SkillBaseEx * pData = GetSkillData( nSkillID );
|
|
if( pData )
|
|
{
|
|
return pData->GetCastDelay( nSkill_lv );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool SSkillDB::IsNeedTarget( int nSkillID )
|
|
{
|
|
SkillBaseEx * pData = GetSkillData( nSkillID );
|
|
if( pData )
|
|
{
|
|
return pData->IsNeedTarget();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
SkillBaseEx * SSkillDB::GetSkillData( int nSkillID )
|
|
{
|
|
SkillBaseEx * pFindSkill = NULL;
|
|
if( m_hashSkill.lookup( nSkillID, pFindSkill ) == false )
|
|
{
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
return pFindSkill;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int SSkillDB::GetToolTipID( int nSkillID )
|
|
{
|
|
SkillBaseEx * pSkill = GetSkillData( nSkillID );
|
|
if( pSkill )
|
|
{
|
|
return pSkill->GetToolTipID();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char * SSkillDB::GetIconName( int nSkillID )
|
|
{
|
|
SkillBaseEx * pSkill = GetSkillData( nSkillID );
|
|
if( pSkill )
|
|
{
|
|
return pSkill->GetIconName();
|
|
}
|
|
|
|
return "NotFound";
|
|
}
|
|
|
|
int SSkillDB::GetIconID( int nSkillID )
|
|
{
|
|
SkillBaseEx * pSkill = GetSkillData( nSkillID );
|
|
if( pSkill )
|
|
{
|
|
return pSkill->GetIconID();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int SSkillDB::GetStringID( int nSkillID )
|
|
{
|
|
SkillBaseEx * pSkill = GetSkillData( nSkillID );
|
|
if( pSkill )
|
|
{
|
|
return pSkill->GetNameID();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SSkillDB::Init()
|
|
{
|
|
Load();
|
|
}
|
|
|
|
void SSkillDB::Destroy()
|
|
{
|
|
SkillBaseEx* pSkill = NULL;
|
|
bool res;
|
|
res = m_hashSkill.get_first_value( pSkill );
|
|
while ( res )
|
|
{
|
|
if ( pSkill != NULL )
|
|
{
|
|
delete pSkill;
|
|
}
|
|
res = m_hashSkill.get_next_value( pSkill );
|
|
}
|
|
m_hashSkill.clear();
|
|
}
|
|
|
|
inline bool GetRecordSetFromResource( XRecordSet< wchar_t > & rs, const char *szFileName )
|
|
{
|
|
KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( szFileName );
|
|
if( !pRes1 ) return false;
|
|
char *p = (char*)pRes1->GetMappedPtr( 0 ) + 2;
|
|
basic_string< wchar_t > tstr( (wchar_t*)p, pRes1->GetLength()/2 - 1 );
|
|
basic_stringstream< wchar_t > temp( tstr );
|
|
DWORD tm = GetSafeTickCount();
|
|
rs.LoadFrom( temp );
|
|
//_oprint( "SkillLoad : %dms\n", GetSafeTickCount() - tm ); 릴리즈모드에서는 보통 50~100ms 안에 끝남.
|
|
KFileManager::Instance().DeleteStream( pRes1 );
|
|
return true;
|
|
}
|
|
|
|
void SSkillDB::Load()
|
|
{
|
|
// 텍스트 파일에서 바로 읽는것 만들다 말았음. -_- by Testors
|
|
bool bNewLoader = false;
|
|
if( bNewLoader )
|
|
{
|
|
XRecordSet< wchar_t > recordset;
|
|
if( GetRecordSetFromResource( recordset, "SkillResource.txt" ) )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
//New Data
|
|
KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( "db_skill.rdb" );
|
|
if( !pRes1 ) return;
|
|
GAME_DB db_hdr;
|
|
|
|
pRes1->Read( &db_hdr, sizeof(db_hdr) );
|
|
|
|
//// RDB 와 Header의 사이즈 비교.
|
|
|
|
////// TEST
|
|
//SkillBaseEx testEX;
|
|
//char sdfdsf[256] = { NULL, };
|
|
//sprintf( sdfdsf, "size : %d, offset : %d", testEX.GetRealSize(), testEX.GetOffset() );
|
|
//::MessageBox( g_hWnd, sdfdsf, "Error", MB_OK );
|
|
|
|
//int fileSize = pRes1->Size() - ( STR_DATE_BUFFER + sizeof( int ) );
|
|
|
|
//char sstr[512] = { NULL, };
|
|
//sprintf( sstr, "%d , %d, %d", sizeof(SkillBase), sizeof(SkillBaseEx), db_hdr.nCount );
|
|
//::MessageBox( g_hWnd, sstr, "Error", MB_OK );
|
|
|
|
////int headerSize = sizeof(SkillBaseEx) * db_hdr.nCount;
|
|
//int headerSize = 833 * db_hdr.nCount;
|
|
//if( fileSize != headerSize )
|
|
//{
|
|
// char str[512] = { NULL, };
|
|
// sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ",
|
|
// db_hdr.szDate,
|
|
// __FILE__,
|
|
// fileSize,
|
|
// headerSize
|
|
// );
|
|
//
|
|
// ::MessageBox( g_hWnd, str, "Error", MB_OK );
|
|
//
|
|
// if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES )
|
|
// {
|
|
// exit( 1 );
|
|
// }
|
|
//}
|
|
|
|
////// RDB 와 Header의 사이즈 비교.
|
|
//int fileSize = pRes1->Size() - ( STR_DATE_BUFFER + sizeof( int ) );
|
|
//int headerSize = sizeof(SkillBaseEx) * db_hdr.nCount;
|
|
//
|
|
//if( fileSize != headerSize )
|
|
//{
|
|
// char str[512] = { NULL, };
|
|
// sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ",
|
|
// db_hdr.szDate,
|
|
// __FILE__,
|
|
// fileSize,
|
|
// headerSize
|
|
// );
|
|
//
|
|
// ::MessageBox( g_hWnd, str, "Error", MB_OK );
|
|
//
|
|
// if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES )
|
|
// {
|
|
// exit( 1 );
|
|
// }
|
|
//}
|
|
|
|
|
|
|
|
|
|
for( int i(0); db_hdr.nCount>i; i++ )
|
|
{
|
|
SkillBaseEx * pSkillBase = new SkillBaseEx;
|
|
pRes1->Read( pSkillBase, sizeof(SkillBaseEx) );
|
|
|
|
|
|
SkillBaseEx * pFindSkill = NULL;
|
|
if( m_hashSkill.lookup( pSkillBase->GetID(), pFindSkill ) == false )
|
|
{
|
|
/* #ifdef _DEV
|
|
if(KSpriteManager::GetManager()->GetResSpriteAni("ui_frame.spr", pSkillBase->GetIconName() ) == NULL)
|
|
{
|
|
GetLog().DebugLog( "SkillDB - spr에 icon 파일이 등록되지 않았습니다 - id:%d / icon id:%d / %s \n",
|
|
pSkillBase->GetID(), pSkillBase->GetIconID(), pSkillBase->GetIconName() );
|
|
}
|
|
#endif*/
|
|
//이유는 알 수 없으나 위 코드가 있으면 리소스를 제대로 읽지 못함 2009.07.06. sfreer
|
|
|
|
m_hashSkill.add( pSkillBase->GetID(), pSkillBase );
|
|
}
|
|
else
|
|
{
|
|
//_oprint( "!!!!Data Error Item Code 가 중복되었습니다.!!!! %d\n", pSkillBase->GetID() );
|
|
// GetLog().DebugLog( "!!!!Data Error Skill Code 가 중복되었습니다.!!!! %d\n", pSkillBase->GetID() );
|
|
// assert(0); //기획팀에 알려 주세여. 바로 수정 해야 합니다.
|
|
|
|
delete pSkillBase;
|
|
}
|
|
}
|
|
KFileManager::Instance().DeleteStream( pRes1 );
|
|
|
|
|
|
#ifdef _COUNTRY_ME_
|
|
///////////////////////////////////////////////////
|
|
// EXCEPTION///////////////////////////////////////
|
|
for (int i=0;i<MAX_EXCEPTION_AR;i++)
|
|
{
|
|
STRUCT_SKILL_DIFF * ps = &g_pException_AR[i];
|
|
SkillBaseEx * pSkill = GetSkillData( ps->uid ); if (pSkill==NULL) continue;
|
|
|
|
int type = ps->type; if (type==0) continue;
|
|
float old_value = ps->old_value;
|
|
float new_value = ps->new_value;
|
|
//float cmp_value = 0.0f;
|
|
//if (type >= 1 && type <=20) cmp_value = pSkill->var[type-1];
|
|
//if (type == 21) cmp_value = pSkill->delay_cooltime;
|
|
//if (type == 22) cmp_value = pSkill->delay_cast_per_skl;
|
|
//if (old_value!= cmp_value)
|
|
// _cprint( "g_pException_AR:%d type:%d old:%.2f(%.2f) new:%.2f\n", ps->uid,type,old_value,cmp_value,new_value);
|
|
if (type >= 1 && type <=20) pSkill->var[type-1] = new_value; else
|
|
if (type == 21) pSkill->delay_cooltime = new_value*100; else
|
|
if (type == 22) pSkill->state_second_per_skl= new_value*100;
|
|
}
|
|
|
|
for (int i=0;i<MAX_EXCEPTION_921;i++)
|
|
{
|
|
STRUCT_SKILL_DIFF * ps = &g_pException_921[i];
|
|
SkillBaseEx * pSkill = GetSkillData( ps->uid ); if (pSkill==NULL) continue;
|
|
|
|
int type = ps->type; if (type==0) continue;
|
|
float old_value = ps->old_value;
|
|
float new_value = ps->new_value;
|
|
//float cmp_value = 0.0f;
|
|
//if (type >= 1 && type <=20) cmp_value = pSkill->var[type-1];
|
|
//if (type == 21) cmp_value = pSkill->delay_cooltime;
|
|
//if (type == 22) cmp_value = pSkill->delay_cast_per_skl;
|
|
//if (old_value!= cmp_value)
|
|
// _cprint( "g_pException_921:%d type:%d old:%.2f(%.2f) new:%.2f\n", ps->uid,type,old_value,cmp_value,new_value);
|
|
if (type >= 1 && type <=20) pSkill->var[type-1] = new_value; else
|
|
if (type == 21) pSkill->delay_cooltime = new_value*100; else
|
|
if (type == 22) pSkill->state_second_per_skl= new_value*100;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
SSkillDB* SSkillDB::m_pThis = NULL;
|
|
SSkillDB & GetSkillDB()
|
|
{
|
|
if( NULL == SSkillDB::m_pThis )
|
|
SSkillDB::m_pThis = new SSkillDB;
|
|
|
|
return *SSkillDB::m_pThis;
|
|
// static SSkillDB skilldb;
|
|
// return skilldb;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//스킬 트리 Display~
|
|
|
|
|
|
SSkillTreeDisplayDB::SSkillTreeDisplayDB()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SSkillTreeDisplayDB::~SSkillTreeDisplayDB()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
SSkillTreeDisplayDB::SKILL_TREE::~SKILL_TREE()
|
|
{
|
|
for( unsigned int i(0); job_tree_list.size()>i; i++ )
|
|
{
|
|
delete job_tree_list[i];
|
|
}
|
|
job_tree_list.clear();
|
|
}
|
|
|
|
void SSkillTreeDisplayDB::Init()
|
|
{
|
|
Load();
|
|
}
|
|
|
|
void SSkillTreeDisplayDB::Destroy()
|
|
{
|
|
for( unsigned int i(0); tree_list.size()>i; i++ )
|
|
{
|
|
delete tree_list[i];
|
|
}
|
|
|
|
tree_list.clear();
|
|
}
|
|
|
|
void SSkillTreeDisplayDB::GetSkillTree( int nJobID, vector<SkillTreeDisplay* >& skill_tree )
|
|
{
|
|
for( unsigned int i(0); tree_list.size()>i; i++ )
|
|
{
|
|
SKILL_TREE* pData = tree_list[i];
|
|
if( pData->nJobID == nJobID )
|
|
{
|
|
for( unsigned int n(0); pData->job_tree_list.size()>n; n++ )
|
|
{
|
|
skill_tree.push_back( pData->job_tree_list[n] );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SSkillTreeDisplayDB::addTreeData( const SkillTreeDisplay* pNewData )
|
|
{
|
|
for( unsigned int i(0); tree_list.size()>i; i++ )
|
|
{
|
|
SKILL_TREE* pData = tree_list[i];
|
|
if( pData->nJobID == pNewData->job_id )
|
|
{
|
|
SkillTreeDisplay* pSkillData = new SkillTreeDisplay;
|
|
pSkillData->job_id = pNewData->job_id;
|
|
pSkillData->slot_v = pNewData->slot_v;
|
|
pSkillData->skill1_id = pNewData->skill1_id;
|
|
pSkillData->skill2_id = pNewData->skill2_id;
|
|
pSkillData->skill3_id = pNewData->skill3_id;
|
|
pSkillData->skill4_id = pNewData->skill4_id;
|
|
pSkillData->skill5_id = pNewData->skill5_id;
|
|
|
|
pData->job_tree_list.push_back( pSkillData );
|
|
|
|
assert( pData->job_tree_list.size() <= 9 && "한 직업당 스킬 슬롯이 9개 이상임" );
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// _performance_print( "%d JOB : %d\n", tree_list.size(), pNewData->job_id );
|
|
|
|
SKILL_TREE* pSkill_tree = new SKILL_TREE;
|
|
pSkill_tree->nJobID = pNewData->job_id;
|
|
|
|
SkillTreeDisplay* pSkillData = new SkillTreeDisplay;
|
|
pSkillData->job_id = pNewData->job_id;
|
|
pSkillData->slot_v = pNewData->slot_v;
|
|
pSkillData->skill1_id = pNewData->skill1_id;
|
|
pSkillData->skill2_id = pNewData->skill2_id;
|
|
pSkillData->skill3_id = pNewData->skill3_id;
|
|
pSkillData->skill4_id = pNewData->skill4_id;
|
|
pSkillData->skill5_id = pNewData->skill5_id;
|
|
|
|
pSkill_tree->job_tree_list.push_back( pSkillData );
|
|
|
|
tree_list.push_back( pSkill_tree );
|
|
}
|
|
|
|
void SSkillTreeDisplayDB::Load()
|
|
{
|
|
//New Data
|
|
KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( "db_SkillTreeDisplay.rdb" );
|
|
if( !pRes1 ) return;
|
|
GAME_DB db_hdr;
|
|
|
|
pRes1->Read( &db_hdr, sizeof(db_hdr) );
|
|
|
|
//// RDB 와 Header의 사이즈 비교.
|
|
//int fileSize = pRes1->Size() - ( STR_DATE_BUFFER + sizeof( int ) );
|
|
//int headerSize = sizeof(SkillTreeDisplay) * db_hdr.nCount;
|
|
//
|
|
//if( fileSize != headerSize )
|
|
//{
|
|
// char str[512] = { NULL, };
|
|
// sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ",
|
|
// db_hdr.szDate,
|
|
// __FILE__,
|
|
// fileSize,
|
|
// headerSize
|
|
// );
|
|
//
|
|
// ::MessageBox( g_hWnd, str, "Error", MB_OK );
|
|
//
|
|
// if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES )
|
|
// {
|
|
// exit( 1 );
|
|
// }
|
|
//}
|
|
|
|
for( int i(0); db_hdr.nCount>i; i++ )
|
|
{
|
|
SkillTreeDisplay skilltreedisplay;
|
|
pRes1->Read( &skilltreedisplay, sizeof(skilltreedisplay) );
|
|
|
|
addTreeData( &skilltreedisplay );
|
|
}
|
|
KFileManager::Instance().DeleteStream( pRes1 );
|
|
}
|
|
|
|
SSkillTreeDisplayDB & GetSkillTreeDisplayDB()
|
|
{
|
|
static SSkillTreeDisplayDB skillTreeDisplayDB;
|
|
return skillTreeDisplayDB;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 스킬 트리 DB Struct
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 생성자
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
SSkillTreeDB::SSkillTreeDB()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 파괴자
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
SSkillTreeDB::~SSkillTreeDB()
|
|
{
|
|
auto pos = m_mapSkillTreeList.begin();
|
|
auto end = m_mapSkillTreeList.end();
|
|
|
|
for( ; pos != end; ++pos )
|
|
{
|
|
delete pos->second;
|
|
}
|
|
|
|
m_mapSkillTreeList.clear();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 초기화
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
void SSkillTreeDB::Init()
|
|
{
|
|
Load();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// RDB 파일 불러오기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
void SSkillTreeDB::Load()
|
|
{
|
|
KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( "db_skilltree.rdb" );
|
|
if( NULL == pRes1 )
|
|
{
|
|
SLOG( "[SSkillTreeDB] Create Stream Failed - [db_skilltree.rdb]" );
|
|
assert( NULL );
|
|
return ;
|
|
}
|
|
|
|
GAME_DB db_hdr;
|
|
|
|
pRes1->Read( &db_hdr, sizeof( db_hdr ) );
|
|
|
|
|
|
for( int i(0); db_hdr.nCount>i; i++ )
|
|
{
|
|
std::vector< SkillTreeEx >* _skillList = NULL;
|
|
int nTreeSize = 0;
|
|
pRes1->Read( &nTreeSize, sizeof( nTreeSize ) );
|
|
|
|
if( nTreeSize > 0 )
|
|
{
|
|
_skillList = new std::vector< SkillTreeEx >();
|
|
for( int nCount = 0; nTreeSize > nCount; nCount++ )
|
|
{
|
|
SkillTree SkillTreeTemp;
|
|
pRes1->Read( &SkillTreeTemp, sizeof( SkillTreeTemp ) );
|
|
|
|
SkillTreeEx stSkillTreeEx( SkillTreeTemp );
|
|
|
|
if( NULL != SkillTreeTemp.skill_group_id )
|
|
stSkillTreeEx.bIsRandomSkill = true;
|
|
|
|
_skillList->push_back( stSkillTreeEx );
|
|
}
|
|
|
|
m_mapSkillTreeList.insert( std::make_pair( _skillList->front().skill_tree_id, _skillList ) );
|
|
}
|
|
}
|
|
|
|
KFileManager::Instance().DeleteStream( pRes1 );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 스킬 ID를 넘겨 주면, 갖고 있는 모든 Job ID를 돌려 준다.
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
void SSkillTreeDB::GetJobList_hasSkill( int nSkillID, vector<int> & jobList )
|
|
{
|
|
auto vJobList = GetJobDB().GetJobAllData();
|
|
auto pos = vJobList.cbegin();
|
|
auto end = vJobList.cend();
|
|
|
|
for( ; pos != end; ++pos )
|
|
{
|
|
const JobInfoEx* pJob = (*pos);
|
|
|
|
auto pSkillTree = GetSkillTreeData( pJob->skill_tree_id );
|
|
auto tree_pos = pSkillTree->cbegin();
|
|
auto tree_end = pSkillTree->cend();
|
|
for( ; tree_pos != tree_end; ++tree_pos )
|
|
{
|
|
if( (*tree_pos).skill_id == nSkillID )
|
|
{
|
|
bool need_add = true;
|
|
for( size_t i(0); i<jobList.size(); ++i )
|
|
{
|
|
if( jobList[i] == pJob->id ) // TODO
|
|
{
|
|
need_add = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( need_add == true )
|
|
{
|
|
jobList.push_back( pJob->id );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 스킬 트리 데이터 얻기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
const vector< SkillTreeEx >* SSkillTreeDB::GetSkillTreeData( int nSkillTree )
|
|
{
|
|
auto pos = m_mapSkillTreeList.find( nSkillTree );
|
|
if( pos != m_mapSkillTreeList.end() )
|
|
{
|
|
return pos->second;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 스킬 최대 레벨 얻기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
int SSkillTreeDB::GetSkillMaxLevel( int nSkillTree, int nSkillId )
|
|
{
|
|
int Result = 0;
|
|
const vector< SkillTreeEx >* skill_tree = GetSkillTreeData( nSkillTree );
|
|
if( skill_tree != NULL )
|
|
{
|
|
auto pos = skill_tree->cbegin();
|
|
auto end = skill_tree->cend();
|
|
for( ; pos != end; ++pos )
|
|
{
|
|
const SkillTreeEx& sk = (*pos);
|
|
// 하나의 스킬 트리에서 같은 스킬이 여러개 나올수 있다.
|
|
if( sk.skill_tree_id == nSkillTree && sk.skill_id == nSkillId && Result < sk.max_skill_lv )
|
|
{
|
|
Result = sk.max_skill_lv;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 인스턴스 얻기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
SSkillTreeDB & GetSkillTreeDB()
|
|
{
|
|
static SSkillTreeDB skilltreedb;
|
|
return skilltreedb;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
SSkillStageDB::SSkillStageDB()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SSkillStageDB::~SSkillStageDB()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void SSkillStageDB::Init()
|
|
{
|
|
Load();
|
|
}
|
|
|
|
void SSkillStageDB::Destroy()
|
|
{
|
|
_SKILL_FX* pSkillFx = NULL;
|
|
bool res;
|
|
res = m_hashSkillFx.get_first_value( pSkillFx );
|
|
while ( res )
|
|
{
|
|
if ( pSkillFx != NULL )
|
|
{
|
|
delete pSkillFx;
|
|
}
|
|
res = m_hashSkillFx.get_next_value( pSkillFx );
|
|
}
|
|
m_hashSkillFx.clear();
|
|
}
|
|
|
|
void SSkillStageDB::Load()
|
|
{
|
|
KStream * pRes = KFileManager::Instance().CreateStreamFromResource( "db_SkillStage.rdb" );
|
|
if( !pRes ) return;
|
|
GAME_DB db_hdr;
|
|
|
|
pRes->Read( &db_hdr, sizeof(db_hdr) );
|
|
|
|
//// RDB 와 Header의 사이즈 비교.
|
|
//int fileSize = pRes->Size() - ( STR_DATE_BUFFER + sizeof( int ) );
|
|
//int headerSize = sizeof(_SKILL_FX) * db_hdr.nCount;
|
|
//if( fileSize != headerSize )
|
|
//{
|
|
// char str[512] = { NULL, };
|
|
// sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ",
|
|
// db_hdr.szDate,
|
|
// __FILE__,
|
|
// fileSize,
|
|
// headerSize
|
|
// );
|
|
//
|
|
// ::MessageBox( g_hWnd, str, "Error", MB_OK );
|
|
//
|
|
// if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES )
|
|
// {
|
|
// exit( 1 );
|
|
// }
|
|
//}
|
|
|
|
for( int i(0); db_hdr.nCount>i; i++ )
|
|
{
|
|
_SKILL_FX * pSkillFx = new _SKILL_FX;
|
|
pRes->Read( pSkillFx, sizeof(_SKILL_FX) );
|
|
|
|
//마법류는 자동으로 설정 한다.
|
|
if( pSkillFx->nCasting_Type_Id == 1 && pSkillFx->nStage_Type_Id != 1001 ) //임시(채광 채집 조작 스킬들은 DB모션을 사용한다 )
|
|
{
|
|
int nCasting_Fx_Set_Id = pSkillFx->nCasting_Fx_Set_Id ;
|
|
if( pSkillFx->szElemental == 0 ){ pSkillFx->nCasting_Start_Motion_Id = 70; pSkillFx->nCasting_Middle_Motion_Id = 80; pSkillFx->nCasting_Fx_Set_Id = 2002; }
|
|
if( pSkillFx->szElemental == 1 ){ pSkillFx->nCasting_Start_Motion_Id = 71; pSkillFx->nCasting_Middle_Motion_Id = 81; pSkillFx->nCasting_Fx_Set_Id = 2003; }
|
|
if( pSkillFx->szElemental == 2 ){ pSkillFx->nCasting_Start_Motion_Id = 72; pSkillFx->nCasting_Middle_Motion_Id = 82; pSkillFx->nCasting_Fx_Set_Id = 2004; }
|
|
if( pSkillFx->szElemental == 3 ){ pSkillFx->nCasting_Start_Motion_Id = 73; pSkillFx->nCasting_Middle_Motion_Id = 83; pSkillFx->nCasting_Fx_Set_Id = 2005; }
|
|
if( pSkillFx->szElemental == 4 ){ pSkillFx->nCasting_Start_Motion_Id = 74; pSkillFx->nCasting_Middle_Motion_Id = 84; pSkillFx->nCasting_Fx_Set_Id = 2006; }
|
|
if( pSkillFx->szElemental == 5 ){ pSkillFx->nCasting_Start_Motion_Id = 75; pSkillFx->nCasting_Middle_Motion_Id = 85; pSkillFx->nCasting_Fx_Set_Id = 2007; }
|
|
if( pSkillFx->szElemental == 6 ){ pSkillFx->nCasting_Start_Motion_Id = 76; pSkillFx->nCasting_Middle_Motion_Id = 86; pSkillFx->nCasting_Fx_Set_Id = 2008; }
|
|
|
|
if( pSkillFx->szIs_Creature_Skill == 2 ) //몬스터 스킬일 경우 스킬연출 디비 FX값 참조
|
|
{
|
|
pSkillFx->nCasting_Fx_Set_Id = nCasting_Fx_Set_Id;
|
|
}
|
|
|
|
//90 마법시전1 - 자기자신에 시전
|
|
//91 마법시전2 - 타인에 시전 (도움)
|
|
//92 마법시전3 - 타인에 시전 (피해)
|
|
//93 마법시전4 - 자기주변에 시전
|
|
//94 마법시전5 - 소환연출
|
|
|
|
//소환 스킬은 94번 모션 셋트임.
|
|
if( pSkillFx->nStage_Type_Id == 1 || pSkillFx->nStage_Type_Id == 2 )
|
|
pSkillFx->nFire_Motion_Id = 94;
|
|
|
|
if(pSkillFx->szHas_Target == 0 ) //셀프 스킬
|
|
pSkillFx->nFire_Motion_Id = 90;
|
|
|
|
if( pSkillFx->szDeal_Damage == 0 ) //이로움
|
|
pSkillFx->nFire_Motion_Id = 91;
|
|
else if( pSkillFx->szDeal_Damage == 1 ) //해로움
|
|
pSkillFx->nFire_Motion_Id = 92;
|
|
|
|
pSkillFx->nFire_Motion_Id = 92;
|
|
//FireMotionID는 스킬 발사 상황에 따라 달라 진다. SNewSkill 쪽에서 제어함.
|
|
}
|
|
|
|
_SKILL_FX * pFindSkill = NULL;
|
|
if( m_hashSkillFx.lookup( pSkillFx->nID, pFindSkill ) == false )
|
|
{
|
|
m_hashSkillFx.add( pSkillFx->nID, pSkillFx );
|
|
}
|
|
else
|
|
{
|
|
_oprint( "!!!!Data Error SkillFx Code 가 중복되었습니다.!!!! %d\n", pSkillFx->nID );
|
|
// assert(0); //기획팀에 알려 주세여. 바로 수정 해야 합니다.
|
|
|
|
delete pSkillFx;
|
|
}
|
|
}
|
|
KFileManager::Instance().DeleteStream( pRes );
|
|
}
|
|
|
|
_SKILL_FX* SSkillStageDB::GetSkillStageData( int nSkillID)
|
|
{
|
|
_SKILL_FX * pFindSkill = NULL;
|
|
if( m_hashSkillFx.lookup( nSkillID, pFindSkill ) == false )
|
|
return NULL;
|
|
else
|
|
return pFindSkill;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
SSkillStageDB & GetSkillStageDB()
|
|
{
|
|
static SSkillStageDB SkillStageDB;
|
|
return SkillStageDB;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
SFieldTypeMaterialDB::SFieldTypeMaterialDB()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SFieldTypeMaterialDB::~SFieldTypeMaterialDB()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void SFieldTypeMaterialDB::Init()
|
|
{
|
|
Load();
|
|
}
|
|
|
|
void SFieldTypeMaterialDB::Destroy()
|
|
{
|
|
_FIELD_TYPE_MATERIAL* pFieldTypeMaterial = NULL;
|
|
bool res;
|
|
res = m_hashFieldTypeMaterial.get_first_value( pFieldTypeMaterial );
|
|
while ( res )
|
|
{
|
|
if ( pFieldTypeMaterial != NULL )
|
|
{
|
|
delete pFieldTypeMaterial;
|
|
}
|
|
res = m_hashFieldTypeMaterial.get_next_value( pFieldTypeMaterial );
|
|
}
|
|
m_hashFieldTypeMaterial.clear();
|
|
}
|
|
|
|
void SFieldTypeMaterialDB::Load()
|
|
{
|
|
KStream * pRes = KFileManager::Instance().CreateStreamFromResource( "db_FieldTypeMaterial.rdb" );
|
|
if( !pRes ) return;
|
|
GAME_DB db_hdr;
|
|
|
|
pRes->Read( &db_hdr, sizeof(db_hdr) );
|
|
|
|
//// RDB 와 Header의 사이즈 비교.
|
|
//int fileSize = pRes->Size() - ( STR_DATE_BUFFER + sizeof( int ) );
|
|
//int headerSize = sizeof(_FIELD_TYPE_MATERIAL) * db_hdr.nCount;
|
|
//
|
|
//if( fileSize != headerSize )
|
|
//{
|
|
// char str[512] = { NULL, };
|
|
// sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ",
|
|
// db_hdr.szDate,
|
|
// __FILE__,
|
|
// fileSize,
|
|
// headerSize
|
|
// );
|
|
//
|
|
// ::MessageBox( g_hWnd, str, "Error", MB_OK );
|
|
//
|
|
// if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES )
|
|
// {
|
|
// exit( 1 );
|
|
// }
|
|
//}
|
|
|
|
for( int i(0); db_hdr.nCount>i; i++ )
|
|
{
|
|
_FIELD_TYPE_MATERIAL * pFieldTypeMaterial = new _FIELD_TYPE_MATERIAL;
|
|
pRes->Read( pFieldTypeMaterial, sizeof(_FIELD_TYPE_MATERIAL) );
|
|
|
|
_FIELD_TYPE_MATERIAL * pFindSkill = NULL;
|
|
if( m_hashFieldTypeMaterial.lookup( pFieldTypeMaterial->nMaterial, pFindSkill ) == false )
|
|
{
|
|
m_hashFieldTypeMaterial.add( pFieldTypeMaterial->nMaterial, pFieldTypeMaterial );
|
|
}
|
|
else
|
|
{
|
|
_oprint( "!!!!Data Error FieldTypeMaterial Code 가 중복되었습니다.!!!! %d\n", pFieldTypeMaterial->nMaterial );
|
|
// assert(0); //기획팀에 알려 주세여. 바로 수정 해야 합니다.
|
|
|
|
delete pFieldTypeMaterial;
|
|
}
|
|
}
|
|
KFileManager::Instance().DeleteStream( pRes );
|
|
}
|
|
|
|
|
|
SFieldTypeMaterialDB & GetFieldTypeMaterialDB()
|
|
{
|
|
static SFieldTypeMaterialDB FiledTypeMaterialDB;
|
|
return FiledTypeMaterialDB;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 분해 식 DB 인스턴스 얻기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
SSummonRandomSkillDB & GetSummonRandomSkillDB()
|
|
{
|
|
static SSummonRandomSkillDB SummonRandomSkillDB;
|
|
return SummonRandomSkillDB;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 생성자
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
SSummonRandomSkillDB::SSummonRandomSkillDB()
|
|
{
|
|
if( false == Load() )
|
|
{
|
|
SDEBUGLOG( "[SSummonRandomSkillDB] Load Failed " );
|
|
assert( NULL );
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 파괴자
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
SSummonRandomSkillDB::~SSummonRandomSkillDB()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// RDB 파일 불러오기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
bool SSummonRandomSkillDB::Load()
|
|
{
|
|
KStream* pRes( KFileManager::Instance().CreateStreamFromResource( "db_SummonRandomSkill.rdb" ) );
|
|
if( NULL == pRes )
|
|
{
|
|
SDEBUGLOG( "[SSummonRandomSkillDB] Create Stream Failed - [db_SummonRandomSkill.rdb]" );
|
|
assert( NULL );
|
|
return false;
|
|
}
|
|
|
|
GAME_DB db_hdr;
|
|
string idKey;
|
|
|
|
pRes->Read( &db_hdr, sizeof(db_hdr) );
|
|
|
|
for( int nCount = 0; nCount < db_hdr.nCount; nCount++ )
|
|
{
|
|
SummonRandomSkillBase stSummonRandomSkillBase;
|
|
size_t ReadSize( pRes->Read( &stSummonRandomSkillBase, sizeof(SummonRandomSkillBase) ) );
|
|
if( NULL == ReadSize )
|
|
{
|
|
SDEBUGLOG( "[SSummonRandomSkillDB] Read Failed" );
|
|
assert( ReadSize );
|
|
return false;
|
|
}
|
|
|
|
PSUMMON_RANDOM_SKILL_ID pSummonRandomSkillID( new SUMMON_RANDOM_SKILL_ID() ); // 데이터 저장 용
|
|
if( NULL == pSummonRandomSkillID )
|
|
{
|
|
SDEBUGLOG( "[SSummonRandomSkillDB] Alloc Failed" );
|
|
assert( pSummonRandomSkillID );
|
|
continue;
|
|
}
|
|
|
|
char szBuffer[256] = { NULL, };
|
|
set<int> setSkillID; // 데이터 중복 검사 용
|
|
|
|
|
|
for( int nCount = 0; nCount < stSummonRandomSkillBase.skill_count; nCount++ )
|
|
{
|
|
int nSkillID( stSummonRandomSkillBase.skill_id[nCount] );
|
|
|
|
if( NULL == nSkillID )
|
|
{
|
|
#ifdef _DEV
|
|
_sntprintf_s( szBuffer, _countof( szBuffer), _TRUNCATE, "[SSummonRandomSkillDB] Skill ID 가 0 입니다. 데이터를 무시합니다 : Group Unique ID - [%u], 스킬 아이디 [%u]번째", stSummonRandomSkillBase.skill_group_id, nCount );
|
|
MessageBox( HWND_DESKTOP, szBuffer, "[SSummonRandomSkillDB] 데이터 에러", MB_OK | MB_ICONERROR );
|
|
ZeroMemory( szBuffer, sizeof( szBuffer ) );
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
|
|
if( false == ( setSkillID.insert( nSkillID ).second ) )
|
|
{
|
|
#ifdef _DEV
|
|
_sntprintf_s( szBuffer, _countof( szBuffer), _TRUNCATE, "[SSummonRandomSkillDB] Skill ID 중복 !! : Group Unique ID - [%u], 스킬 아이디 [%u]번째", stSummonRandomSkillBase.skill_group_id, nCount );
|
|
MessageBox( HWND_DESKTOP, szBuffer, "[SSummonRandomSkillDB] 데이터 에러", MB_OK | MB_ICONERROR );
|
|
ZeroMemory( szBuffer, sizeof( szBuffer ) );
|
|
#endif
|
|
continue;
|
|
}
|
|
else
|
|
pSummonRandomSkillID->vecSkillID.push_back( nSkillID );
|
|
}
|
|
|
|
if( false == m_mapSummonRandomSkill.insert( pair<UINT, PSUMMON_RANDOM_SKILL_ID>( stSummonRandomSkillBase.skill_group_id, pSummonRandomSkillID ) ).second )
|
|
{
|
|
SAFE_DELETE( pSummonRandomSkillID );
|
|
#ifdef _DEV
|
|
_sntprintf_s( szBuffer, _countof( szBuffer), _TRUNCATE, "[SSummonRandomSkillDB] Gruop Unique ID 중복이거나 컨테이너 삽입에 실패하였습니다. : Group Unique ID - [%u]", stSummonRandomSkillBase.skill_group_id );
|
|
MessageBox( HWND_DESKTOP, szBuffer, "[SSummonRandomSkillDB] 데이터 에러", MB_OK | MB_ICONERROR );
|
|
ZeroMemory( szBuffer, sizeof( szBuffer ) );
|
|
#endif
|
|
continue;
|
|
}
|
|
}
|
|
|
|
KFileManager::Instance().DeleteStream( pRes );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 파괴
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
void SSummonRandomSkillDB::Destroy()
|
|
{
|
|
for( SUMMON_RANDOM_SKILL_ITER Iter = m_mapSummonRandomSkill.begin(); Iter != m_mapSummonRandomSkill.end(); ++Iter )
|
|
{
|
|
PSUMMON_RANDOM_SKILL_ID pSummonRandomSkillID( Iter->second );
|
|
SAFE_DELETE( pSummonRandomSkillID );
|
|
}
|
|
|
|
m_mapSummonRandomSkill.clear();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// 랜덤 스킬 ID 리스트 얻기
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
const SUMMON_RANDOM_SKILL_ID* const SSummonRandomSkillDB::GetRandomSkillIDList( const int nGroupID )
|
|
{
|
|
SUMMON_RANDOM_SKILL_ITER Iter( m_mapSummonRandomSkill.find( nGroupID ) );
|
|
|
|
if( Iter != m_mapSummonRandomSkill.end() )
|
|
return Iter->second;
|
|
|
|
return NULL;
|
|
}
|