#include "StdAfx.h" #include "SummonManager.h" #include "SummonedNPCs.h" #include "SkillInfoParser.h" #include "Summoned.h" //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ SummonManager::SummonManager() { m_pSummonNPCsPool = new util::CMemoryPoolFactory; } SummonManager::~SummonManager() { SAFE_DELETE( m_pSummonNPCsPool ); } VOID SummonManager::Release() { m_SummonNPCsList.clear(); if( m_pSummonNPCsPool ) { m_pSummonNPCsPool->Release(); } } VOID SummonManager::Init( DWORD dwMaxPoolSize ) { // (WAVERIX)(REMARK)(¼öÄ¡ Á¶Á¤) // - SummonedNPCs´Â ±×¸® ºÎ´ã°¡´Â ÀÚ·á ±¸Á¶´Â ¾Æ´Ï´Ù <-( ¹°·Ð ´Ù¸¥ °Í¿¡ ºñÇØ¼­... ) // - SUMMON_NPC_LISTÀÇ Çü½ÄÀ» Ç®·ÎºÎÅÍ ¹ÞÀ» Çʿ䰡 ¾øÀ» µí Çѵ¥, ¿ÜºÎ ¸ðµâ¿¡¼­ Æ÷ÀÎÅ͸¦ // »ç¿ëÇϰí ÀÖ´Â °ü°è·Î Á¤È®È÷ È®ÀÎÈÄ ¼öÁ¤ÇÏÀÚ. m_pSummonNPCsPool->Initialize( 100, 100, "SummonedNPCs", AssertionLogger4Pool_Server ); } #ifdef _NA_007667_20141001_WITCHBLADE_SKILL SummonedNPCs* SummonManager::AllocSummonNPCs( Character* pSummoner, BOOL bPlayerSkill, WORD ability_id /*= 0*/ ) #else SummonedNPCs* SummonManager::AllocSummonNPCs( Character* pSummoner, BOOL bPlayerSkill ) #endif //_NA_007667_20141001_WITCHBLADE_SKILL { SummonedNPCs* pSummonedNPCs = FindSummonNPCs( pSummoner->GetObjectKey() ); #ifdef _NA_007667_20141001_WITCHBLADE_SKILL if( pSummonedNPCs ) { // Ç÷¹ÀÌ¾î ¼ÒȯÀÇ °æ¿ì if( bPlayerSkill ) { if (ability_id == eABILITY_SUMMON) { // ÀϹݼÒȯÀÏ °æ¿ì ÀϹݼÒȯµÈ ¼Òȯ¼ö¸¸ Áö¿î´Ù DeleteSummonedUsingType(pSummoner, eSUMMON_NORMAL); } else if (ability_id == eABILITY_SUMMON_IMMOVABLE) { // °íÁ¤Çü¼Òȯ¼öÀϰæ¿ì °íÁ¤Çü ¼Òȯ¼ö¸¸ Áö¿î´Ù DeleteSummonedUsingType(pSummoner, eSUMMON_IMMOVABLE); } else { FreeSummonNPCs(pSummonedNPCs); //xiaomi ´Ë´¦¸ü¸ÄÕÙ»½ÎïÏú»Ù // ÇØ´çÇÏ´Â ±×·ìÀÌ ¾øÀ¸¸é »õ·Î»ý¼º pSummonedNPCs = (SummonedNPCs*)m_pSummonNPCsPool->Alloc(); } } else { // NPCÀÇ °æ¿ì ÀÌÀü ¼ÒȯÁ¤º¸¸¦ ±×´ë·Î ÀÌ¿ëÇÑ´Ù. return pSummonedNPCs; } } else { pSummonedNPCs = (SummonedNPCs*)m_pSummonNPCsPool->Alloc(); } #else if( pSummonedNPCs ) { // Ç÷¹ÀÌ¾î ¼ÒȯÀÇ °æ¿ì if( bPlayerSkill ) { // ÀÌ¹Ì ¼ÒȯÀ» ÇßÀ¸¸é ÀÌÀü ¼Òȯü¸¦ »èÁ¦ÇÑ´Ù. FreeSummonNPCs( pSummonedNPCs ); } else { // NPCÀÇ °æ¿ì ÀÌÀü ¼ÒȯÁ¤º¸¸¦ ±×´ë·Î ÀÌ¿ëÇÑ´Ù. return pSummonedNPCs; } } // ÇØ´çÇÏ´Â ±×·ìÀÌ ¾øÀ¸¸é »õ·Î»ý¼º pSummonedNPCs = (SummonedNPCs*)m_pSummonNPCsPool->Alloc(); #endif //_NA_007667_20141001_WITCHBLADE_SKILL if( !pSummonedNPCs ) { SUNLOG( eCRITICAL_LOG, "[SummonManager::AllocSummonNPCs] Can't Allocate SummonedNPCs " ); return NULL; } // SummonedNPCs ÃʱâÈ­ if(pSummoner->IsEqualObjectKind(PLAYER_OBJECT)) { pSummonedNPCs->Init( pSummoner, eSUMMON_COMMAND_DELEGATE_ATTACK_IGNORE_PLAYER ); } else { pSummonedNPCs->Init( pSummoner, eSUMMON_COMMAND_DELEGATE_ATTACK ); } // SummonManager¿¡ µî·Ï m_SummonNPCsList.insert( std::make_pair( pSummoner->GetObjectKey(), pSummonedNPCs ) ); #ifdef WAVERIX_CODE_DELETE_RESERVED m_SummonHash.insert( pSummonedNPCs ); #endif return pSummonedNPCs; } BOOL SummonManager::FreeSummonNPCs( SummonedNPCs *pSummonNPCs, BOOL bFollowerDestroy ) { if( NULL == FindSummonNPCs( pSummonNPCs->GetSummonerKey() ) ) { SUNLOG( eCRITICAL_LOG, "[SummonManager::FreeSummonNPCs] Can't Remove SummonNPCs " ); return FALSE; } m_SummonNPCsList.erase( pSummonNPCs->GetSummonerKey() ); #ifdef WAVERIX_CODE_DELETE_RESERVED SUMMON_HASH::iterator it = m_SummonHash.find(pSummonNPCs); if( it == m_SummonHash.end() ) { SUNLOG( eCRITICAL_LOG, "[SusunLove] FreeSummonNPCs Free Same Memory Pool! SummonerKey[%d]", pSummonNPCs->GetSummonerKey() ); return FALSE; } else { m_SummonHash.erase(it); } #endif pSummonNPCs->Release( bFollowerDestroy ); m_pSummonNPCsPool->Free( pSummonNPCs ); return TRUE; } VOID SummonManager::LoopNode::_AddSummonedSkill( SUMMONED_MAP_PAIR rPair ) { NPC* pNPC = rPair.second; if(pNPC->IsEqualObjectKind(SUMMON_OBJECT) == 0) return; Summoned* pSummoned = (Summoned*)pNPC; pSummoned->AddSkill( SKILL_CODE.Get() ); } VOID SummonManager::AddSummonedSkill( DWORD dwSummonKey, SLOTCODE scSkillCode ) { SummonedNPCs* pSummonedNPCs = FindSummonNPCs( dwSummonKey ); if( !pSummonedNPCs ) return; SkillScriptInfo* pBaseCurSkillInfo = SkillInfoParser::Instance()->GetSkillInfo( scSkillCode ); if( pBaseCurSkillInfo->m_bySkillUserType != eSKILL_USER_SUMMONED ) return; LoopNode loopNode; loopNode.SKILL_CODE.Set( scSkillCode ); pSummonedNPCs->ForeachSummonedList( &SummonManager::LoopNode::_AddSummonedSkill, &loopNode ); } VOID SummonManager::LoopNode::_DelSummonedSkill( SUMMONED_MAP_PAIR rPair ) { NPC* pNPC = rPair.second; if(pNPC->IsEqualObjectKind(SUMMON_OBJECT) == 0) return; Summoned *pSummoned = (Summoned*)pNPC; pSummoned->DelSkill( SKILL_CODE.Get() ); } VOID SummonManager::DelSummonedSkill( DWORD dwSummonKey, SLOTCODE scSkillCode ) { SummonedNPCs *pSummonedNPCs = FindSummonNPCs( dwSummonKey ); if( !pSummonedNPCs ) return; SkillScriptInfo *pBaseCurSkillInfo = SkillInfoParser::Instance()->GetSkillInfo( scSkillCode ); if( pBaseCurSkillInfo->m_bySkillUserType != eSKILL_USER_SUMMONED ) return; LoopNode loopNode; loopNode.SKILL_CODE.Set( scSkillCode ); pSummonedNPCs->ForeachSummonedList( &SummonManager::LoopNode::_DelSummonedSkill, &loopNode ); } // ÇöÀç´Â ¼Òȯü°¡ 1¸¶¸®¶ó¼­ ¿ÀºêÁ§Æ®Å°·Î ±¸ºÐÀÌ ÇÊ¿ä¾øÁö¸¸ // ³ªÁßÀ» À§ÇØ Å¬¶ó·ÎºÎÅÍ ¸í·ÉÀ» ³»¸± ¼Òȯü ¿ÀºêÁ§Æ®Å°¸¦ ¹Þ¾Æ¾ß ÇÑ´Ù! RC::eSUMMON_RESULT SummonManager::SetCommandState( DWORD dwSummonKey, eSUMMON_COMMAND eCommand, DWORD dwObjectKey, DWORD dwTargetKey ) { SummonedNPCs *pSummonedNPCs = FindSummonNPCs( dwSummonKey ); if( !pSummonedNPCs ) return RC::RC_SUMMON_SUMMONED_NPC_NOTEXIST; switch(eCommand) { case eSUMMON_COMMAND_DESTROY: { //!~ _NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL if (dwTargetKey) pSummonedNPCs->Destroy( dwTargetKey ); else pSummonedNPCs->Destroy( dwObjectKey ); //~! _NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL } break; default: return pSummonedNPCs->SetCommandState( eCommand, dwObjectKey, dwTargetKey ); // »óŸ¦ ¹Ù²Ù¾îÁØ´Ù. } return RC::RC_SUMMON_SUCCESS; } VOID SummonManager::LoopNode::_LeaveSummonNPCs( SUMMONED_MAP_PAIR rPair ) { NPC* pNPC = rPair.second; pNPC->SetSummonerKey( 0 ); } VOID SummonManager::LeaveSummonNPCs( Character *pLeaveChar ) { #ifdef _NA_000000_20140224_SUMMONER_REFACTORING SummonedNPCs *pSummonedNPCs = FindSummonNPCs( pLeaveChar->GetObjectKey() ); if (pSummonedNPCs) { if(pLeaveChar->IsEqualObjectKind(PLAYER_OBJECT)) { // Ç÷¹À̾ ¶°³¯°æ¿ì ¼ÒȯÁ¤º¸¸¦ ¹«Á¶°Ç ÇØÁ¦ÇÑ´Ù. FreeSummonNPCs( pSummonedNPCs ); } else { // ¼ÒȯÀ» ½ÃŲ ÁÖüÀÎ °æ¿ì ¼ÒȯNPCµéÀÇ °øÀ¯¼ÒȯŰ(m_dwSummonerKey)¸¦ NULL·Î ÃʱâÈ­ÇÑ´Ù. // NPC°¡ ¼ÒȯÇÑ ºÎÇÏ(¼Òȯü)µéÀº »èÁ¦ÇÏÁö ¾Ê¾Æ¾ßÇÑ´Ù. LoopNode loopNode; pSummonedNPCs->ForeachSummonedList( &SummonManager::LoopNode::_LeaveSummonNPCs, &loopNode ); FreeSummonNPCs( pSummonedNPCs, FALSE ); } } else { // ¼ÒȯÀ» ´çÇÑ NPCÀÎ °æ¿ì ¼ÒȯÁ¤º¸¿¡¼­ Á¦°ÅÇÑ´Ù. pSummonedNPCs = FindSummonNPCs( pLeaveChar->GetSummonerKey() ); if (pSummonedNPCs) { DWORD dwObjectKey = pLeaveChar->GetObjectKey(); NPC* pLeaveNPC = static_cast(pLeaveChar); pSummonedNPCs->DecreaseSummoned( pLeaveNPC->GetBaseInfo()->m_MonsterCode, dwObjectKey ); // ¼Òȯ¸®½ºÆ®ÀÇ ¸â¹ö¼ö°¡ 0À̸é Ç®¿¡ ¹ÝȯÇÑ´Ù. if (pSummonedNPCs->GetNumberOfNPCs() == 0) { FreeSummonNPCs( pSummonedNPCs ); } } pLeaveChar->SetSummonerKey(0); } #else SummonedNPCs *pSummonedNPCs = FindSummonNPCs( pLeaveChar->GetObjectKey() ); if( !pSummonedNPCs ) return; // Ç÷¹À̾ ¶°³¯°æ¿ì ¼ÒȯÁ¤º¸¸¦ ¹«Á¶°Ç ÇØÁ¦ÇÑ´Ù. if(pLeaveChar->IsEqualObjectKind(PLAYER_OBJECT)) { FreeSummonNPCs( pSummonedNPCs ); } else { DWORD dwObjectKey = pLeaveChar->GetObjectKey(); NPC* pLeaveNPC = (NPC*)pLeaveChar; // ¼ÒȯÀ» ½ÃŲ ÁÖüÀÎ °æ¿ì ¼ÒȯNPCµéÀÇ °øÀ¯¼ÒȯŰ(m_dwSummonerKey)¸¦ NULL·Î ÃʱâÈ­ÇÑ´Ù. // NPC°¡ ¼ÒȯÇÑ ºÎÇÏ(¼Òȯü)µéÀº »èÁ¦ÇÏÁö ¾Ê¾Æ¾ßÇÑ´Ù. if( pSummonedNPCs->IsSummoner( dwObjectKey ) ) { LoopNode loopNode; pSummonedNPCs->ForeachSummonedList( &SummonManager::LoopNode::_LeaveSummonNPCs, &loopNode ); FreeSummonNPCs( pSummonedNPCs, FALSE ); } // ¼ÒȯÀ» ´çÇÑ NPCÀÎ °æ¿ì ¼ÒȯÁ¤º¸¿¡¼­ Á¦°ÅÇÑ´Ù. else { pSummonedNPCs->DecreaseSummoned( pLeaveNPC->GetBaseInfo()->m_MonsterCode, dwObjectKey ); // ¼Òȯ¸®½ºÆ®ÀÇ ¸â¹ö¼ö°¡ 0À̸é Ç®¿¡ ¹ÝȯÇÑ´Ù. if( !pSummonedNPCs->GetNumberOfNPCs() ) { FreeSummonNPCs( pSummonedNPCs ); } } } pLeaveChar->SetSummonerKey(0); #endif //_NA_000000_20140224_SUMMONER_REFACTORING } #ifdef _NA_007667_20141001_WITCHBLADE_SKILL bool SummonManager::DeleteSummonedUsingType( Character* pSummoner, eSUMMON_TYPE type ) { SummonedNPCs* pSummonedNPCs = FindSummonNPCs( pSummoner->GetObjectKey() ); if (pSummonedNPCs == NULL) { return false; } Summoned* summoned = pSummonedNPCs->FindSummonedUsingType(type); if (summoned == NULL) { //¾îÂîµÇ¾úµç ¾ø´Â»óÅ·Π¸¸µé¾î¾ß ÇÏ´Ï.. return true; } pSummonedNPCs->Destroy(summoned->GetObjectKey()); } #endif //_NA_007667_20141001_WITCHBLADE_SKILL