DragonNest/GameCommon/DnSkillTreeSystem.cpp

667 lines
23 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +08:00
#include "StdAfx.h"
#include "DnSkillTreeSystem.h"
#include "DnTableDB.h"
#if defined(_VILLAGESERVER) || defined(_GAMESERVER)
#include "DNGameDataManager.h"
#else
#include "DNTableFile.h"
#endif
#include "DnCommonUtil.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
CDnSkillTreeSystem::CDnSkillTreeSystem(void)
{
}
CDnSkillTreeSystem::~CDnSkillTreeSystem(void)
{
SAFE_DELETE_PVEC( m_vlpJobSkillTreeList );
}
bool CDnSkillTreeSystem::InitializeTable( void )
{
bool bResult = true;
// <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA>κ<EFBFBD><CEBA><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>/ <20><>/<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><>ų<EFBFBD><C5B3> ItemID <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
DNTableFileFormat* pSkillTable = GetDNTable( CDnTableDB::TSKILL );
DNTableFileFormat* pSkillLevelTable = GetDNTable( CDnTableDB::TSKILLLEVEL );
DNTableFileFormat* pSkillTreeTable = GetDNTable( CDnTableDB::TSKILLTREE );
int iNumSkill = pSkillTable->GetItemCount();
for( int iIndex = 0; iIndex < iNumSkill; ++iIndex )
{
int iSkillID = pSkillTable->GetItemID( iIndex );
// Ʈ<><C6AE><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> ID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
vector<int> vlSkillTreeTableItemID;
pSkillTreeTable->GetItemIDListFromField( "_SkillTableID", iSkillID, vlSkillTreeTableItemID );
if( (int)vlSkillTreeTableItemID.empty() )
continue;
_ASSERT( (int)vlSkillTreeTableItemID.size() == 1 );
int iTreeTableID = vlSkillTreeTableItemID.front();
// <20><>ų <20><><EFBFBD><EFBFBD> ȹ<><C8B9><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> SP <20><> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20>ִ<EFBFBD> <20>ʿ<EFBFBD> SP 1<><31>¥<EFBFBD><C2A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD>.
vector<int> vlSkillLevelList;
// pve <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>ϸ<EFBFBD> <20>ȴ<EFBFBD>.
pSkillLevelTable->GetItemIDListFromField( "_SkillIndex", iSkillID, vlSkillLevelList );
// pve, pvp <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD>Ͽ<EFBFBD> <20>ɷ<EFBFBD><C9B7><EFBFBD>.
vector<int>::iterator iterLevelList = vlSkillLevelList.begin();
for( iterLevelList; iterLevelList != vlSkillLevelList.end(); )
{
int iSkillLevelTableID = *iterLevelList;
int iApplyType = pSkillLevelTable->GetFieldFromLablePtr( iSkillLevelTableID, "_ApplyType" )->GetInteger();
if( iApplyType != 0 )
iterLevelList = vlSkillLevelList.erase( iterLevelList );
else
++iterLevelList;
}
_ASSERT( false == vlSkillLevelList.empty() );
//
if (vlSkillLevelList.empty() == true)
continue;
int iSkillLevelTableID = vlSkillLevelList.front();
int iNeedJobID = pSkillTable->GetFieldFromLablePtr( iSkillID, "_NeedJob" )->GetInteger();
map<int, S_SKILLTREE_INFO*>::iterator iter = m_mapSkillTreeByJobID.find( iNeedJobID );
if( m_mapSkillTreeByJobID.end() == iter )
{
S_SKILLTREE_INFO* pNewTree = new S_SKILLTREE_INFO;
pNewTree->iJobID = iNeedJobID;
m_mapSkillTreeByJobID.insert( make_pair(iNeedJobID, pNewTree) );
m_vlpJobSkillTreeList.push_back( pNewTree );
pNewTree->vlNodeRenderInfo.assign( MAX_SKILL_SLOT_COUNT, S_NODE_RENDER_INFO() );
}
S_SKILLTREE_INFO* pTree = m_mapSkillTreeByJobID[ iNeedJobID ];
S_NODE_INFO* pNodeInfo = new S_NODE_INFO;
pNodeInfo->iSkillID = iSkillID;
pNodeInfo->iJobID = iNeedJobID;
pNodeInfo->iNeedSkillPointToAcquire = pSkillLevelTable->GetFieldFromLablePtr( iSkillLevelTableID, "_NeedSkillPoint" )->GetInteger();
pNodeInfo->iTreeSlotIndex = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, "_TreeSlotIndex" )->GetInteger();
pNodeInfo->bDefaultLocked = (pSkillTable->GetFieldFromLablePtr( iSkillID, "_Lock" )->GetInteger() == 1) ? true : false;
#if defined( PRE_ADD_PRESET_SKILLTREE )
char szLabel[256] = {0,};
for( int itr = 0; itr < E_ADVICE_SKILL_LEVEL_COUNT; ++itr )
{
sprintf_s( szLabel, _countof(szLabel), "_AdviceSkillLevel%d", itr + 1 );
int nAdviceSkillLevel = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, szLabel )->GetInteger();
pNodeInfo->vecAdviceSkillLevel.push_back( nAdviceSkillLevel );
}
#endif // #if defined( PRE_ADD_PRESET_SKILLTREE )
#if defined( PRE_ADD_ONLY_SKILLBOOK )
pNodeInfo->bNeedSkillBook = (pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, "_NeedSkillBook" )->GetInteger() == 1) ? true : false;
#endif // #if defined( PRE_ADD_ONLY_SKILLBOOK )
// ȹ<><C8B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
char caLabel[ 32 ];
pNodeInfo->UnLockCondition.iUnlockSkillBookItemID = pSkillTable->GetFieldFromLablePtr( iSkillID, "_UnlockSkillBookItemID" )->GetInteger();
pNodeInfo->AcquireCondition.iNeedLevel = pSkillLevelTable->GetFieldFromLablePtr( iSkillLevelTableID, "_LevelLimit" )->GetInteger();
for( int i = 0; i < MAX_PARENT_SKILL_COUNT; ++i )
{
// <20><><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0 <20><> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD>.
sprintf_s( caLabel, "_NeedParentSkillLevel%d", i + 1 );
int iNeedLevel = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, caLabel )->GetInteger();
if( 0 != iNeedLevel )
pNodeInfo->AcquireCondition.vlParentSkillNeedLevel.push_back( iNeedLevel );
}
// <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><20>Ѿ<D1BE><EEB0AC>. <20><><EFBFBD>α׷<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD><C5B0> <20><> <20>̿ܿ<CCBF><DCBF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>!
_ASSERT( pNodeInfo->iTreeSlotIndex < (int)pTree->vlNodeRenderInfo.size() );
pTree->vlNodeRenderInfo.at( pNodeInfo->iTreeSlotIndex ) = S_NODE_RENDER_INFO( iSkillID, pNodeInfo->iTreeSlotIndex, iNeedJobID,
&pNodeInfo->UnLockCondition, &pNodeInfo->AcquireCondition );
pNodeInfo->pNodeRenderInfo = &(pTree->vlNodeRenderInfo[pNodeInfo->iTreeSlotIndex]);
pTree->vlpNodeList.push_back( pNodeInfo );
pTree->mapNodeBySkillID.insert( make_pair(iSkillID, pNodeInfo) );
m_mapNodeListBySkillBookID.insert( make_pair(pNodeInfo->UnLockCondition.iUnlockSkillBookItemID, pNodeInfo) );
}
// <20>θ<EFBFBD><CEB8>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> Ʈ<><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
_MakeupParentSkillLinks( pSkillTreeTable, pSkillTable );
return bResult;
}
#if defined(_VILLAGESERVER) || defined(_GAMESERVER)
bool CDnSkillTreeSystem::InitializeTableUsingDataManager( CDNGameDataManager* pDataManager )
{
bool bResult = true;
// <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA>κ<EFBFBD><CEBA><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>/ <20><>/<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><>ų<EFBFBD><C5B3> ItemID <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
#ifdef _WORK
DNTableFileFormat* pSkillTable;
if (pDataManager->GetLoaded())
pSkillTable = CDnTableDB::GetInstance().ReLoadSox( CDnTableDB::TSKILL );
else
pSkillTable = GetDNTable( CDnTableDB::TSKILL );
#else
DNTableFileFormat* pSkillTable = GetDNTable( CDnTableDB::TSKILL );
#endif
int iNumSkill = pSkillTable->GetItemCount();
for( int iIndex = 0; iIndex < iNumSkill; ++iIndex )
{
int iSkillID = pSkillTable->GetItemID( iIndex );
// Ʈ<><C6AE><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> ID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
TSkillTreeData* pSkillTreeData = pDataManager->GetSkillTreeData( iSkillID );
if( NULL == pSkillTreeData )
continue;
// <20><>ų <20><><EFBFBD><EFBFBD> ȹ<><C8B9><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> SP <20><> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20>ִ<EFBFBD> <20>ʿ<EFBFBD> SP 1<><31>¥<EFBFBD><C2A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD>.
const TSkillData* pSkillData = pDataManager->GetSkillData( iSkillID );
int iNeedJobID = pSkillData->nNeedJobID;
map<int, S_SKILLTREE_INFO*>::iterator iter = m_mapSkillTreeByJobID.find( iNeedJobID );
if( m_mapSkillTreeByJobID.end() == iter )
{
S_SKILLTREE_INFO* pNewTree = new S_SKILLTREE_INFO;
pNewTree->iJobID = iNeedJobID;
m_mapSkillTreeByJobID.insert( make_pair(iNeedJobID, pNewTree) );
m_vlpJobSkillTreeList.push_back( pNewTree );
pNewTree->vlNodeRenderInfo.assign( MAX_SKILL_SLOT_COUNT, S_NODE_RENDER_INFO() );
}
S_SKILLTREE_INFO* pTree = m_mapSkillTreeByJobID[ iNeedJobID ];
S_NODE_INFO* pNodeInfo = new S_NODE_INFO;
pNodeInfo->iSkillID = iSkillID;
pNodeInfo->iJobID = iNeedJobID;
// <20><>ų <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20>ش<EFBFBD> <20><>ų id <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѱ<EFBFBD>.
if( pSkillData->vLevelDataList.empty() )
{
g_Log.Log( LogType::_ERROR, L"[CSkillTreeSystem::InitializeTableUsingDataManager] Not Exist SkillLevelTable Data!! SkillID: %d \r\n", iSkillID );
SAFE_DELETE( pNodeInfo );
continue;
}
pNodeInfo->iNeedSkillPointToAcquire = pSkillData->vLevelDataList.front().nNeedSkillPoint;
pNodeInfo->iTreeSlotIndex = pSkillTreeData->nTreeSlotIndex;
pNodeInfo->bDefaultLocked = pSkillData->bDefaultLocked;
#if defined( PRE_ADD_ONLY_SKILLBOOK )
pNodeInfo->bNeedSkillBook = pSkillTreeData->bNeedSkillBook;
#endif // #if defined( PRE_ADD_ONLY_SKILLBOOK )
// ȹ<><C8B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
pNodeInfo->UnLockCondition.iUnlockSkillBookItemID = pSkillData->nUnlockSkillBookItemID;
pNodeInfo->AcquireCondition.iNeedLevel = pSkillData->vLevelDataList.front().cLevelLimit;
for( int i = 0; i < MAX_PARENT_SKILL_COUNT; ++i )
{
// <20><><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0 <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int iNeedLevel = pSkillTreeData->nNeedParentSkillLevel[ i ];
if( 0 != iNeedLevel )
pNodeInfo->AcquireCondition.vlParentSkillNeedLevel.push_back( iNeedLevel );
}
// <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><20>Ѿ<D1BE><EEB0AC>. <20><><EFBFBD>α׷<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD><C5B0> <20><> <20>̿ܿ<CCBF><DCBF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>!
_ASSERT( pNodeInfo->iTreeSlotIndex < (int)pTree->vlNodeRenderInfo.size() );
pTree->vlNodeRenderInfo.at( pNodeInfo->iTreeSlotIndex ) = S_NODE_RENDER_INFO( iSkillID, pNodeInfo->iTreeSlotIndex, iNeedJobID,
&pNodeInfo->UnLockCondition, &pNodeInfo->AcquireCondition );
pNodeInfo->pNodeRenderInfo = &(pTree->vlNodeRenderInfo[pNodeInfo->iTreeSlotIndex]);
pTree->vlpNodeList.push_back( pNodeInfo );
pTree->mapNodeBySkillID.insert( make_pair(iSkillID, pNodeInfo) );
m_mapNodeListBySkillBookID.insert( make_pair(pNodeInfo->UnLockCondition.iUnlockSkillBookItemID, pNodeInfo) );
}
// <20>θ<EFBFBD><CEB8>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> Ʈ<><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
int iNumTreeNode = pDataManager->GetNumSkillTreeData();
for( int iIndex = 0; iIndex < iNumTreeNode; ++iIndex )
{
const TSkillTreeData* pSkillTreeData = pDataManager->GetSkillTreeDataByIndex( iIndex );
//const TSkillData* pSkillData = pDataManager->GetSkillData( pSkillTreeData->nSkillID );
//int iJobID = pSkillData->nNeedJobID;
S_NODE_INFO* pNodeInfo = _FindNode( pSkillTreeData->nSkillID );
if( NULL == pNodeInfo )
{
OutputDebug( "[%d] <20><>ų Ʈ<><C6AE> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų ID\n", pSkillTreeData->nSkillID );
_ASSERT( !"<EFBFBD><EFBFBD>ų Ʈ<><C6AE> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų ID" );
}
else
{
#if defined(PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP)
pNodeInfo->pNodeRenderInfo->vlNeedJobSP.push_back(pSkillTreeData->nNeedBasicSP);
pNodeInfo->pNodeRenderInfo->vlNeedJobSP.push_back(pSkillTreeData->nNeedFirstSP);
pNodeInfo->pNodeRenderInfo->vlNeedJobSP.push_back(pSkillTreeData->nNeedSecondSP);
#endif // PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP
}
// <20>θ<EFBFBD> <20><>ų ã<>Ƽ<EFBFBD> <20>ڱ<EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>Ͻ<EFBFBD>Ų<EFBFBD><C5B2>.
for( int i = 0; i < MAX_PARENT_SKILL_COUNT; ++i )
{
int iParentSkillID = pSkillTreeData->nParentSkillID[ i ];
if( 0 != iParentSkillID )
{
S_NODE_INFO* pParentNodeInfo = _FindNode( iParentSkillID );
if( NULL == pParentNodeInfo )
{
OutputDebug( "[%d <20><> <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d] <20><>ų Ʈ<><C6AE> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų ID\n", pSkillTreeData->nSkillID, iParentSkillID );
_ASSERT( !"<EFBFBD><EFBFBD>ų Ʈ<><C6AE> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų ID" );
}
if( pNodeInfo )
pNodeInfo->vlpParentNodeInfo.push_back( pParentNodeInfo );
if( pParentNodeInfo )
pParentNodeInfo->vlpChildNodeInfo.push_back( pNodeInfo );
}
}
}
return bResult;
}
#endif
CDnSkillTreeSystem::S_NODE_INFO* CDnSkillTreeSystem::_FindNode( int iSkillID )
{
S_NODE_INFO* pNodeInfo = NULL;
vector<S_SKILLTREE_INFO*>::iterator iter = m_vlpJobSkillTreeList.begin();
for( iter; iter != m_vlpJobSkillTreeList.end(); ++iter )
{
map<int, S_NODE_INFO*>& mapNodeBySkillID = (*iter)->mapNodeBySkillID;
map<int, S_NODE_INFO*>::iterator iterNode = mapNodeBySkillID.find( iSkillID );
if( mapNodeBySkillID.end() != iterNode )
{
pNodeInfo = iterNode->second;
}
}
return pNodeInfo;
}
#ifdef PRE_ADD_ONLY_SKILLBOOK
bool CDnSkillTreeSystem::IsNeedSkillBook( int iSkillID, bool& bExistSkill )
{
S_NODE_INFO* pNodeInfo = NULL;
vector<S_SKILLTREE_INFO*>::iterator iter = m_vlpJobSkillTreeList.begin();
for( iter; iter != m_vlpJobSkillTreeList.end(); ++iter )
{
map<int, S_NODE_INFO*>& mapNodeBySkillID = (*iter)->mapNodeBySkillID;
map<int, S_NODE_INFO*>::iterator iterNode = mapNodeBySkillID.find( iSkillID );
if( mapNodeBySkillID.end() != iterNode )
{
pNodeInfo = iterNode->second;
}
}
if( pNodeInfo )
{
bExistSkill = true;
return pNodeInfo->bNeedSkillBook;
}
bExistSkill = false;
return false;
}
#endif // PRE_ADD_ONLY_SKILLBOOK
void CDnSkillTreeSystem::_MakeupParentSkillLinks( DNTableFileFormat* pSkillTreeTable, DNTableFileFormat* pSkillTable )
{
// <20>θ<EFBFBD>/<2F>ڽ<EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̾<EFBFBD><CCBE>ش<EFBFBD>.
int iNumTreeNode = pSkillTreeTable->GetItemCount();
for( int iIndex = 0; iIndex < iNumTreeNode; ++iIndex )
{
int iTreeTableID = pSkillTreeTable->GetItemID( iIndex );
int iSkillID = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, "_SkillTableID" )->GetInteger();
if( 0 == iSkillID )
continue;
int iJobID = pSkillTable->GetFieldFromLablePtr( iSkillID, "_NeedJob" )->GetInteger();
S_NODE_INFO* pNodeInfo = _FindNode( iSkillID );
_ASSERT( pNodeInfo && "<EFBFBD><EFBFBD>ų Ʈ<><C6AE> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų ID" );
if( pNodeInfo )
{
// <20>θ<EFBFBD> <20><>ų ã<>Ƽ<EFBFBD> <20>ڱ<EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>Ͻ<EFBFBD>Ų<EFBFBD><C5B2>.
char caLabel[ 32 ];
for( int i = 0; i < MAX_PARENT_SKILL_COUNT; ++i )
{
sprintf_s( caLabel, "_ParentSkillID%d", i + 1 );
int iParentSkillID = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, caLabel )->GetInteger();
if( 0 != iParentSkillID )
{
S_NODE_INFO* pParentNodeInfo = _FindNode( iParentSkillID );
if (pParentNodeInfo == NULL)
continue;
pNodeInfo->vlpParentNodeInfo.push_back( pParentNodeInfo );
pNodeInfo->pNodeRenderInfo->vlParentSkillJobIDs.push_back( pParentNodeInfo->iJobID );
pNodeInfo->pNodeRenderInfo->vlParentSkillIDs.push_back( pParentNodeInfo->iSkillID );
_ASSERT( pNodeInfo->iSkillID == pNodeInfo->pNodeRenderInfo->iSkillID && "<EFBFBD><EFBFBD>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ߺ<EFBFBD><DFBA>Ǿ<EFBFBD><C7BE><EFBFBD> <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>." );
if( pNodeInfo->iSkillID != pNodeInfo->pNodeRenderInfo->iSkillID )
{
OutputDebug( "[SkillID: %d] <20><>ų <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD>(%d)<29><> <20>ߺ<EFBFBD><DFBA>Ǿ<EFBFBD><C7BE><EFBFBD> <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.\n",
pNodeInfo->iSkillID, pNodeInfo->pNodeRenderInfo->iSlotIndex );
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ʈ<><C6AE> <20>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD><EFBFBD> <20>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>.
if( pNodeInfo->iJobID == pParentNodeInfo->iJobID )
pParentNodeInfo->pNodeRenderInfo->vlChildSlotIndexInJob.push_back( pNodeInfo->iTreeSlotIndex );
pParentNodeInfo->vlpChildNodeInfo.push_back( pNodeInfo );
}
}
#if defined(PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP)
int nLimitSPValue = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, "_NeedBasicSP1" )->GetInteger();
pNodeInfo->pNodeRenderInfo->vlNeedJobSP.push_back(nLimitSPValue);
nLimitSPValue = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, "_NeedFirstSP1" )->GetInteger();
pNodeInfo->pNodeRenderInfo->vlNeedJobSP.push_back(nLimitSPValue);
nLimitSPValue = pSkillTreeTable->GetFieldFromLablePtr( iTreeTableID, "_NeedSecondSP1" )->GetInteger();
pNodeInfo->pNodeRenderInfo->vlNeedJobSP.push_back(nLimitSPValue);
#endif // PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP
}
}
}
void CDnSkillTreeSystem::TryUnLockSkill( const S_TRY_UNLOCK& PresentInfo, S_OUTPUT* pResult )
{
const S_NODE_INFO* pSkillNodeInfo = _FindNode( PresentInfo.iTryUnlockSkillID );
// <20>־<EFBFBD><D6BE><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20><>ų <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD>ϴ°<CFB4>.
if( NULL == pSkillNodeInfo )
{
pResult->eResult = R_ERROR;
pResult->eErrorCode = E_CANT_FIND_SKILLNODE;
return;
}
//// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD>ϴ°<CFB4>. <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
//if( pSkillNodeInfo->iJobID != PresentInfo.iJobID )
//{
// pResult->eResult = R_ERROR;
// pResult->eErrorCode = E_MISMATCH_JOB;
//}
//<2F><>ų<EFBFBD><C5B3> <20><><EFBFBD>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>?
#if defined(PRE_FIX_51727)
#else
// <20><>ų<EFBFBD><C5B3><EFBFBD><EFBFBD> <20>´<EFBFBD><C2B4><EFBFBD>.
if( PresentInfo.iSkillBookItemID != pSkillNodeInfo->UnLockCondition.iUnlockSkillBookItemID )
{
pResult->eResult = R_INVALID_SKILLBOOK_ITEMID;
return;
}
#endif // PRE_FIX_51727
#if defined(_CLIENT) && defined( PRE_ADD_ONLY_SKILLBOOK )
if( true == pSkillNodeInfo->bNeedSkillBook )
{
pResult->eResult = R_ONLY_SKILL_BOOK;
return;
}
#endif // #if defined( PRE_ADD_ONLY_SKILLBOOK )
pResult->eResult = R_SUCCESS;
}
void CDnSkillTreeSystem::TryAcquireSkill( const S_TRY_ACQUIRE& TryAcquire, S_OUTPUT* pResult )
{
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD>, <20>ʿ䷹<CABF><E4B7B9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD>.
const S_NODE_INFO* pSkillNodeInfo = _FindNode( TryAcquire.iTryAcquireSkillID );
// <20><><EFBFBD><EFBFBD>(<28>θ<EFBFBD>)<29><>ų ȹ<><C8B9> <20><><EFBFBD><EFBFBD>.
// <20>־<EFBFBD><D6BE><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20><>ų <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD>ϴ°<CFB4>.
if( NULL == pSkillNodeInfo )
{
pResult->eResult = R_ERROR;
pResult->eErrorCode = E_CANT_FIND_SKILLNODE;
return;
}
// <20><><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵٸ<D1B4> ȹ<><C8B9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD>.
// SkillInfo <20><><EFBFBD><EFBFBD>ü<EFBFBD><C3BC> <20>´<EFBFBD> <20>Լ<EFBFBD> <20><>ü.
struct FindSkill : unary_function<const S_POSSESSED_SKILL_INFO, bool>
{
int m_iSkillIDToFind;
FindSkill( int iSkillID ) : m_iSkillIDToFind( iSkillID ) {};
bool operator () ( const S_POSSESSED_SKILL_INFO& SkillInfo )
{
return SkillInfo.iSkillID == m_iSkillIDToFind;
}
};
//// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD>ϴ°<CFB4>. <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
//if( pSkillNodeInfo->iJobID != TryAcquire.iJobID )
//{
// pResult->eResult = R_ERROR;
// pResult->eErrorCode = E_MISMATCH_JOB;
//}
// <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD>... <20>ٵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> üũ <20><><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߰ڱ<DFB0>.
if( TryAcquire.iCurrentCharLevel < pSkillNodeInfo->AcquireCondition.iNeedLevel )
{
pResult->eResult = R_NOT_ENOUGH_CHAR_LEVEL;
return;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ.
if( TryAcquire.iHasSkillPoint < pSkillNodeInfo->iNeedSkillPointToAcquire )
{
pResult->eResult = R_NOT_ENOUGH_SKILLPOINT_TO_ACQUIRE;
return;
}
// <20>θ<EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD>. <20>θ<EFBFBD><CEB8><EFBFBD>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20><>.
if( false == pSkillNodeInfo->vlpParentNodeInfo.empty() )
{
size_t NumParentSkill = pSkillNodeInfo->vlpParentNodeInfo.size();
for( size_t i = 0; i < NumParentSkill; ++i )
{
const S_NODE_INFO* pParentNodeInfo = pSkillNodeInfo->vlpParentNodeInfo.at( i );
vector<S_POSSESSED_SKILL_INFO>::const_iterator iter = find_if( TryAcquire.vlPossessedSkillInfo.begin(), TryAcquire.vlPossessedSkillInfo.end(),
FindSkill(pParentNodeInfo->iSkillID) );
if( TryAcquire.vlPossessedSkillInfo.end() == iter )
{
pResult->eResult = R_DONT_HAVE_PARENT_SKILL;
return;
}
// <20>θ<EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD><CCBE><EFBFBD> <20><>.
if( true == iter->bCurrentLock )
{
pResult->eResult = R_LOCKED_PARENTSKILL;
return;
}
// <20>θ<EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̻<EFBFBD> <20>÷<EFBFBD><C3B7>־<EFBFBD><D6BE><EFBFBD> <20><>.
int iParentSkillNeedLevel = pSkillNodeInfo->AcquireCondition.vlParentSkillNeedLevel.at( i );
if( iter->iSkillLevel < iParentSkillNeedLevel )
{
pResult->eResult = R_NOT_ENOUGH_PARENT_SKILL_LEVEL;
return;
}
}
}
pResult->eResult = R_SUCCESS;
}
int CDnSkillTreeSystem::GetNodeCount( int iJobID ) const
{
int iResult = 0;
map<int, S_SKILLTREE_INFO*>::const_iterator iter = m_mapSkillTreeByJobID.find( iJobID );
if( m_mapSkillTreeByJobID.end() != iter )
iResult = (int)iter->second->vlpNodeList.size();
return iResult;
}
int CDnSkillTreeSystem::GetSlotCount( int iJobID ) const
{
int iResult = 0;
map<int, S_SKILLTREE_INFO*>::const_iterator iter = m_mapSkillTreeByJobID.find( iJobID );
if( m_mapSkillTreeByJobID.end() != iter )
{
// <20><><EFBFBD>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>þ<C3BE>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><C5A9>.
//iResult = (int)iter->second->vlNodeRenderInfo.back().iSlotIndex + 1;
iResult = MAX_SKILL_SLOT_COUNT;
}
return iResult;
}
void CDnSkillTreeSystem::GetNodeRenderInfo( int iSlotIndex, int iJobID, /*OUT*/S_NODE_RENDER_INFO* pNodeRenderInfo ) const
{
_ASSERT( pNodeRenderInfo );
if( NULL == pNodeRenderInfo )
return;
map<int, S_SKILLTREE_INFO*>::const_iterator iter = m_mapSkillTreeByJobID.find( iJobID );
if( m_mapSkillTreeByJobID.end() != iter )
{
const S_SKILLTREE_INFO* pSkillTree = iter->second;
if( NULL == pSkillTree )
return;
_ASSERT( iSlotIndex < (int)pSkillTree->vlNodeRenderInfo.size() );
if( iSlotIndex < (int)pSkillTree->vlNodeRenderInfo.size() )
*pNodeRenderInfo = pSkillTree->vlNodeRenderInfo.at( iSlotIndex );
}
}
int CDnSkillTreeSystem::FindSkillBySkillBook( int iSkillBookItemID )
{
int iResult = 0;
map<int, S_NODE_INFO*>::iterator iter = m_mapNodeListBySkillBookID.find( iSkillBookItemID );
if( m_mapNodeListBySkillBookID.end() != iter )
{
iResult = iter->second->iSkillID;
}
return iResult;
}
#ifdef PRE_ADD_LEVELUP_GUIDE
void CDnSkillTreeSystem::GetLevelUpSkillInfo(std::vector<int>& newSkillIdList, int newLevel, int jobId)
{
std::map<int, S_SKILLTREE_INFO*>::const_iterator iter = m_mapSkillTreeByJobID.find(jobId);
if (m_mapSkillTreeByJobID.end() != iter)
{
const S_SKILLTREE_INFO* pInfo = (*iter).second;
if (pInfo)
{
const std::vector<S_NODE_INFO*>& nodeInfoList = pInfo->vlpNodeList;
std::vector<S_NODE_INFO*>::const_iterator nodeInfoIter = nodeInfoList.begin();
for (; nodeInfoIter != nodeInfoList.end(); ++nodeInfoIter)
{
const S_NODE_INFO* pNodeInfo = (*nodeInfoIter);
if (pNodeInfo && (pNodeInfo->AcquireCondition.iNeedLevel == newLevel))
newSkillIdList.push_back(pNodeInfo->iSkillID);
}
}
}
}
void CDnSkillTreeSystem::GetLevelUpSkillInfo(std::vector<int>& newSkillIdList, int newLevel, const std::vector<int>& jobHistoryVec)
{
std::vector<int>::const_iterator& iter = jobHistoryVec.begin();
for (; iter != jobHistoryVec.end(); ++iter)
{
const int& jobId = *iter;
if (CommonUtil::IsValidCharacterJobId(jobId) == false)
continue;
GetLevelUpSkillInfo(newSkillIdList, newLevel, jobId);
}
}
#endif
#if defined(PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP)
void CDnSkillTreeSystem::GetNeedSPValuesByJob(int nSkillID, std::vector<int>& nNeedSPValues)
{
CDnSkillTreeSystem::S_NODE_INFO* pInfo = _FindNode(nSkillID);
if (pInfo && pInfo->pNodeRenderInfo)
nNeedSPValues = pInfo->pNodeRenderInfo->vlNeedJobSP;
}
#endif // PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP
int CDnSkillTreeSystem::IsParentSkill( const int nParentSkillID, const int nChildSkillID )
{
S_NODE_INFO * pData = _FindNode( nChildSkillID );
if( NULL == pData )
return 0;
for( DWORD itr = 0; itr < pData->vlpParentNodeInfo.size(); ++itr )
{
if( nParentSkillID == pData->vlpParentNodeInfo[itr]->iSkillID )
return pData->AcquireCondition.vlParentSkillNeedLevel[itr];
}
return 0;
}
void CDnSkillTreeSystem::GetParentSkillData( const int nChildSkillID, std::vector< std::pair<int, int> > & vecParentSkillData )
{
S_NODE_INFO * pData = _FindNode( nChildSkillID );
if( NULL == pData )
return;
for( DWORD itr = 0; itr < pData->vlpParentNodeInfo.size(); ++itr )
vecParentSkillData.push_back( std::make_pair( pData->vlpParentNodeInfo[itr]->iSkillID, pData->AcquireCondition.vlParentSkillNeedLevel[itr] ) );
}
#if defined( PRE_ADD_PRESET_SKILLTREE )
void CDnSkillTreeSystem::GetAdviceSkillTree( const int nAdviceSkill_Index, const std::vector<int> & vecJobList, std::vector< std::pair<int, BYTE> > & vecData )
{
if( E_ADVICE_SKILL_LEVEL_COUNT <= nAdviceSkill_Index )
return;
vecData.clear();
for( DWORD itr = 0; itr < vecJobList.size(); ++itr )
{
if( NULL == m_mapSkillTreeByJobID[ vecJobList[itr] ] )
continue;
std::vector<S_NODE_INFO*> & vecNodeList = m_mapSkillTreeByJobID[ vecJobList[itr] ]->vlpNodeList;
std::vector<S_NODE_INFO*>::iterator Itor = vecNodeList.begin();
for( ; Itor != vecNodeList.end(); ++Itor )
{
BYTE cAdviceSkillLevel = (*Itor)->vecAdviceSkillLevel[ nAdviceSkill_Index ];
if( 0 != cAdviceSkillLevel )
vecData.push_back( std::make_pair( (*Itor)->iSkillID, cAdviceSkillLevel ) );
}
}
}
#endif // #if defined( PRE_ADD_PRESET_SKILLTREE )