#include "Stdafx.h" #include "TotalLevelSkillSystem.h" #include "DnTableDB.h" #include "DnActor.h" #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) CDnTotalLevelSkillSystem::CDnTotalLevelSkillSystem(DnActorHandle hActor) { m_hActor = hActor; m_TotalLevel = 0; //±âº»ÀûÀ» ½½·Ôµé ºñ Ȱ¼ºÈ­ ½ÃÄÑ ³õ´Â´Ù. for (int i = 0; i < TotallevelSkill_Slot_Count; ++i) { DnSkillHandle hSkill; ActivateTotalLevelSkillSlot(i, false); AddTotalLevelSkill(i, hSkill); } LoadTotalLevelSkillList(); LoadTotalLevelSkillSlotInfo(); } CDnTotalLevelSkillSystem::~CDnTotalLevelSkillSystem() { std::map::iterator iter = m_ActiveTotalLevelSkillList.begin(); std::map::iterator endIter = m_ActiveTotalLevelSkillList.end(); for (; iter != endIter; ++iter) { if (m_hActor && iter->second) m_hActor->RemoveSkill(iter->second->GetClassID()); } SAFE_RELEASE_SPTRVEC( m_vlTotalLevelSkillList ); m_TotalLevelSkillInfoList.clear(); m_TotalLevelSlotInfoList.clear(); } void CDnTotalLevelSkillSystem::LoadTotalLevelSkillList() { SAFE_RELEASE_SPTRVEC( m_vlTotalLevelSkillList ); m_TotalLevelSkillInfoList.clear(); DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TTOTALLEVELSKILL ); if( pSox == NULL ) { DN_ASSERT( 0, "Invalid TotalLevelSkill" ); return; } for( int i=0; i<=pSox->GetItemCount(); i++ ) { int nItemID = pSox->GetItemID( i ); if (nItemID == -1) continue; _TotalLevelSkillInfo _info; _info.m_SkillID = pSox->GetFieldFromLablePtr( nItemID, "_SkillTableID" )->GetInteger(); _info.m_TotalLevelLimit = pSox->GetFieldFromLablePtr( nItemID, "_TotalLevelLimit" )->GetInteger(); _info.m_ActorLevelLimit = pSox->GetFieldFromLablePtr( nItemID, "_LevelLimit" )->GetInteger(); _info.m_SkillType = pSox->GetFieldFromLablePtr( nItemID, "_SkillType" )->GetInteger(); _info.m_SkillTreeSlotIndex = pSox->GetFieldFromLablePtr( nItemID, "_TreeSlotIndex" )->GetInteger(); m_TotalLevelSkillInfoList.insert(std::make_pair(_info.m_SkillID, _info)); DnSkillHandle hSkill; hSkill = CDnSkill::CreateSkill( m_hActor, _info.m_SkillID, 1 ); if( hSkill ) { m_vlTotalLevelSkillList.push_back( hSkill ); } } } void CDnTotalLevelSkillSystem::LoadTotalLevelSkillSlotInfo() { m_TotalLevelSlotInfoList.clear(); DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TTOTALLEVELLSKILLSLOT ); if( pSox == NULL ) { DN_ASSERT( 0, "Invalid TotalLevelSkillSlot" ); return; } for( int i=0; i<=pSox->GetItemCount(); i++ ) { int nItemID = pSox->GetItemID( i ); if (nItemID == -1) continue; _TotalLevelSkillSlotInfo _info; _info.m_LevelLimit = pSox->GetFieldFromLablePtr( nItemID, "_LevelLimit" )->GetInteger(); _info.m_SlotIndex = pSox->GetFieldFromLablePtr( nItemID, "_SlotID" )->GetInteger() - 1; _info.m_isCashSlot = pSox->GetFieldFromLablePtr( nItemID, "_IsCash" )->GetBool(); _info.m_ExpireDate = 0; m_TotalLevelSlotInfoList.insert(std::make_pair(_info.m_SlotIndex, _info)); } } DnSkillHandle CDnTotalLevelSkillSystem::FindTotalLevelSkill( int nSkillTableID ) { DnSkillHandle hRetSkill; vector::iterator iter = m_vlTotalLevelSkillList.begin(); for( ; iter != m_vlTotalLevelSkillList.end(); iter++ ) { DnSkillHandle hSkill = (*iter); if( hSkill->GetClassID() == nSkillTableID ) { hRetSkill = (*iter); break; } } return hRetSkill; } bool CDnTotalLevelSkillSystem::IsTotalLevelSkill( int nSkillTableID ) { DnSkillHandle hSkill = FindTotalLevelSkill( nSkillTableID ); if( hSkill ) return true; return false; } CDnTotalLevelSkillSystem::_TotalLevelSkillInfo* CDnTotalLevelSkillSystem::GetTotalLevelSkillInfo(int nSkillID) { _TotalLevelSkillInfo* pInfo = NULL; std::map::iterator skillInfoIter = m_TotalLevelSkillInfoList.find(nSkillID); if (skillInfoIter != m_TotalLevelSkillInfoList.end()) pInfo = &skillInfoIter->second; return pInfo; } bool CDnTotalLevelSkillSystem::IsUsableSkill(DnSkillHandle hSkill) { if (!hSkill) return false; if (!m_hActor) return false; _TotalLevelSkillInfo* pSkillInfo = GetTotalLevelSkillInfo(hSkill->GetClassID()); if (pSkillInfo == NULL) return false; //ÅëÇÕ ·¹º§ Á¦ÇÑ È®ÀÎ.. if (m_TotalLevel < pSkillInfo->m_TotalLevelLimit) return false; //¾×ÅÍ ·¹º§ Á¦ÇÑ int nActorLevel = m_hActor->GetLevel(); if (nActorLevel < pSkillInfo->m_ActorLevelLimit) return false; return true; } int CDnTotalLevelSkillSystem::CanAddSkill(int slotIndex, DnSkillHandle hSkill) { int nErrorCode = 0; if (IsUsableSkill(hSkill) == false) return TotalLevelSystem_Error_NotUsable; //½½·ÔÀÌ È°¼ºÈ­ µÇ¾î ÀÖ´ÂÁö È®ÀÎ. bool bSlotActivate = false; std::map::iterator slotActivateIter = m_TotalLevelSkillSlotActivate.find(slotIndex); if (slotActivateIter != m_TotalLevelSkillSlotActivate.end()) { bSlotActivate = slotActivateIter->second; } //½½·ÔÀÌ È°¼ºÈ­ µÇ¾î ÀÖÁö ¾ÊÀ¸¸é Ãß°¡ ¾ÈµÊ... if (bSlotActivate == false) return TotalLevelSystem_Error_NotActivateSlot; //Ãß°¡ ÇÏ·Á´Â ÅëÇÕ ·¹º§ ½ºÅ³ ŸÀÔ È®ÀÎ.. int nAddSkillType = TotalLevelSkill_Type_None; _TotalLevelSkillInfo* pSkillInfo = GetTotalLevelSkillInfo(hSkill->GetClassID()); if (pSkillInfo) nAddSkillType = pSkillInfo->m_SkillType; else return TotalLevelSystem_Error_NotUsable; bool bCheckSlotType = false; std::map::iterator slotIter = m_TotalLevelSlotInfoList.find(slotIndex); if (slotIter != m_TotalLevelSlotInfoList.end()) { _TotalLevelSkillSlotInfo& _info = slotIter->second; //ij½¬ ½½·Ô¿¡ Ãß°¡´Â ½½·ÔÀÌ È°¼ºÈ­ µÇ¾î ÀÖÀ¸¸é ¹«Á¶°Ç Ãß°¡ if (_info.m_isCashSlot == true) nErrorCode = TotalLevelSystem_Error_None; else { if (m_ActiveTotalLevelSkillList.empty() == true) nErrorCode = TotalLevelSystem_Error_None; else { bool bExistSkillType = false; //°°Àº ÅëÇÕ ·¹º§ ½ºÅ³ ŸÀÔÀÌ ÀÌ¹Ì Ãß°¡ µÇ¾î ÀÖÀ¸¸é Ãß°¡ ¾ÈµÊ.. std::map::iterator activateSkillIter = m_ActiveTotalLevelSkillList.begin(); std::map::iterator activateSkillEndIter = m_ActiveTotalLevelSkillList.end(); for (; activateSkillIter != activateSkillEndIter; ++activateSkillIter) { if (!activateSkillIter->second) continue; int nTotalLevelSkillType = TotalLevelSkill_Type_None; pSkillInfo = GetTotalLevelSkillInfo(activateSkillIter->second->GetClassID()); if (pSkillInfo) nTotalLevelSkillType = pSkillInfo->m_SkillType; //°°Àº ½½·Ô indexÀÎ °æ¿ì °°Àº ŸÀÔÀÇ ½ºÅ³ÀÌ ÀÖÀ¸¸é ¹«½Ã ÇÏ°í ½ºÅ³ Ãß°¡ÇÑ´Ù. if (activateSkillIter->first == slotIndex) { if (nTotalLevelSkillType == nAddSkillType) { if (hSkill->GetClassID() == activateSkillIter->second->GetClassID()) { nErrorCode = TotalLevelSystem_Error_NotUsable; return nErrorCode; } } } else { //ÀÌ ½½·ÔÀÌ Ä³½Ã ½½·ÔÀ̶ó¸é Ãß°¡ °¡´É... //ij½Ã ½½·ÔÀÌ ¾Æ´Ï°í, °°Àº ½ºÅ³ ŸÀÔÀ̸é Ãß°¡ ¾ÈµÊ. std::map::iterator oldSlotIter = m_TotalLevelSlotInfoList.find(activateSkillIter->first); if (oldSlotIter != m_TotalLevelSlotInfoList.end()) { if (oldSlotIter->second.m_isCashSlot != true && nTotalLevelSkillType == nAddSkillType) { bExistSkillType = true; break; } } } } //°°Àº ½ºÅ³ ŸÀÔÀÌ ¾ø¾î¾ß Ãß°¡ µÊ. if (bExistSkillType == false) nErrorCode = TotalLevelSystem_Error_None; else nErrorCode = TotalLevelSystem_Error_SameSkillType; } } } return nErrorCode; } void CDnTotalLevelSkillSystem::AddTotalLevelSkill(int slotIndex, DnSkillHandle hSkill, bool isInitialize/* = false*/) { DnSkillHandle hActivateSkill; std::map::iterator findIter = m_ActiveTotalLevelSkillList.find(slotIndex); if (findIter != m_ActiveTotalLevelSkillList.end()) hActivateSkill = findIter->second; //±âÁ¸¿¡ ÀÖ´Â ½ºÅ³Àº Á¦°Å Çϰí if (hActivateSkill) m_hActor->RemoveSkill(hActivateSkill->GetClassID()); if (hSkill) m_hActor->OnAddSkill(hSkill, isInitialize); //±âÁ¸ ½½·Ô Á¤º¸°¡ ÀÖÀ¸¸é ½ºÅ³ ´ëü Çϰí, if (findIter != m_ActiveTotalLevelSkillList.end()) { //»õ·Î µî·ÏÇÒ ½ºÅ³ÀÌ ÀÖÀ¸¸é ½ºÅ³ º¯°æÇϰí, »õ·Î µî·ÏÇÒ ½ºÅ³ÀÌ ¾øÀ¸¸é Á¤º¸ Á¦°Å if (hSkill) findIter->second = hSkill; else findIter->second.Identity(); } else { m_ActiveTotalLevelSkillList.insert(std::make_pair(slotIndex, hSkill)); } } DnSkillHandle CDnTotalLevelSkillSystem::GetActivateTotalLevelSkill(int slotIndex) { DnSkillHandle hActivateSkill; std::map::iterator findIter = m_ActiveTotalLevelSkillList.find(slotIndex); if (findIter != m_ActiveTotalLevelSkillList.end()) hActivateSkill = findIter->second; return hActivateSkill; } void CDnTotalLevelSkillSystem::RemoveTotallevelSkill(int slotIndex) { DnSkillHandle hActivateSkill = GetActivateTotalLevelSkill(slotIndex); if (hActivateSkill) { m_hActor->RemoveSkill(hActivateSkill->GetClassID()); //½ÇÁ¦ ¸®½ºÆ®¿¡¼­ ½ºÅ³ ÃʱâÈ­.. RemoveTotalLevelSkillFromList(slotIndex); } } void CDnTotalLevelSkillSystem::RemoveTotalLevelSkillFromList(int slotIndex) { std::map::iterator findIter = m_ActiveTotalLevelSkillList.find(slotIndex); if (findIter != m_ActiveTotalLevelSkillList.end()) findIter->second.Identity(); } void CDnTotalLevelSkillSystem::ActivateTotalLevelSkillSlot(int slotIndex, bool bActivate) { if (bActivate == false) { //½½·ÔÀÌ ºñ Ȱ¼ºÈ­ µÉ °æ¿ì ±âÁ¸ÀÇ ½ºÅ³ÀÌ ÀÖÀ¸¸é ½ºÅ³ Á¦°Å.. DnSkillHandle hActivateSkill = GetActivateTotalLevelSkill(slotIndex); if (hActivateSkill) RemoveTotallevelSkill(slotIndex); } std::map::iterator iter = m_TotalLevelSkillSlotActivate.find(slotIndex); if (iter != m_TotalLevelSkillSlotActivate.end()) iter->second = bActivate; else m_TotalLevelSkillSlotActivate.insert(std::make_pair(slotIndex, bActivate)); } void CDnTotalLevelSkillSystem::SetTotalLevel(int totalLevel) { if (m_TotalLevel == totalLevel) return; m_TotalLevel = totalLevel; UpdateTotalLevel(); } void CDnTotalLevelSkillSystem::UpdateTotalLevel() { int nCharLevel = m_hActor ? m_hActor->GetLevel() : -1; //½½·Ô Ȱ¼ºÈ­ Á¤º¸ °»½Å std::map::iterator iter = m_TotalLevelSlotInfoList.begin(); std::map::iterator endIter = m_TotalLevelSlotInfoList.end(); for (; iter != endIter; ++iter) { _TotalLevelSkillSlotInfo& _info = iter->second; if (_info.m_isCashSlot == false) { bool bActivate = nCharLevel != -1 ? nCharLevel >= _info.m_LevelLimit : false; ActivateTotalLevelSkillSlot(_info.m_SlotIndex, bActivate); } } } void CDnTotalLevelSkillSystem::ActivateTotalLevelSkillCashSlot(int nSlotIndex, bool bActivate, __time64_t tExpireDate) { //½½·Ô Ȱ¼ºÈ­ Á¤º¸ °»½Å std::map::iterator iter = m_TotalLevelSlotInfoList.begin(); std::map::iterator endIter = m_TotalLevelSlotInfoList.end(); for (; iter != endIter; ++iter) { _TotalLevelSkillSlotInfo& _info = iter->second; if (_info.m_SlotIndex == nSlotIndex && _info.m_isCashSlot == true) { ActivateTotalLevelSkillSlot(_info.m_SlotIndex, bActivate); _info.m_ExpireDate = tExpireDate; } } } void CDnTotalLevelSkillSystem::Process(LOCAL_TIME localTime, float fDelta) { vector::iterator iter = m_vlTotalLevelSkillList.begin(); vector::iterator endIter = m_vlTotalLevelSkillList.end(); for (; iter != endIter; ++iter) { DnSkillHandle hSkill = (*iter); if( hSkill) hSkill->Process( localTime, fDelta ); } } int CDnTotalLevelSkillSystem::FindEmptySlot() { int nSlotIndex = -1; std::map::iterator iter = m_ActiveTotalLevelSkillList.begin(); std::map::iterator endIter = m_ActiveTotalLevelSkillList.end(); for (; iter != endIter; ++iter) { if (!iter->second) { int slotIndex = iter->first; bool bSlotActivate = false; std::map::iterator slotActivateIter = m_TotalLevelSkillSlotActivate.find(slotIndex); if (slotActivateIter != m_TotalLevelSkillSlotActivate.end()) { bSlotActivate = slotActivateIter->second; } if (bSlotActivate == false) continue; nSlotIndex = iter->first; break; } } return nSlotIndex; } int CDnTotalLevelSkillSystem::FindEmptyCashSlot(int nSkillID) { int nSelectedSlotIndex = -1; //½ºÅ³ Á¤º¸°¡ Á¤»óÀÌ ¾Æ´Ï¸é °Ç³Ê¶Ü. _TotalLevelSkillInfo* pSkillInfo = GetTotalLevelSkillInfo(nSkillID); if (pSkillInfo == NULL) return nSelectedSlotIndex; std::map::iterator iter = m_TotalLevelSlotInfoList.begin(); std::map::iterator endIter = m_TotalLevelSlotInfoList.end(); for (; iter != endIter; ++iter) { //ij½Ã ½½·Ô¸¸ È®ÀÎ ÇÑ´Ù. if (iter->second.m_isCashSlot == true) { int slotIndex = iter->first; //ij½Ã ½½·ÔÀÌ È°¼ºÈ­ µÇ¾î ÀÖÁö ¾ÊÀ¸¸é °Ç³Ê¶Ü. if (IsActivateSlot(slotIndex) == false) continue; std::map::iterator findSkillIter = m_ActiveTotalLevelSkillList.find(slotIndex); if (findSkillIter != m_ActiveTotalLevelSkillList.end()) { //ÇØ´ç ½½·ÔÀÇ ½ºÅ³ÀÌ ¾øÀ¸¸é ÀÌ ½½·ÔÀ» ¼±Åà ÇÑ´Ù. if (!findSkillIter->second) { nSelectedSlotIndex = slotIndex; break; } else { //°°Àº ½ºÅ³ ŸÀÔ ÀÌ¸é ¼±Åà Çϰí, ´Ù¸¥ ½ºÅ³ ŸÀÔÀÌ¸é ¼±Åà ÇÏÁö ¾Ê´Â´Ù. _TotalLevelSkillInfo* pOldSkillInfo = GetTotalLevelSkillInfo(findSkillIter->second->GetClassID()); if (pOldSkillInfo && pSkillInfo->m_SkillType == pOldSkillInfo->m_SkillType) { nSelectedSlotIndex = slotIndex; break; } } } } } return nSelectedSlotIndex; } int CDnTotalLevelSkillSystem::FindEmptyNormalSlot(int nSkillID) { int nSelectedSlotIndex = -1; //½ºÅ³ Á¤º¸°¡ Á¤»óÀÌ ¾Æ´Ï¸é °Ç³Ê¶Ü. _TotalLevelSkillInfo* pSkillInfo = GetTotalLevelSkillInfo(nSkillID); if (pSkillInfo == NULL) return nSelectedSlotIndex; std::map normalEmptySlotList; //1. °°Àº ½ºÅ³ ŸÀÔÀ» °¡Áø ½½·ÔÀ» ã´Â´Ù. std::map::iterator iter = m_TotalLevelSlotInfoList.begin(); std::map::iterator endIter = m_TotalLevelSlotInfoList.end(); for (; iter != endIter; ++iter) { //ÀÏ¹Ý ½½·Ô¸¸ È®ÀÎ ÇÑ´Ù. if (iter->second.m_isCashSlot == false) { int slotIndex = iter->first; //½½·ÔÀÌ È°¼ºÈ­ µÇ¾î ÀÖÁö ¾ÊÀ¸¸é °Ç³Ê¶Ü. if (IsActivateSlot(slotIndex) == false) continue; std::map::iterator findSkillIter = m_ActiveTotalLevelSkillList.find(slotIndex); if (findSkillIter != m_ActiveTotalLevelSkillList.end()) { //½ºÅ³ÀÌ ÀÖ´Â °æ¿ì if (findSkillIter->second) { //°°Àº ½ºÅ³ ŸÀÔ ÀÌ¸é ¼±Åà Çϰí, ´Ù¸¥ ½ºÅ³ ŸÀÔÀÌ¸é ¼±Åà ÇÏÁö ¾Ê´Â´Ù. int nOldSkillID = findSkillIter->second->GetClassID(); _TotalLevelSkillInfo* pOldSkillInfo = GetTotalLevelSkillInfo(nOldSkillID); if (pOldSkillInfo && pSkillInfo->m_SkillType == pOldSkillInfo->m_SkillType) { if (nSkillID != nOldSkillID) { nSelectedSlotIndex = slotIndex; break; } else { //°°Àº ŸÀÔÀÇ ½ºÅ³ÀÌ ÀÌ¹Ì ÀÖ´Ù¸é.. nSelectedSlotIndex = -2; } } } //½ºÅ³ÀÌ ¾øÀ¸¸é ºó ½½·Ô¿¡ Ãß°¡ ÇØ³õ´Â´Ù. else { normalEmptySlotList.insert(std::make_pair(slotIndex, slotIndex)); } } } } //°°Àº ½ºÅ³ ¾ÆÀ̵𸦠°¡Áø ½½·ÔÀÌ ÀÖ°í, ºó ½½·ÔÀÌ ¾øÀ¸¸é ¿¡·¯ ¸Þ½ÃÁö Ãâ·Â µÇÁö ¾Êµµ·Ï Çϱâ À§ÇØ nSelectedSlotIndex¸¦ -2·Î ¼³Á¤ÇÔ. if (nSelectedSlotIndex == -2 && normalEmptySlotList.empty()) { return nSelectedSlotIndex; } //À§¿¡¼­ °°Àº ŸÀÔÀÇ ½ºÅ³À» ãÁö ¸øÇßÀ¸¸é ºó ½½·ÔÀ» ã´Â´Ù. if (nSelectedSlotIndex == -1) { if (normalEmptySlotList.empty() == false) { std::map::iterator emtpySlotIter = normalEmptySlotList.begin(); if (emtpySlotIter != normalEmptySlotList.end()) nSelectedSlotIndex = emtpySlotIter->first; } } return nSelectedSlotIndex; } int CDnTotalLevelSkillSystem::FindEmptySlot(int nSkillID) { int nSlotIndex = -1; //1. ij½Ã ½½·Ô È®ÀÎ. nSlotIndex = FindEmptyCashSlot(nSkillID); if (nSlotIndex == -1) nSlotIndex = FindEmptyNormalSlot(nSkillID); return nSlotIndex; } CDnTotalLevelSkillSystem::_TotalLevelSkillSlotInfo* CDnTotalLevelSkillSystem::GetSlotInfo(int nSlotIndex) { _TotalLevelSkillSlotInfo* pInfo = NULL; std::map::iterator findIter = m_TotalLevelSlotInfoList.find(nSlotIndex); if (findIter != m_TotalLevelSlotInfoList.end()) pInfo = &(findIter->second); return pInfo; } bool CDnTotalLevelSkillSystem::IsActivateSlot(int nSlotIndex) { std::map::iterator findIter = m_TotalLevelSkillSlotActivate.find(nSlotIndex); if (findIter != m_TotalLevelSkillSlotActivate.end()) return findIter->second; else return false; } #endif // PRE_ADD_TOTAL_LEVEL_SKILL