355 lines
14 KiB
C++
355 lines
14 KiB
C++
|
|
#include <atlcomtime.h>
|
|
|
|
#include <logging/FileLog.h>
|
|
#include <toolkit/XConsole.h>
|
|
|
|
#include "ContentLoader.h"
|
|
#include "InstanceDungeonManager.h"
|
|
#include "ChannelManager.h"
|
|
#include "GameDBUtil.h"
|
|
#include "DBPerformanceTracker.h"
|
|
#include "ADOConnection.h"
|
|
|
|
|
|
std::vector< GameContent::INSTANCE_DUNGEON_BASE * > & GetInstanceDungeonVector()
|
|
{
|
|
static std::vector< GameContent::INSTANCE_DUNGEON_BASE * > vInstanceDungeonInfo;
|
|
|
|
return vInstanceDungeonInfo;
|
|
}
|
|
|
|
struct dbInstanceDungeon : public CADORecordBinding
|
|
{
|
|
BEGIN_ADO_BINDING(dbInstanceDungeon)
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 1, adInteger, id, sizeof( id ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 2, adInteger, name_id, sizeof( name_id ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 3, adInteger, local_flag, sizeof( local_flag ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 4, adInteger, dungeon_channel_id, sizeof( dungeon_channel_id ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 5, adInteger, dungeon_x, sizeof( dungeon_x ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 6, adInteger, dungeon_y, sizeof( dungeon_y ), FALSE )
|
|
END_ADO_BINDING()
|
|
|
|
int id;
|
|
int name_id;
|
|
int local_flag;
|
|
int dungeon_channel_id;
|
|
int dungeon_x;
|
|
int dungeon_y;
|
|
};
|
|
|
|
struct dbInstanceDungeonType : public CADORecordBinding, GameContent::INSTANCE_DUNGEON_TYPE_BASE
|
|
{
|
|
BEGIN_ADO_BINDING(dbInstanceDungeonType)
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 1, adInteger, instance_dungeon_id, sizeof( instance_dungeon_id ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 2, adInteger, nID, sizeof( nID ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 3, adInteger, nMinLevel, sizeof( nMinLevel ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 4, adInteger, nMaxLevel, sizeof( nMaxLevel ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 5, adInteger, nNeedItemCode, sizeof( nNeedItemCode ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 6, adBigInt, nNeedItemCount, sizeof( nNeedItemCount ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 7, adVarChar, szScriptOnCreate, _countof( szScriptOnCreate ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 8, adVarChar, szScriptOnJoin, _countof( szScriptOnJoin ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 9, adVarChar, szScriptOnLeave, _countof( szScriptOnLeave ), FALSE )
|
|
END_ADO_BINDING()
|
|
|
|
int instance_dungeon_id;
|
|
};
|
|
|
|
struct dbInstanceDungeonMonsterRespawn : public CADORecordBinding, GameContent::INSTANCE_DUNGEON_MONSTER_RESPAWN_INFO
|
|
{
|
|
BEGIN_ADO_BINDING(dbInstanceDungeonMonsterRespawn)
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 1, adInteger, instance_dungeon_id, sizeof( instance_dungeon_id ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 2, adInteger, instance_type_id, sizeof( instance_type_id ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 3, adInteger, nID, sizeof( nID ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 4, adInteger, left, sizeof( left ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 5, adInteger, top, sizeof( top ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 6, adInteger, right, sizeof( right ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 7, adInteger, bottom, sizeof( bottom ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 8, adInteger, nMonsterID, sizeof( nMonsterID ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 9, adInteger, nCount, sizeof( nCount ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 10, adInteger, nPeriod, sizeof( nPeriod ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 11, adBoolean, bWandering, sizeof( bWandering ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 12, adInteger, nRespawnGroup, sizeof( nRespawnGroup ), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 13, adBoolean, bRespawnControl, sizeof( bRespawnControl), FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 14, adVarChar, szScriptOnDead, _countof( szScriptOnDead ), FALSE )
|
|
END_ADO_BINDING()
|
|
|
|
int instance_dungeon_id;
|
|
int instance_type_id;
|
|
int left;
|
|
int top;
|
|
int right;
|
|
int bottom;
|
|
};
|
|
|
|
struct dbInstanceDungeonHealingProp : public CADORecordBinding
|
|
{
|
|
BEGIN_ADO_BINDING( dbInstanceDungeonHealingProp )
|
|
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 1, adInteger, instance_dungeon_id, 4, FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 2, adInteger, instance_type_id, 4, FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 3, adInteger, id, 4, FALSE )
|
|
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 4, adInteger, local_flag, 4, FALSE )
|
|
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 5, adInteger, prop_id, 4, FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 6, adInteger, x, 4, FALSE )
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 7, adInteger, y, 4, FALSE )
|
|
|
|
ADO_NUMERIC_ENTRY2( 10, adDecimal, dv_offset_z, 10, 8, FALSE)
|
|
ADO_NUMERIC_ENTRY2( 11, adDecimal, dv_around_x, 10, 8, FALSE)
|
|
ADO_NUMERIC_ENTRY2( 12, adDecimal, dv_around_y, 10, 8, FALSE)
|
|
ADO_NUMERIC_ENTRY2( 13, adDecimal, dv_around_z, 10, 8, FALSE)
|
|
ADO_NUMERIC_ENTRY2( 14, adDecimal, dv_scale_x, 10, 8, FALSE)
|
|
ADO_NUMERIC_ENTRY2( 15, adDecimal, dv_scale_y, 10, 8, FALSE)
|
|
ADO_NUMERIC_ENTRY2( 16, adDecimal, dv_scale_z, 10, 8, FALSE)
|
|
ADO_VARIABLE_LENGTH_ENTRY4( 17, adBoolean, is_height_locked, sizeof( is_height_locked ), FALSE)
|
|
ADO_NUMERIC_ENTRY2( 18, adDecimal, dv_lock_height, 10, 8, FALSE)
|
|
|
|
END_ADO_BINDING()
|
|
|
|
int instance_dungeon_id;
|
|
int instance_type_id;
|
|
int id;
|
|
|
|
int local_flag;
|
|
|
|
int prop_id;
|
|
int x;
|
|
int y;
|
|
|
|
_decimal_variant dv_offset_z;
|
|
_decimal_variant dv_around_x;
|
|
_decimal_variant dv_around_y;
|
|
_decimal_variant dv_around_z;
|
|
_decimal_variant dv_scale_x;
|
|
_decimal_variant dv_scale_y;
|
|
_decimal_variant dv_scale_z;
|
|
bool is_height_locked;
|
|
_decimal_variant dv_lock_height;
|
|
};
|
|
|
|
void onInstanceDungeonInfo( dbInstanceDungeon * emprs )
|
|
{
|
|
extern volatile int g_nCurrentLocalFlag;
|
|
if( emprs->local_flag & g_nCurrentLocalFlag )
|
|
return;
|
|
|
|
GameContent::INSTANCE_DUNGEON_BASE *pInfo = new GameContent::INSTANCE_DUNGEON_BASE();
|
|
|
|
pInfo->nID = emprs->id;
|
|
pInfo->nNameID = emprs->name_id;
|
|
|
|
X2D::Box< AR_UNIT > bxArea;
|
|
ChannelManager::GetRegionOfChannel( emprs->dungeon_channel_id, bxArea );
|
|
pInfo->nDungeonRegionLeft = GetRegionX( bxArea.GetLeft() );
|
|
pInfo->nDungeonRegionTop = GetRegionY( bxArea.GetTop() );
|
|
pInfo->nDungeonRegionRight = GetRegionX( bxArea.GetRight() ) + 1;
|
|
pInfo->nDungeonRegionBottom = GetRegionY( bxArea.GetBottom() ) + 1;
|
|
pInfo->posDungeon.x = emprs->dungeon_x;
|
|
pInfo->posDungeon.y = emprs->dungeon_y;
|
|
|
|
#ifdef _DEBUG
|
|
// 디버그 모드일 때만 이미 로드된 인스턴스 던전 정보인지 확인
|
|
for( std::vector< GameContent::INSTANCE_DUNGEON_BASE * >::const_iterator it = GetInstanceDungeonVector().begin() ; it != GetInstanceDungeonVector().end() ; ++it )
|
|
{
|
|
if( (*it)->nID == pInfo->nID )
|
|
{
|
|
assert( 0 );
|
|
delete pInfo;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
GetInstanceDungeonVector().push_back( pInfo );
|
|
}
|
|
|
|
void onInstanceDungeonTypeInfo( dbInstanceDungeonType * emprs )
|
|
{
|
|
// 실행할 내용이 없는 트리거는 길이를 0으로 만들어 줌
|
|
if( !strcmp( emprs->szScriptOnCreate, "0" ) || !strcmp( emprs->szScriptOnCreate, " " ) )
|
|
emprs->szScriptOnCreate[ 0 ] = NULL;
|
|
if( !strcmp( emprs->szScriptOnJoin, "0" ) || !strcmp( emprs->szScriptOnJoin, " " ) )
|
|
emprs->szScriptOnJoin[ 0 ] = NULL;
|
|
if( !strcmp( emprs->szScriptOnLeave, "0" ) || !strcmp( emprs->szScriptOnLeave, " " ) )
|
|
emprs->szScriptOnLeave[ 0 ] = NULL;
|
|
|
|
GameContent::INSTANCE_DUNGEON_TYPE_BASE *pInfo = new GameContent::INSTANCE_DUNGEON_TYPE_BASE( *emprs );
|
|
|
|
for( std::vector< GameContent::INSTANCE_DUNGEON_BASE * >::iterator it = GetInstanceDungeonVector().begin() ; it != GetInstanceDungeonVector().end() ; ++it )
|
|
{
|
|
if( (*it)->nID != emprs->instance_dungeon_id )
|
|
continue;
|
|
|
|
#ifdef _DEBUG
|
|
for( std::vector< const GameContent::INSTANCE_DUNGEON_TYPE_BASE * >::const_iterator itInstance = (*it)->vInstanceDungeonTypeBase.begin() ; itInstance != (*it)->vInstanceDungeonTypeBase.end() ; ++itInstance )
|
|
{
|
|
if( (*itInstance)->nID == pInfo->nID )
|
|
{
|
|
assert( 0 );
|
|
delete pInfo;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
(*it)->vInstanceDungeonTypeBase.push_back( pInfo );
|
|
return;
|
|
}
|
|
|
|
assert( 0 );
|
|
delete pInfo;
|
|
}
|
|
|
|
void onInstanceDungeonMonsterRespawnInfo( dbInstanceDungeonMonsterRespawn * emprs )
|
|
{
|
|
// 리스폰 주기는 DB에선 초 단위로 입력되어 있으므로 AR_TIME 단위로 변환해야 함
|
|
emprs->nPeriod *= 100;
|
|
|
|
emprs->bxArea.Set( emprs->left, emprs->top, emprs->right, emprs->bottom );
|
|
|
|
// 실행할 내용이 없는 트리거는 길이를 0으로 만들어 줌
|
|
if( !strcmp( emprs->szScriptOnDead, "0" ) || !strcmp( emprs->szScriptOnDead, " " ) )
|
|
emprs->szScriptOnDead[ 0 ] = NULL;
|
|
|
|
GameContent::INSTANCE_DUNGEON_MONSTER_RESPAWN_INFO * pInfo = new GameContent::INSTANCE_DUNGEON_MONSTER_RESPAWN_INFO( *emprs );
|
|
|
|
for( std::vector< GameContent::INSTANCE_DUNGEON_BASE * >::iterator it = GetInstanceDungeonVector().begin() ; it != GetInstanceDungeonVector().end() ; ++it )
|
|
{
|
|
if( (*it)->nID != emprs->instance_dungeon_id )
|
|
continue;
|
|
|
|
for( std::vector< const GameContent::INSTANCE_DUNGEON_TYPE_BASE * >::const_iterator itInstance = (*it)->vInstanceDungeonTypeBase.begin() ; itInstance != (*it)->vInstanceDungeonTypeBase.end() ; ++itInstance )
|
|
{
|
|
if( (*itInstance)->nID != emprs->instance_type_id )
|
|
continue;
|
|
|
|
#ifdef _DEBUG
|
|
for( std::vector< const GameContent::INSTANCE_DUNGEON_MONSTER_RESPAWN_INFO * >::const_iterator itRespawn = (*itInstance)->vRespawnInfo.begin() ; itRespawn != (*itInstance)->vRespawnInfo.end() ; ++itRespawn )
|
|
{
|
|
if( (*itRespawn)->nID == pInfo->nID )
|
|
{
|
|
assert( 0 );
|
|
delete pInfo;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
const_cast< GameContent::INSTANCE_DUNGEON_TYPE_BASE * >( (*itInstance) )->vRespawnInfo.push_back( pInfo );
|
|
return;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
assert( 0 );
|
|
delete pInfo;
|
|
}
|
|
|
|
void onInstanceDungeonHealingPropInfo( dbInstanceDungeonHealingProp * emprs )
|
|
{
|
|
extern volatile int g_nCurrentLocalFlag;
|
|
if( g_nCurrentLocalFlag & emprs->local_flag )
|
|
return;
|
|
|
|
for( std::vector< GameContent::INSTANCE_DUNGEON_BASE * >::iterator it = GetInstanceDungeonVector().begin() ; it != GetInstanceDungeonVector().end() ; ++it )
|
|
{
|
|
if( (*it)->nID != emprs->instance_dungeon_id )
|
|
continue;
|
|
|
|
for( std::vector< const GameContent::INSTANCE_DUNGEON_TYPE_BASE * >::const_iterator itInstance = (*it)->vInstanceDungeonTypeBase.begin() ; itInstance != (*it)->vInstanceDungeonTypeBase.end() ; ++itInstance )
|
|
{
|
|
if( (*itInstance)->nID != emprs->instance_type_id )
|
|
continue;
|
|
|
|
GameContent::FIELD_PROP_RESPAWN_INFO * pInfo = new GameContent::FIELD_PROP_RESPAWN_INFO( emprs->prop_id, emprs->x, emprs->y, 0,
|
|
emprs->dv_offset_z.getFloat(), emprs->dv_around_x.getFloat(), emprs->dv_around_y.getFloat(), emprs->dv_around_z.getFloat(),
|
|
emprs->dv_scale_x.getFloat(), emprs->dv_scale_y.getFloat(), emprs->dv_scale_z.getFloat(), emprs->is_height_locked, emprs->dv_lock_height.getFloat() );
|
|
|
|
const_cast< GameContent::INSTANCE_DUNGEON_TYPE_BASE * >( (*itInstance) )->vHealingPropInfo.push_back( pInfo );
|
|
return;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
assert( 0 );
|
|
}
|
|
|
|
bool InstanceDungeonLoader::onProcess( int nThreadNum )
|
|
{
|
|
#ifdef FRAUN_PERFORMANCE_LOG
|
|
DWORD dwTime = GetSafeTickCount();
|
|
#endif
|
|
|
|
DBPerformanceTrackHelper helper;
|
|
try
|
|
{
|
|
_ConnectionPtr ContentDBConnPtr = NULL;
|
|
InitContentDbConnection( ContentDBConnPtr );
|
|
_ConnectionPtr UserDBConnPtr = NULL;
|
|
InitUserDbConnection( UserDBConnPtr );
|
|
|
|
helper.start();
|
|
size_t nLoadedInstanceDungeon = LoadDbResource< dbInstanceDungeon >( "InstanceDungeonResource", ContentDBConnPtr, onInstanceDungeonInfo );
|
|
size_t nLoadedInstanceDungeonType = LoadDbResource< dbInstanceDungeonType >( "InstanceDungeonTypeResource", ContentDBConnPtr, onInstanceDungeonTypeInfo );
|
|
size_t nLoadedMonsterRespawn = LoadDbResource< dbInstanceDungeonMonsterRespawn >( "InstanceDungeonMonsterRespawnResource", ContentDBConnPtr, onInstanceDungeonMonsterRespawnInfo );
|
|
size_t nLoadedHealingProp = LoadDbResource< dbInstanceDungeonHealingProp >( "InstanceDungeonHealingPropResource", ContentDBConnPtr, onInstanceDungeonHealingPropInfo );
|
|
helper.end( "InstanceDungeonLoader" );
|
|
|
|
for( std::vector< GameContent::INSTANCE_DUNGEON_BASE * >::const_iterator it = GetInstanceDungeonVector().begin() ; it != GetInstanceDungeonVector().end() ; ++it )
|
|
{
|
|
if( !InstanceDungeonManager::Instance().RegisterInstanceDungeonBase( (*it) ) )
|
|
{
|
|
assert( 0 );
|
|
|
|
--nLoadedInstanceDungeon;
|
|
|
|
nLoadedInstanceDungeon -= (*it)->vInstanceDungeonTypeBase.size();
|
|
for( std::vector< const GameContent::INSTANCE_DUNGEON_TYPE_BASE * >::const_iterator itInstance = (*it)->vInstanceDungeonTypeBase.begin() ; itInstance != (*it)->vInstanceDungeonTypeBase.end() ; ++itInstance )
|
|
{
|
|
nLoadedMonsterRespawn -= (*itInstance)->vRespawnInfo.size();
|
|
|
|
for( std::vector< const GameContent::INSTANCE_DUNGEON_MONSTER_RESPAWN_INFO * >::const_iterator itRespawn = (*itInstance)->vRespawnInfo.begin() ; itRespawn != (*itInstance)->vRespawnInfo.end() ; ++itRespawn )
|
|
{
|
|
delete (*itRespawn);
|
|
}
|
|
|
|
delete (*itInstance);
|
|
}
|
|
|
|
delete (*it);
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
GetInstanceDungeonVector().clear();
|
|
|
|
#ifdef FRAUN_PERFORMANCE_LOG
|
|
DWORD loadingTime = GetSafeTickCount() - dwTime;
|
|
_cprint("InstanceDungeon loader completed; time taken: %d\n", loadingTime);
|
|
FILELOG("InstanceDungeon loader completed; time taken: %d", loadingTime);
|
|
#endif
|
|
_cprint( "Total %d Instance Dungeon info loaded...\n", nLoadedInstanceDungeon );
|
|
FILELOG( "Total %d Instance Dungeon info loaded...", nLoadedInstanceDungeon );
|
|
_cprint( "Total %d Instance Dungeon Type loaded...\n", nLoadedInstanceDungeonType );
|
|
FILELOG( "Total %d Instance Dungeon Type info loaded...", nLoadedInstanceDungeonType );
|
|
_cprint( "Total %d Instance Dungeon Monster Respawn info loaded...\n", nLoadedMonsterRespawn );
|
|
FILELOG( "Total %d Instance Dungeon Monster Respawn info loaded...", nLoadedMonsterRespawn );
|
|
_cprint( "Total %d Instance Dungeon Healing Prop info loaded...\n", nLoadedHealingProp );
|
|
FILELOG( "Total %d Instance Dungeon Healing Prop info loaded...", nLoadedHealingProp );
|
|
}
|
|
catch( _com_error &e )
|
|
{
|
|
helper.end( e.Error(), "InstanceDungeonLoader" );
|
|
LogDBError( e, "InstanceDungeonLoader", "InstanceDungeonLoader::onProcess()" );
|
|
|
|
std::string strError = "INSTANCE DUNGEON RESOUCE DB ERROR : ";
|
|
strError += e.Description();
|
|
throw XException( strError );
|
|
}
|
|
|
|
return true;
|
|
} |