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

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