726 lines
25 KiB
C++
726 lines
25 KiB
C++
#include "stdafx.h"
|
|
#include <kfile/KStream.h>
|
|
#include <kfile/KFileManager.h>
|
|
#include <kfile/KBinaryFiler.h>
|
|
#include "nob12.h"
|
|
|
|
#include "SCobManager.h"
|
|
#include <mmo/ArTime.h>
|
|
#include <kfile/TrfMapper.h>
|
|
|
|
#include "SLog.h"
|
|
|
|
//#include <string>
|
|
|
|
//using namespace std;
|
|
using namespace GAME_DEFINE;
|
|
|
|
//#ifndef _RAC
|
|
const char * pAniClassEx[] =
|
|
{
|
|
"una_", // 맨손 0
|
|
"swo_", //칼 한손 1
|
|
"swa_", //칼 양손 2
|
|
"spa_", //창 양손 3
|
|
"bwa_", //활 양손 4
|
|
"dgo_", //단검 한손 5
|
|
"swt_", //장검 이도류 6
|
|
"dgt_", //단검 이도류 7
|
|
// "sfo_", //지팡이 한손 8
|
|
"sfa_", //지팡이 양손 9
|
|
"axa_", //도끼 양손 10
|
|
// "mao_", //둔기 한손 11
|
|
// "maa_", //둔기 양손 12
|
|
// "cbo_", //석궁 한손 13
|
|
"cba_", //석궁 양손 14
|
|
<<<<<<< HEAD
|
|
=======
|
|
//"cbt_", // AziaMafia Double Crossbow // From ZONE source; dual crossbows (In ZONE source here is no this element in this array)
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
};
|
|
//#else
|
|
//// extern const char * pAniClassEx[];
|
|
//#endif
|
|
|
|
static inline const char* SafeStr( const char* pStr )
|
|
{
|
|
return pStr ? pStr : "";
|
|
}
|
|
|
|
//COB ==============================================================
|
|
COBManager *KSingletoneResourceManager<COBManager>::s_pStaticManager = new COBManager;
|
|
COBManager::COBManager()
|
|
{
|
|
|
|
}
|
|
|
|
COBManager::~COBManager()
|
|
{
|
|
std::vector<COBSET *>* coblist;
|
|
bool res;
|
|
res = m_resByName.get_first_value( coblist );
|
|
while ( res )
|
|
{
|
|
if ( coblist != NULL )
|
|
{
|
|
std::vector<COBSET *>::iterator it = coblist->begin();
|
|
for( ; coblist->end() != it; it++ )
|
|
{
|
|
delete (*it);
|
|
}
|
|
coblist->clear();
|
|
delete coblist;
|
|
}
|
|
res = m_resByName.get_next_value( coblist );
|
|
}
|
|
m_resByName.clear();
|
|
}
|
|
|
|
std::vector<COBSET *> * COBManager::Load_NoCash( const char *resname )
|
|
{
|
|
std::vector<COBSET *> * pCobSet = NULL;
|
|
KStream *stream = KFileManager::Instance().CreateStreamFromResource( resname );
|
|
|
|
if( !stream ) return NULL;
|
|
|
|
if ( trf::IsTRFStream( *stream ) )
|
|
pCobSet = DetailLoadTRF( *stream );
|
|
else
|
|
pCobSet = DetailLoad( *stream );
|
|
|
|
if ( pCobSet == NULL )
|
|
pCobSet = DetailLoad( *stream );
|
|
|
|
KFileManager::Instance().DeleteStream( stream );
|
|
|
|
return pCobSet;
|
|
}
|
|
|
|
std::vector<COBSET *> * COBManager::Load( const char *resname )
|
|
{
|
|
return load( resname );
|
|
}
|
|
|
|
std::vector<COBSET *> * COBManager::load( const char *pFileName )
|
|
{
|
|
DWORD dwTime = GetSafeTickCount();
|
|
|
|
THREAD_SYNCRONIZE( m_lckIntf );
|
|
|
|
#ifdef _DEBUG
|
|
if (!strcmp(pFileName, "Navislamia_dungeon_zombiedeco01.cob"))
|
|
{
|
|
OutputDebugString("Navislamia_dungeon_zombiedeco");
|
|
}
|
|
OutputDebugString(pFileName);
|
|
OutputDebugString("\n");
|
|
#endif
|
|
|
|
#ifdef _DEV
|
|
//_oprint("load cob : %s\n", pFileName);
|
|
#endif
|
|
|
|
//이미 있음.
|
|
std::vector<COBSET *> * pCobSet;
|
|
if( m_resByName.lookup( pFileName, pCobSet ) == true )
|
|
{
|
|
return pCobSet;
|
|
}
|
|
|
|
KStream *stream = KFileManager::Instance().CreateStreamFromResource( pFileName );
|
|
if( stream == NULL )
|
|
{
|
|
SDEBUGLOG( "[Function = %s]", __FUNCTION__);
|
|
SDEBUGLOG( "COBManager : %s cannot load!!", pFileName);
|
|
return NULL;
|
|
}
|
|
|
|
if ( trf::IsTRFStream( *stream ) )
|
|
pCobSet = DetailLoadTRF( *stream );
|
|
else
|
|
pCobSet = DetailLoad( *stream );
|
|
|
|
if( pCobSet )
|
|
{
|
|
//Hash에 추가
|
|
m_resByName.add( pFileName, pCobSet );
|
|
}
|
|
else
|
|
{
|
|
assert(0 && "Error: COBManager::Load Fail - FILE NOT READ" );
|
|
_oprint( "Error: COBManager::Load %s\n", pFileName );
|
|
}
|
|
|
|
KFileManager::Instance().DeleteStream( stream ); // by Testors
|
|
|
|
DWORD dwLoadTime = GetSafeTickCount()-dwTime;
|
|
if( dwLoadTime > 30 )
|
|
{
|
|
// _oprint( "COBManager::Load() : %s - %dms - ThreadId:%d\n", pFileName, dwLoadTime, GetCurrentThreadId() );
|
|
}
|
|
|
|
return pCobSet;
|
|
}
|
|
|
|
std::vector<COBSET *> * COBManager::DetailLoad( KStream &Stream )
|
|
{
|
|
#ifndef NDEBUG
|
|
DWORD dwStartTime = GetSafeTickCount();
|
|
#endif
|
|
|
|
KBinaryFiler filer;
|
|
if ( filer.Load( Stream ) )
|
|
{
|
|
std::vector<COBSET *> * coblist = new std::vector<COBSET *>;
|
|
for(int i(0); i <filer.GetDataObjectCount(); ++i)
|
|
{
|
|
KTemplateDataObject * pObject = filer.GetDataObjectAt(i);
|
|
|
|
const char *lpszName = pObject->GetTemplateName();
|
|
|
|
if( strcmp(lpszName, "cob_header_v10") == 0 || strcmp(lpszName, "old_cob_header") == 0 ||
|
|
strcmp(lpszName, "cob_header_v11") == 0 || strcmp(lpszName, "cob_old_header") == 0 || strcmp(lpszName, "cob_header") == 0 ||
|
|
strcmp(lpszName, "cob_header_v12") == 0 || strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
COBSET * pCobSet = new COBSET;
|
|
|
|
KFT_cob_header_v12 cob_header(pObject);
|
|
|
|
DWORD dwAniEventListSize = cob_header.GetValue_ani_event_size();
|
|
DWORD dwAniListSize = cob_header.GetValue_ani_list_size();
|
|
DWORD dwObj_Clan = cob_header.GetValue_obj_clan();
|
|
DWORD dwMeshPartSize = cob_header.GetValue_mesh_part_size();
|
|
DWORD dwSex = cob_header.GetValue_obj_sex();
|
|
DWORD dwAniPartIndex = cob_header.GetValue_obj_partindex();
|
|
pCobSet->nAniPart = dwAniPartIndex;
|
|
pCobSet->nClan = dwObj_Clan;
|
|
pCobSet->nSex = dwSex;
|
|
|
|
if( strcmp(lpszName, "cob_old_header") == 0 || strcmp(lpszName, "cob_header") == 0 ||
|
|
strcmp(lpszName, "cob_header_v11") == 0 || strcmp(lpszName, "cob_header_v12") == 0 ||
|
|
strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
cob_header.GetArrayValue_sel_cube ( 0, pCobSet->fSelCube, sizeof(pCobSet->fSelCube), 6 );
|
|
cob_header.GetArrayValue_dead_cube ( 0, pCobSet->fDeadCube, sizeof(pCobSet->fDeadCube), 6 );
|
|
cob_header.GetArrayValue_collide_cube( 0, pCobSet->fCollideCube, sizeof(pCobSet->fCollideCube), 6 );
|
|
cob_header.GetArrayValue_visible_cube( 0, pCobSet->fVisibleCube, sizeof(pCobSet->fVisibleCube), 6 );
|
|
|
|
char szFileName[_MAX_FNAME];
|
|
int nLen = 256;
|
|
|
|
//추가 프랍용 데이타
|
|
if( pCobSet->nClan == GCLAN_PROP_NX3 ||
|
|
pCobSet->nClan == GCLAN_PROP_SPEED ||
|
|
pCobSet->nClan == GCLAN_PROP_COB )
|
|
{
|
|
//Prop Data
|
|
pCobSet->nRenderType = cob_header.GetValue_render_type(); //Prop
|
|
pCobSet->nPropCategory = cob_header.GetValue_prop_category(); //Prop
|
|
pCobSet->nShadowType = cob_header.GetValue_shadow_type(); //Prop
|
|
|
|
//Mesh
|
|
DWORD dwMeshSize = cob_header.GetValue_mesh_list_size();
|
|
|
|
for( unsigned int n(0); dwMeshSize>n; n++ )
|
|
{
|
|
const char * pMesh = cob_header.GetArrayString_mesh_list( n );
|
|
std::string strMesh = pMesh;
|
|
|
|
pCobSet->m_MeshList.push_back( strMesh );
|
|
}
|
|
|
|
//높이 화일
|
|
cob_header.GetString_height_file_name( szFileName, nLen );
|
|
pCobSet->m_strHeightFile = szFileName;
|
|
|
|
if( strcmp(lpszName, "cob_header_v12") == 0 ||
|
|
strcmp(lpszName, "cob_header_v13") == 0)
|
|
{
|
|
//Camera Collision 화일
|
|
cob_header.GetString_camera_collision_file_name( szFileName, nLen );
|
|
pCobSet->m_strCameraCollisionFile = szFileName;
|
|
}
|
|
else
|
|
{
|
|
pCobSet->m_strCameraCollisionFile = "empty";
|
|
}
|
|
|
|
//LOD
|
|
DWORD dwLODSize = cob_header.GetValue_lod_list_size();
|
|
|
|
KFTA_lod_data lod_list;
|
|
cob_header.GetMemberTemplateArray_lod_list( lod_list );
|
|
|
|
for( unsigned int n(0); dwLODSize>n; n++ )
|
|
{
|
|
nLen = 256;
|
|
|
|
EFFECT_POS_DATA lod;
|
|
|
|
KFT_lod_data kft_lod;
|
|
lod_list.GetData( n, kft_lod );
|
|
|
|
lod.dwIndex = kft_lod.GetValue_nLevel();
|
|
kft_lod.GetString_lod_name( szFileName, nLen ); //얻어올 string 길이보다 nLen 이 작으면 실패함.
|
|
lod.strName = szFileName;
|
|
|
|
pCobSet->m_LodList.push_back( lod );
|
|
}
|
|
}
|
|
//gmpbigsun( 2012_1128 ) : MTE
|
|
else if( GCLAN_MONSTER == pCobSet->nClan )
|
|
{
|
|
if( strcmp(lpszName, "cob_header_v12") == 0 || strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
//몬스터의 경우 m_strCameraCollisionFile에 MTE texture name이 기록되어있다.
|
|
cob_header.GetString_camera_collision_file_name( szFileName, nLen );
|
|
pCobSet->m_strCameraCollisionFile = szFileName;
|
|
}
|
|
}
|
|
|
|
//추가 아바타 데이타
|
|
//처음 한번만 로딩됨
|
|
if( pCobSet->m_EffPosList.empty() )
|
|
{
|
|
DWORD dwEffPosSize = cob_header.GetValue_effpos_list_size();
|
|
KFTA_effect_pos effect_pos_list;
|
|
cob_header.GetMemberTemplateArray_effpos_list( effect_pos_list );
|
|
|
|
|
|
for( unsigned int n(0); dwEffPosSize>n; n++ )
|
|
{
|
|
nLen = 256;
|
|
EFFECT_POS_DATA effect_pos;
|
|
|
|
KFT_effect_pos kft_effect_pos;
|
|
effect_pos_list.GetData( n, kft_effect_pos );
|
|
|
|
effect_pos.dwIndex = kft_effect_pos.GetValue_nIndex();
|
|
kft_effect_pos.GetString_effect_pos_name( szFileName, nLen );
|
|
effect_pos.strName = szFileName;
|
|
|
|
pCobSet->m_EffPosList.push_back( effect_pos );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const float pfVal[] = { -1.f, -1.f, -1.f, 1.f, 1.f, 1.f, };
|
|
|
|
memcpy( pCobSet->fSelCube , pfVal, sizeof(pCobSet->fSelCube) );
|
|
memcpy( pCobSet->fDeadCube , pfVal, sizeof(pCobSet->fDeadCube) );
|
|
memcpy( pCobSet->fVisibleCube, pfVal, sizeof(pCobSet->fVisibleCube) );
|
|
memcpy( pCobSet->fCollideCube, pfVal, sizeof(pCobSet->fCollideCube) );
|
|
}
|
|
|
|
//Mesh Part Name
|
|
KFTA_cob_mesh_part_list mesh_part_list_array;
|
|
cob_header.GetMemberTemplateArray_mesh_part_list(mesh_part_list_array);
|
|
for( unsigned int j(0); dwMeshPartSize>j; j++ )
|
|
{
|
|
KFT_cob_mesh_part_list mesh_part_list;
|
|
mesh_part_list_array.GetData( j, mesh_part_list );
|
|
DWORD mesh_part_Num = mesh_part_list.GetValue_mesh_part_num();
|
|
DWORD mesh_part_list_size = mesh_part_list.GetValue_mesh_part_size();
|
|
for( unsigned int a(0); mesh_part_list_size>a; a++ )
|
|
{
|
|
//NX3 리스트
|
|
const char * pMeshPartName = mesh_part_list.GetArrayString_mesh_part_list(a);
|
|
std::string MeshName = pMeshPartName;
|
|
switch( mesh_part_Num )
|
|
{
|
|
case MPART_FACE : pCobSet->m_FaceList.push_back( MeshName ); break; //얼굴
|
|
case MPART_HAIR : pCobSet->m_HairList.push_back( MeshName ); break; //머리칼, 투구
|
|
case MPART_BODY : pCobSet->m_BodyList.push_back( MeshName ); break; //몸통-상의,하의 포함
|
|
case MPART_FOOT : pCobSet->m_FootList.push_back( MeshName ); break; //신발(단화, 장화)
|
|
case MPART_HAND : pCobSet->m_HandList.push_back( MeshName ); break; //손 (긴,짧은장갑)
|
|
case MPART_L_SKIRT : pCobSet->m_LSkirtList.push_back( MeshName ); break; //긴 치마
|
|
case MPART_M_SKIRT : pCobSet->m_MSkirtList.push_back( MeshName ); break; //중 치마
|
|
case MPART_S_SKIRT : pCobSet->m_SSkirtList.push_back( MeshName ); break; //짧 치마
|
|
|
|
case MPART_MANTLE : pCobSet->m_MantleList.push_back( MeshName ); break; //망토
|
|
case MPART_ACCE_EYE : pCobSet->m_AccEyeList.push_back( MeshName ); break; //액세서리
|
|
case MPART_ACCE_LIP : pCobSet->m_AccLipList.push_back( MeshName ); break; //액세서리
|
|
case MPART_ACCE_EAR : //액세서리
|
|
if (GameRule::GetCurrentLocalBitSet() != GameRule::LOCAL_BITSET::ME) // 귀걸이 감추기. 무슬림 국가에서는 다 막아야 할 듯. 일단 중동만
|
|
pCobSet->m_AccEarList.push_back( MeshName );
|
|
break;
|
|
case MPART_ACCE_NECK : pCobSet->m_AccNeckList.push_back( MeshName );break; //액세서리
|
|
case MPART_FABRIC : pCobSet->m_FabricList.push_back( MeshName ); break; //앞 가리개
|
|
|
|
case MPART_L_WEAPON : pCobSet->m_LWeaponList.push_back( MeshName ); break; //왼손 무기
|
|
case MPART_R_WEAPON : pCobSet->m_RWeaponList.push_back( MeshName ); break; //오른손 무기
|
|
|
|
case MPART_HELM : pCobSet->m_HelmList.push_back( MeshName ); break; //투구 무기
|
|
}
|
|
}
|
|
}
|
|
|
|
//Animation List 임.
|
|
for( unsigned int j(0); dwAniListSize>j; j++ )
|
|
{ //NAF 리스트 임.
|
|
const char * pAniName = cob_header.GetArrayString_ani_list(j);
|
|
std::string strAniName = pAniName;
|
|
|
|
pCobSet->m_AniList.push_back(strAniName);
|
|
}
|
|
|
|
KFTA_ani_event_list ani_event_list_array;
|
|
cob_header.GetMemberTemplateArray_ani_event_list(ani_event_list_array);
|
|
#ifndef _RAC
|
|
//Event List
|
|
for( unsigned int j(0); dwAniEventListSize>j; j++ )
|
|
{
|
|
KFT_ani_event_list ani_event_list;
|
|
ani_event_list_array.GetData(j, ani_event_list);
|
|
|
|
char szAniName[128];
|
|
memset( szAniName, 0, sizeof(szAniName) );
|
|
int nLen = 128;
|
|
|
|
ani_event_list.GetString_ani_name(szAniName, nLen);
|
|
DWORD dwEventListSize = ani_event_list.GetValue_event_list_size();
|
|
|
|
EVENT_LIST event_list;
|
|
event_list.strAniName = szAniName;
|
|
|
|
KFTA_ani_event ani_event_array;
|
|
ani_event_list.GetMemberTemplateArray_event_list( ani_event_array );
|
|
|
|
char szFileName[128];
|
|
for( unsigned int k(0); dwEventListSize>k; k++ )
|
|
{
|
|
memset( szFileName, 0, sizeof(szFileName) );
|
|
nLen = 128;
|
|
|
|
KFT_ani_event ani_event;
|
|
ani_event_array.GetData(k, ani_event);
|
|
DWORD dwEventType = ani_event.GetValue_event_type();
|
|
DWORD dwEventTime = ani_event.GetValue_event_time();
|
|
|
|
E_DATA event_data;
|
|
event_data.dwType = ani_event.GetValue_event_type();
|
|
event_data.dwTime = ani_event.GetValue_event_time();
|
|
event_data.dwDetail = ani_event.GetValue_event_detail();
|
|
// event_data.dwDirection = 0;
|
|
event_data.dwDirection = ani_event.GetValue_event_direction();
|
|
// event_data.dwProperty = 0;
|
|
event_data.dwProperty = ani_event.GetValue_event_property();
|
|
ani_event.GetString_event_file_name( szFileName, nLen );
|
|
|
|
event_data.strFileName = szFileName;
|
|
|
|
event_list.vEventlist.push_back(event_data);
|
|
}
|
|
|
|
pCobSet->m_AniEventList.push_back(event_list);
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
//CobSet를 모은다.
|
|
coblist->push_back( pCobSet );
|
|
}
|
|
else
|
|
{
|
|
_oprint( "%s\n", lpszName );
|
|
assert(0 && "Invalid COB 리소스" );
|
|
}
|
|
}
|
|
return coblist;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
using namespace trf;
|
|
|
|
struct KStreamPtr
|
|
{
|
|
KStreamPtr( KStream& st ) : stream( st ) { ptr = st.GetMappedPtr(0); }
|
|
~KStreamPtr() { stream.FreeMappedPtr( ptr ); }
|
|
KStream& stream;
|
|
void* ptr;
|
|
};
|
|
|
|
std::vector<COBSET *> * COBManager::DetailLoadTRF( KStream &Stream )
|
|
{
|
|
#ifndef NDEBUG
|
|
DWORD dwStartTime = GetSafeTickCount();
|
|
#endif
|
|
|
|
try
|
|
{
|
|
KStreamPtr ptr( Stream );
|
|
Mapper mapper( &GetMetaData(), ptr.ptr, Stream.GetLength() );
|
|
trf::MDictPtr pDict = mapper.root();
|
|
|
|
std::vector<COBSET *> * coblist = new std::vector<COBSET *>;
|
|
for(int i(0); i <pDict->count(); ++i)
|
|
{
|
|
trf::MTemplatePtr pObject = pDict->getTemplateAt( i );
|
|
|
|
const char *lpszName = pObject->className();
|
|
|
|
if( strcmp(lpszName, "old_cob_header") == 0 || strcmp(lpszName, "cob_header_v10") == 0 ||
|
|
strcmp(lpszName, "cob_header_v11") == 0 || strcmp(lpszName, "cob_old_header") == 0 || strcmp(lpszName, "cob_header") == 0 ||
|
|
strcmp(lpszName, "cob_header_v12") == 0 ||
|
|
strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
COBSET * pCobSet = new COBSET;
|
|
|
|
pCobSet->nAniPart = pObject->getDWordBy( "obj_partindex" );
|
|
pCobSet->nClan = pObject->getDWordBy( "obj_clan" );
|
|
pCobSet->nSex = pObject->getDWordBy( "obj_sex" );
|
|
|
|
if( strcmp(lpszName, "cob_old_header") == 0 || strcmp(lpszName, "cob_header") == 0 ||
|
|
strcmp(lpszName, "cob_header_v11") == 0 || strcmp(lpszName, "cob_header_v12") == 0 ||
|
|
strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
pObject->getArrayBy( "sel_cube" )->readFixedData( 0, 6, pCobSet->fSelCube, sizeof( pCobSet->fSelCube ) );
|
|
pObject->getArrayBy( "dead_cube" )->readFixedData( 0, 6, pCobSet->fDeadCube, sizeof( pCobSet->fDeadCube ) );
|
|
pObject->getArrayBy( "collide_cube" )->readFixedData( 0, 6, pCobSet->fCollideCube, sizeof( pCobSet->fCollideCube ) );
|
|
pObject->getArrayBy( "visible_cube" )->readFixedData( 0, 6, pCobSet->fVisibleCube, sizeof( pCobSet->fVisibleCube ) );
|
|
|
|
//추가 프랍용 데이타
|
|
if( pCobSet->nClan == GCLAN_PROP_NX3 ||
|
|
pCobSet->nClan == GCLAN_PROP_SPEED ||
|
|
pCobSet->nClan == GCLAN_PROP_COB )
|
|
{
|
|
//Prop Data
|
|
pCobSet->nRenderType = pObject->getDWordBy( "render_type" ); //Prop
|
|
pCobSet->nPropCategory = pObject->getDWordBy( "prop_category" ); //Prop
|
|
pCobSet->nShadowType = pObject->getDWordBy( "shadow_type" ); //Prop
|
|
|
|
//Mesh
|
|
trf::MArrayPtr pMeshList = pObject->getArrayBy( "mesh_list" );
|
|
for( int n(0); pMeshList->count()>n; n++ )
|
|
{
|
|
pCobSet->m_MeshList.push_back( pMeshList->getStringAt( n ) );
|
|
}
|
|
|
|
//높이 화일
|
|
pCobSet->m_strHeightFile = SafeStr( pObject->getStringBy( "height_file_name" ) );
|
|
|
|
if( strcmp(lpszName, "cob_header_v12") == 0 ||
|
|
strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
//Camera Collision 화일
|
|
pCobSet->m_strCameraCollisionFile = SafeStr( pObject->getStringBy( "camera_collision_file_name" ) );
|
|
}
|
|
else
|
|
{
|
|
pCobSet->m_strCameraCollisionFile = "empty";
|
|
}
|
|
|
|
//LOD
|
|
trf::MTemplateArrayPtr pLodList = pObject->getTemplateArrayBy( "lod_list" );
|
|
for( int n(0); pLodList->count()>n; n++ )
|
|
{
|
|
EFFECT_POS_DATA lod;
|
|
|
|
trf::MTemplatePtr pLod = pLodList->getTemplateAt( n );
|
|
|
|
lod.dwIndex = pLod->getDWordBy( "nLevel" );
|
|
lod.strName = SafeStr( pLod->getStringBy( "lod_name" ) );
|
|
|
|
pCobSet->m_LodList.push_back( lod );
|
|
}
|
|
}
|
|
else if( GCLAN_MONSTER == pCobSet->nClan )
|
|
{
|
|
if( strcmp(lpszName, "cob_header_v12") == 0 || strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
//몬스터의 경우 m_strCameraCollisionFile에 MTE texture name이 기록되어있다.
|
|
pCobSet->m_strCameraCollisionFile = pObject->getStringBy( "camera_collision_file_name" );
|
|
}
|
|
}
|
|
|
|
//추가 아바타 데이타
|
|
//처음 한번만 로딩됨
|
|
if( pCobSet->m_EffPosList.empty() )
|
|
{
|
|
trf::MTemplateArrayPtr pEffposList = pObject->getTemplateArrayBy( "effpos_list" );
|
|
for( int n(0); pEffposList->count()>n; n++ )
|
|
{
|
|
EFFECT_POS_DATA effect_pos;
|
|
|
|
trf::MTemplatePtr pEffpos = pEffposList->getTemplateAt( n );
|
|
effect_pos.dwIndex = pEffpos->getDWordBy( "nIndex" );
|
|
effect_pos.strName = SafeStr( pEffpos->getStringBy( "effect_pos_name" ) );
|
|
|
|
pCobSet->m_EffPosList.push_back( effect_pos );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const float pfVal[] = { -1.f, -1.f, -1.f, 1.f, 1.f, 1.f, };
|
|
|
|
memcpy( pCobSet->fSelCube , pfVal, sizeof(pCobSet->fSelCube) );
|
|
memcpy( pCobSet->fDeadCube , pfVal, sizeof(pCobSet->fDeadCube) );
|
|
memcpy( pCobSet->fVisibleCube, pfVal, sizeof(pCobSet->fVisibleCube) );
|
|
memcpy( pCobSet->fCollideCube, pfVal, sizeof(pCobSet->fCollideCube) );
|
|
}
|
|
|
|
//Mesh Part Name
|
|
trf::MTemplateArrayPtr pMeshPartListArray = pObject->getTemplateArrayBy( "mesh_part_list" );
|
|
for( int j(0); pMeshPartListArray->count()>j; j++ )
|
|
{
|
|
trf::MTemplatePtr pMeshPartList = pMeshPartListArray->getTemplateAt( j );
|
|
DWORD mesh_part_Num = pMeshPartList->getDWordBy( "mesh_part_num" );
|
|
trf::MArrayPtr pMeshParts = pMeshPartList->getArrayBy( "mesh_part_list" );
|
|
for( int a(0); pMeshParts->count()>a; a++ )
|
|
{
|
|
//NX3 리스트
|
|
std::string MeshName = pMeshParts->getStringAt( a );
|
|
switch( mesh_part_Num )
|
|
{
|
|
case MPART_FACE : pCobSet->m_FaceList.push_back( MeshName ); break; //얼굴
|
|
case MPART_HAIR : pCobSet->m_HairList.push_back( MeshName ); break; //머리칼, 투구
|
|
case MPART_BODY : pCobSet->m_BodyList.push_back( MeshName ); break; //몸통-상의,하의 포함
|
|
case MPART_FOOT : pCobSet->m_FootList.push_back( MeshName ); break; //신발(단화, 장화)
|
|
case MPART_HAND : pCobSet->m_HandList.push_back( MeshName ); break; //손 (긴,짧은장갑)
|
|
case MPART_L_SKIRT : pCobSet->m_LSkirtList.push_back( MeshName ); break; //긴 치마
|
|
case MPART_M_SKIRT : pCobSet->m_MSkirtList.push_back( MeshName ); break; //중 치마
|
|
case MPART_S_SKIRT : pCobSet->m_SSkirtList.push_back( MeshName ); break; //짧 치마
|
|
|
|
case MPART_MANTLE : pCobSet->m_MantleList.push_back( MeshName ); break; //망토
|
|
case MPART_ACCE_EYE : pCobSet->m_AccEyeList.push_back( MeshName ); break; //액세서리
|
|
case MPART_ACCE_LIP : pCobSet->m_AccLipList.push_back( MeshName ); break; //액세서리
|
|
case MPART_ACCE_EAR : //액세서리
|
|
if (GameRule::GetCurrentLocalBitSet() != GameRule::LOCAL_BITSET::ME) // 귀걸이 감추기. 무슬림 국가에서는 다 막아야 할 듯. 일단 중동만
|
|
pCobSet->m_AccEarList.push_back( MeshName );
|
|
break;
|
|
case MPART_ACCE_NECK : pCobSet->m_AccNeckList.push_back( MeshName );break; //액세서리
|
|
case MPART_FABRIC : pCobSet->m_FabricList.push_back( MeshName ); break; //앞 가리개
|
|
|
|
case MPART_L_WEAPON : pCobSet->m_LWeaponList.push_back( MeshName ); break; //왼손 무기
|
|
case MPART_R_WEAPON : pCobSet->m_RWeaponList.push_back( MeshName ); break; //오른손 무기
|
|
|
|
case MPART_HELM : pCobSet->m_HelmList.push_back( MeshName ); break; //투구 무기
|
|
}
|
|
}
|
|
}
|
|
|
|
trf::MArrayPtr pAniList = pObject->getArrayBy( "ani_list" );
|
|
//Animation List 임.
|
|
for( int j(0); pAniList->count()>j; j++ )
|
|
{ //NAF 리스트 임.
|
|
pCobSet->m_AniList.push_back( pAniList->getStringAt( j ) );
|
|
}
|
|
|
|
trf::MTemplateArrayPtr pAniEventListArray = pObject->getTemplateArrayBy( "ani_event_list" );
|
|
#ifndef _RAC
|
|
//Event List
|
|
for( unsigned int j(0); pAniEventListArray->count()>j; j++ )
|
|
{
|
|
trf::MTemplatePtr pAniEventList = pAniEventListArray->getTemplateAt( j );
|
|
|
|
EVENT_LIST event_list;
|
|
event_list.strAniName = SafeStr( pAniEventList->getStringBy( "ani_name" ) );
|
|
|
|
trf::MTemplateArrayPtr pAniEventArray = pAniEventList->getTemplateArrayBy( "event_list" );
|
|
|
|
for( unsigned int k(0); pAniEventArray->count()>k; k++ )
|
|
{
|
|
trf::MTemplatePtr pAniEvent = pAniEventArray->getTemplateAt( k );
|
|
|
|
DWORD dwEventType = pAniEvent->getDWordBy( "event_type" );
|
|
DWORD dwEventTime = pAniEvent->getDWordBy( "event_time" );
|
|
|
|
E_DATA event_data;
|
|
event_data.dwType = pAniEvent->getDWordBy( "event_type" );
|
|
event_data.dwTime = pAniEvent->getDWordBy( "event_time" );
|
|
event_data.dwDetail = pAniEvent->getDWordBy( "event_detail" );
|
|
// event_data.dwDirection = 0;
|
|
event_data.dwDirection = pAniEvent->getDWordBy( "event_direction" );
|
|
// event_data.dwProperty = 0;
|
|
event_data.dwProperty = pAniEvent->getDWordBy( "event_property" );
|
|
event_data.strFileName = SafeStr( pAniEvent->getStringBy( "event_file_name" ) );
|
|
|
|
event_list.vEventlist.push_back(event_data);
|
|
}
|
|
|
|
pCobSet->m_AniEventList.push_back(event_list);
|
|
}
|
|
#endif
|
|
|
|
if( strcmp(lpszName, "cob_header_v13") == 0 )
|
|
{
|
|
trf::MTemplateArrayPtr pMeshTextureListArray = pObject->getTemplateArrayBy( "mesh_texture_list" );
|
|
for( int i = 0; i < pMeshTextureListArray->count(); ++i )
|
|
{
|
|
trf::MTemplatePtr pNx3List = pMeshTextureListArray->getTemplateAt( i );
|
|
trf::MTemplateArrayPtr pNx3TextureArray = pNx3List->getTemplateArrayBy( "nx3_seq_list" );
|
|
for( int x = 0; x < pNx3TextureArray->count(); ++x )
|
|
{
|
|
trf::MTemplatePtr pNx3TextureData = pNx3TextureArray->getTemplateAt( x );
|
|
|
|
std::string std_nx3_name = pNx3TextureData->getStringBy( "str_nx3_name" );
|
|
trf::MTemplateArrayPtr pSeqArray = pNx3TextureData->getTemplateArrayBy( "seq_list" );
|
|
|
|
TEXTURE_GROUP_LIST* pGroup_data = new TEXTURE_GROUP_LIST;
|
|
pGroup_data->strNx3Name = std_nx3_name;
|
|
|
|
for( int seq = 0; seq < pSeqArray->count(); ++seq )
|
|
{
|
|
trf::MTemplatePtr pSeqData = pSeqArray->getTemplateAt( seq );
|
|
std::string strSeqName = pSeqData->getStringBy( "str_seq_name" );
|
|
|
|
TEXTURE_GROUP_LIST::Seq_list* pSeqdata = new TEXTURE_GROUP_LIST::Seq_list;
|
|
pSeqdata->strSeqName = strSeqName;
|
|
|
|
pGroup_data->vSeqList.push_back( pSeqdata );
|
|
|
|
trf::MTemplateArrayPtr pSeqTextureArray = pSeqData->getTemplateArrayBy( "seq_texture_list" );
|
|
for( int nTexGroupIndex = 0; nTexGroupIndex < TEXTURE_GROUP_INDEX_MAX; ++nTexGroupIndex )
|
|
{
|
|
trf::MTemplatePtr pSeqTexture = pSeqTextureArray->getTemplateAt( nTexGroupIndex );
|
|
trf::MArrayPtr pTextureNameList = pSeqTexture->getArrayBy( "texture_name_list" );
|
|
|
|
for( int seqtex = 0; seqtex < pTextureNameList->count(); ++seqtex )
|
|
{
|
|
const char* pszTextureName = pTextureNameList->getStringAt( seqtex );
|
|
|
|
if( pszTextureName != NULL )
|
|
{
|
|
if( pSeqdata->vTextureIndex[nTexGroupIndex].size() < (size_t)seqtex ) /// 2011.01.19 형변환 추가 - prodongi
|
|
{
|
|
pSeqdata->vTextureIndex[nTexGroupIndex].resize( seqtex + 1, "" );
|
|
pSeqdata->vTextureIndex[nTexGroupIndex][seqtex] = pszTextureName;
|
|
}
|
|
else
|
|
pSeqdata->vTextureIndex[nTexGroupIndex].push_back( pszTextureName );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pCobSet->m_TextureGroupList[i].push_back( pGroup_data );
|
|
}
|
|
}
|
|
}
|
|
//CobSet를 모은다.
|
|
coblist->push_back( pCobSet );
|
|
}
|
|
else
|
|
{
|
|
_oprint( "%s\n", lpszName );
|
|
assert(0 && "Invalid COB resource" );
|
|
}
|
|
}
|
|
return coblist;
|
|
|
|
}
|
|
catch ( Exception& )
|
|
{
|
|
#ifdef _DEBUG
|
|
assert( 0 && "화일 Load Fail. 담당자에게 알려!!!" );
|
|
#endif
|
|
return NULL;
|
|
}
|
|
}
|