#include "gamesrv.h" #include "stdafx.h" #include "SkillManager.h" #include "ObjectManager.h" #include "BasicString.h" #include "Skill_Common.h" #include "Npc_Common.h" #include "GameFile.h" #include "BaseObject.h" #include "Protocol.h" #include "Player.h" #include "Monster.h" #include "Totem.h" #include "StatusCalc_Server.h" #include "SkillScript.h" #include "CommunityScript.h" #include "MakeSkillScript.h" #include "RangeCheck.h" #include "AppTimer.h" #include "InfluenceObject.h" #include "DuelManager.h" #include "StatusCalc_Server.h" #include "AIManager.h" #include "DamageCalc.h" #include "Party.h" #include "PartyManager.h" #include "ModeInfo.h" #include "PartyUnionManager.h" #include "PartyUnion.h" #include "RandomTable.h" #include "GridManager.h" #include "StageScript.h" #include "TutorialSkillScript.h" cSkillManager* cSkillManager::mpSkillManager = NULL; cSkillManager::cSkillManager() { if(mpSkillManager) { MessageBox(NULL,"cSkillManager : ÀÌ Å¬·¡½º´Â °´Ã¼°¡ À¯ÀÏÇѰ´Ã¼(singleton)À̾î¾ß ÇÕ´Ï´Ù.\ ÀÌÀü °´Ã¼¸¦ »ç¿ëÇÏ´øÁö ÀÌÀü °´Ã¼¸¦ Áö¿ì°í »ý¼ºÇϽʽÿÀ.","°æ°í",MB_OK); } else { mpSkillManager = this; } mpMakeSkillScript = 0; mpCommuScript = 0; mpSkillScript = 0; } cSkillManager::~cSkillManager() { ReleasePlayerHaveSkill(); ReleaseInfluence(); Release(); } bool cSkillManager::Init() { mPlayerSkillObjectPool.Reserve(1000,100); mMonsterSkillObjectPool.Reserve(2000,100); mPlayerMonSkillObjectPool.Reserve(1000,100); mInfluenceObjectPool.Reserve(5000,100); mPlayerHaveSkillPool.Reserve(40000,100); mpSkillScript = new cSkillScript; if( !mpSkillScript->Init() ) { return false; } mpCommuScript = new cCommunityScript; if( !mpCommuScript->Init() ) { return false; } if( !mDramaturgyManager.Init() ) { return false; } mpMakeSkillScript = new cMakeSkillScript; if( !mpMakeSkillScript->Init() ) { return false; } return true; } void cSkillManager::Release() { SAFE_DELETE( mpMakeSkillScript ); SAFE_DELETE( mpCommuScript ); SAFE_RELEASE_DELETE( mpSkillScript ); cPointerHashMap::cIterator iter; cBaseSkillObject* pPlayerSkillObj = NULL; cMonsterSkillObject* pMonsterSkillObj = NULL; cArray* pSkillArray = NULL; for(iter = mPlayerSkillMap.Begin(); iter != mPlayerSkillMap.End(); ++iter) { pSkillArray = (cArray*)(*iter).mSecond; if( pSkillArray == NULL ) continue; for( unsigned int i = 0 ; pSkillArray->GetSize() > i ; ++i ) { pPlayerSkillObj = (cBaseSkillObject*)(*pSkillArray)[i]; SAFE_DELETE( pPlayerSkillObj ); } pSkillArray->Clear(); SAFE_DELETE( pSkillArray ); } mPlayerSkillMap.Clear(); for(iter = mMonsterSkillMap.Begin(); iter != mMonsterSkillMap.End(); ++iter) { pSkillArray = (cArray*)(*iter).mSecond; if( pSkillArray == NULL ) continue; for( unsigned int i = 0 ; pSkillArray->GetSize() > i ; ++i ) { pMonsterSkillObj = (cMonsterSkillObject*)(*pSkillArray)[i]; SAFE_DELETE( pMonsterSkillObj ); } pSkillArray->Clear(); SAFE_DELETE( pSkillArray ); } mMonsterSkillMap.Clear(); } void cSkillManager::Process( unsigned long elapsedTime, unsigned long accumTime ) { cBaseSkillObject* pPlayerSkillObj = NULL; cMonsterSkillObject* pMonsterSkillObj = NULL; cInfluenceObject* pInfluenceObject = NULL; cPointerHashMap::cIterator begin; cPointerHashMap::cIterator end; try { /// Ç÷¹ÀÌ¾î ¾×Æ¼ºê ½ºÅ³ ÇÁ·Î¼¼½º end = mPlayerSkillMap.End(); for( begin = mPlayerSkillMap.Begin() ; begin != end; ++begin ) { cArray* pSkillArray = (cArray*)(*begin).mSecond; if( pSkillArray != NULL ) { unsigned int arraySize = pSkillArray->GetSize(); for( unsigned int i = arraySize ; i > 0 ; --i ) { pPlayerSkillObj = (cBaseSkillObject*)(*pSkillArray)[i-1]; if( pPlayerSkillObj != NULL ) pPlayerSkillObj->Process( elapsedTime, accumTime ); else { NETWORK2->PostServerEvent( "cSkillManager::Process() pPlayerSkillObj == NULL" ); pSkillArray->PopAt( i-1 ); } } } else if ( end != mPlayerSkillMap.End( ) ) { NETWORK2->PostServerEvent( "In if ( end != mPlayerSkillMap.End( ) ) { ... }. Throwing 'cSkillManager::Process' exception." ); } else assert(NULL); } } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mPlayerSkillMap ) { (0x%x)->Process( %u, %u ); }. Throwing 'cSkillManager::Process' exception.", pPlayerSkillObj, elapsedTime, accumTime ); throw; } try { /// ¸ó½ºÅÍ ¾×Ƽºê ½ºÅ³ ÇÁ·Î¼¼½º end = mMonsterSkillMap.End(); for( begin = mMonsterSkillMap.Begin() ; begin != end; ++begin ) { cArray* pSkillArray = (cArray*)(*begin).mSecond; if( pSkillArray != NULL ) { unsigned int arraySize = pSkillArray->GetSize( ); for( unsigned int i = arraySize ; i > 0 ; --i ) { pMonsterSkillObj = (cMonsterSkillObject*)(*pSkillArray)[i-1]; if( pMonsterSkillObj != NULL ) pMonsterSkillObj->Process( elapsedTime, accumTime ); else { NETWORK2->PostServerEvent("cSkillManager::Process() pMonsterSkillObj == NULL"); pSkillArray->PopAt( i-1 ); } } } else if ( end != mMonsterSkillMap.End( ) ) { NETWORK2->PostServerEvent( "In if ( end != mMonsterSkillMap.End( ) ) { ... }. Throwing 'cSkillManager::Process' exception." ); } else assert(NULL); } } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mMonsterSkillMap ) { (0x%x)->Process( %u, %u ) }. Throwing 'cSkillManager::Process' exception.", pMonsterSkillObj, elapsedTime, accumTime ); throw; } try { /// È¿°ú ¸®½ºÆ® ÇÁ·Î¼¼½º end = mInfluenceMap.End(); for( begin = mInfluenceMap.Begin() ; begin != end; ++begin ) { pInfluenceObject = (cInfluenceObject*)((*begin).mSecond); if( pInfluenceObject != NULL ) { if( pInfluenceObject->Process( elapsedTime, accumTime ) == false ) mDeleteInfluenceAry.PushBack( pInfluenceObject->GetUniqueIdx() ); } else if ( end != mInfluenceMap.End( ) ) NETWORK2->PostServerEvent( "In if ( end != mInfluenceMap.End( ) ) { ... }. Throwing 'cSkillManager::Process' exception." ); else assert(NULL); } } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mInfluenceMap ) { (0x%x)->Process( %u, %u ) }. Throwing 'cSkillManager::Process' exception.", pInfluenceObject, elapsedTime, accumTime ); throw; } try { /// Ç÷¹À̾î hp/mp º¯µ¿ ¸Þ¼¼Áö ¹ß¼Û cHashSet::cIterator b = mPlayerChangeSet.Begin(); cHashSet::cIterator e = mPlayerChangeSet.End(); for( ; b != e ; ++b ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( *b ); if( pPlayer != NULL ) { if( pPlayer->GetStateDie() == true ) { MSG_SYN_SKILL_APPLY_DIE sync; sync.Category = NM_SKILL; sync.Protocol = NM_SKILL_DAMAGE_APPLY_DIE_SYN; sync.mAttacker = pPlayer->GetSkillLastAttack(); sync.mDamageKind = pPlayer->GetSkillLastKind(); sync.mTarget = pPlayer->GetObject(); NETWORK2->QuickSend( pPlayer, (char*)&sync, sizeof(sync) ); } else { MSG_SYN_SKILL_APPLY_HPMP sync; sync.Category = NM_SKILL; sync.Protocol = NM_SKILL_DAMAGE_APPLY_HPMP_SYN; sync.mTarget = pPlayer->GetObject(); sync.mHP = pPlayer->GetHP(); sync.mMaxHP = pPlayer->GetMaxHP(); sync.mMP = pPlayer->GetMP(); sync.mMaxMP = pPlayer->GetMaxMP(); NETWORK2->QuickSend( pPlayer, (char*)&sync, sizeof(sync) ); } } } mPlayerChangeSet.Clear(); } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mDeleteSkillAry ) { ... }. Throwing 'cSkillManager::Process' exception." ); throw; } try { /// ¸ó½ºÅÍ hp/mp º¯µ¿ ¸Þ¼¼Áö ¹ß¼Û cHashSet::cIterator b = mMonsterChangeSet.Begin(); cHashSet::cIterator e = mMonsterChangeSet.End(); for( ; b != e ; ++b ) { cMonster* pMonster = OBJECTMANAGER->GetMonster( *b ); if( pMonster != NULL ) { if( pMonster->GetStateDie() == true ) { MSG_SYN_SKILL_APPLY_DIE sync; sync.Category = NM_SKILL; sync.Protocol = NM_SKILL_DAMAGE_APPLY_DIE_SYN; sync.mAttacker = pMonster->GetSkillLastAttack(); sync.mDamageKind = pMonster->GetSkillLastKind(); sync.mTarget = pMonster->GetObject(); NETWORK2->QuickSend( pMonster, (char*)&sync, sizeof(sync) ); } else { MSG_SYN_SKILL_APPLY_HPMP sync; sync.Category = NM_SKILL; sync.Protocol = NM_SKILL_DAMAGE_APPLY_HPMP_SYN; sync.mTarget = pMonster->GetObject(); sync.mHP = pMonster->GetHP(); sync.mMaxHP = pMonster->GetMaxHP(); sync.mMP = pMonster->GetMP(); sync.mMaxMP = pMonster->GetMaxMP(); NETWORK2->QuickSend( pMonster, (char*)&sync, sizeof(sync) ); } } } mMonsterChangeSet.Clear(); } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mDeleteSkillAry ) { ... }. Throwing 'cSkillManager::Process' exception." ); throw; } try { /// Ç÷¹À̾î, ¸ó½ºÅÍ ¾×Ƽºê ½ºÅ³ »èÁ¦ unsigned int DelSkillArySize = mDeleteSkillAry.GetSize( ); sDelSkillInfo* info; for( unsigned int i = 0 ; i < DelSkillArySize ; ++i ) { info = &mDeleteSkillAry[i]; if( info != NULL ) { if( DeleteSkillObject( info->skillUser.type, info->skillUser.index, info->mSkillIdx ) == false ) NETWORK2->PostServerEvent( "cSkillManager::Process DeleteSkillObject[%d,%d,%d]", info->skillUser.type, info->skillUser.index, info->mSkillIdx ); } } mDeleteSkillAry.Clear(); } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mDeleteSkillAry ) { ... }. Throwing 'cSkillManager::Process' exception." ); throw; } try { /// È¿°ú »èÁ¦ ¸ñ·Ï ó¸® unsigned int mDelSize = mDeleteInfluenceAry.GetSize( ); for( unsigned int i = 0; i < mDelSize; ++i ) { unsigned long uniqueIdx = mDeleteInfluenceAry[i]; cInfluenceObject* pInf = GetInfluence( uniqueIdx ); if( pInf != NULL ) DeleteInfluence( pInf->GetTarget(), uniqueIdx ); } mDeleteInfluenceAry.Clear(); } catch ( ... ) { NETWORK2->PostServerEvent( "In for( mDeleteInfluenceAry ) { ... }. Throwing 'cSkillManager::Process' exception." ); throw; } } bool cSkillManager::IsUsingSkill( unsigned char type, unsigned long objectIdx ) { switch( type ) { case eOBJECTTYPE_MONSTER: { cArray* pSkillArray = (cArray*)mMonsterSkillMap.GetAt( objectIdx ); if( pSkillArray == NULL ) { return false; } cMonsterSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cMonsterSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) continue; /// µ¥¹ÌÁö Àû¿ë±îÁö °¡±âÀü ´Ü°èÀÌ¸é ½ºÅ³ »ç¿ë Áß if( pSkillObject->GetSkillState() < eSKILLPROCESS_PROJECTILE ) return true; } } break; case eOBJECTTYPE_HERO: case eOBJECTTYPE_PLAYER: { cArray* pSkillArray = (cArray*)mPlayerSkillMap.GetAt( objectIdx ); if( pSkillArray == NULL ) { return false; } cBaseSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cBaseSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) continue; if( pSkillObject->IsProjectile() == false ) { /// µ¥¹ÌÁö Àû¿ë±îÁö °¡±âÀü ´Ü°èÀÌ¸é ½ºÅ³ »ç¿ë Áß if( pSkillObject->GetSkillState() < eSKILLPROCESS_HP || pSkillObject->IsDetailEnd() == false ) return true; } else { /// µ¥¹ÌÁö Àû¿ë±îÁö °¡±âÀü ´Ü°èÀÌ¸é ½ºÅ³ »ç¿ë Áß if( pSkillObject->GetSkillState() < eSKILLPROCESS_PROJECTILE ) return true; } } } break; default: assert(NULL); NETWORK2->PostServerEvent("IsUsingSkill type error[%d]", type ); return false; } return false; } unsigned long cSkillManager::SkillLeftEndTime( unsigned char type, unsigned long objectIdx ) { switch( type ) { case eOBJECTTYPE_MONSTER: { cArray* pSkillArray = (cArray*)mMonsterSkillMap.GetAt( objectIdx ); if( pSkillArray == NULL ) { return 0; } cMonsterSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cMonsterSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) continue; /// µ¥¹ÌÁö Àû¿ë±îÁö °¡±âÀü ´Ü°èÀÌ¸é ½ºÅ³ »ç¿ë Áß if( pSkillObject->GetSkillState() < eSKILLPROCESS_PROJECTILE ) return pSkillObject->SkillEndTime(); } } break; case eOBJECTTYPE_HERO: case eOBJECTTYPE_PLAYER: { cArray* pSkillArray = (cArray*)mPlayerSkillMap.GetAt( objectIdx ); if( pSkillArray == NULL ) { return 0; } cBaseSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cBaseSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) continue; if( pSkillObject->IsProjectile() == false ) { /// µ¥¹ÌÁö Àû¿ë±îÁö °¡±âÀü ´Ü°èÀÌ¸é ½ºÅ³ »ç¿ë Áß if( pSkillObject->GetSkillState() < eSKILLPROCESS_HP || pSkillObject->IsDetailEnd() == false ) return pSkillObject->SkillEndTime(); } else { /// µ¥¹ÌÁö Àû¿ë±îÁö °¡±âÀü ´Ü°èÀÌ¸é ½ºÅ³ »ç¿ë Áß if( pSkillObject->GetSkillState() < eSKILLPROCESS_PROJECTILE ) return pSkillObject->SkillEndTime(); } } } break; default: assert(NULL); NETWORK2->PostServerEvent("IsUsingSkill type error[%d]", type ); return 0; } return 0; } void cSkillManager::CastSkillCancel( sObject attacker, bool isObstacle, unsigned long attributeType ) { if( attacker.type == eOBJECTTYPE_PLAYER || attacker.type == eOBJECTTYPE_HERO ) { cPlayer* pAttacker = OBJECTMANAGER->GetPlayer(attacker.index); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::CastSkillCancel - attacker[%d,%d]", attacker.type, attacker.index ); return; } unsigned long skillIndex = 0; cArray* pSkillArray = (cArray*)mPlayerSkillMap.GetAt( attacker.index ); if( pSkillArray != NULL ) { bool isCasting = false; cBaseSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cBaseSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("CastSkillCancel - mPlayerSkillMap.GetAt( %d )", attacker.index ); continue; } if( pSkillObject->GetSkillState() == eSKILLPROCESS_CASTING || pSkillObject->IsChanneling() ) { if( attributeType != eATTRIBUTETYPE_NONE && pSkillObject->GetAttributeType() != (eATTRIBUTETYPE)attributeType ) break; skillIndex = pSkillObject->GetUniqueIdx(); /// ij½ºÆÃ Ãë¼Òó¸® DeleteSkillObject( attacker.type, attacker.index, skillIndex ); if( pAttacker->ChangeState( eOBJECT_STATE_IDLE ) == false ) { if( pAttacker->GetStateDie() == false ) { NETWORK2->PostServerEvent("cSkillManager::CastSkillCancel pAttacker[%d,%d,%d,%d]->ChangeState( eOBJECT_STATE_IDLE ) == false", attacker.index, pAttacker->GetState(), pAttacker->GetStateStop(), pAttacker->GetRequestRejection() ); } } isCasting = true; break; } } /// ¾î¶² ½ºÅ³µµ ij½ºÆÃ ÁßÀ̾ƴϸé Ãë¼Ò¼º°ø ¸Þ¼¼Áö¸¦ º¸³»Áö ¾Ê´Â´Ù. if( isCasting == false ) return; } if( isObstacle == false ) /// À¯Àú°¡ Á÷Á¢ ij½ºÆÃÀ» ²ö°æ¿ì { /// ij½ºÆÃ Ãë¼Ò ÀÀ´ä ¸Þ¼¼Áö´Â Ãë¼Ò ¼º°ø½Ã¿¡¸¸ ¹ß¼ÛµÈ´Ù. HANDLE handle = NULL; MSG_RES_SKILL_CAST_CANCEL* pResMsg = (MSG_RES_SKILL_CAST_CANCEL*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_CAST_CANCEL_RES ); if ( pResMsg != NULL ) { pResMsg->mSkillIndex = skillIndex; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_CAST_CANCEL) ); } MSG_SYN_SKILL_CAST_CANCEL pSynMsg; pSynMsg.Category = NM_SKILL; pSynMsg.Protocol = NM_SKILL_CAST_CANCEL_SYN; pSynMsg.mSkillIndex = skillIndex; NETWORK2->QuickSendExcept( pAttacker, (char*)&pSynMsg, sizeof(pSynMsg) ); } else /// »óÅÂÀÌ»ó È¿°ú·Î ÀÎÇÑ Ä³½ºÆÃÀ» ÁßÁö´çÇÑ °æ¿ì { /// ij½ºÆÃ ¹ßµ¿ ½ÇÆÐ ¸Þ¼¼Áö Àü¼Û MSG_SYN_SKILL_CAST_ACTIVITY_FAIL failMsg; failMsg.Category = NM_SKILL; failMsg.Protocol = NM_SKILL_CAST_ACTIVITY_FAIL_SYN; failMsg.mAttacker = attacker; failMsg.mSkillIndex = skillIndex; failMsg.mFailCode = FAIL_SKILL_CASTING_DONT_OBSTACLE; NETWORK2->QuickSend( pAttacker, (char*)&failMsg, sizeof(failMsg) ); } } else if( attacker.type == eOBJECTTYPE_MONSTER ) { cMonster* pAttacker = OBJECTMANAGER->GetMonster(attacker.index); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::CastSkillCancel - attacker[%d,%d]", attacker.type, attacker.index ); return; } unsigned long skillIndex = 0; cArray* pSkillArray = (cArray*)mMonsterSkillMap.GetAt( attacker.index ); if( pSkillArray != NULL ) { cBaseSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cBaseSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) { NETWORK2->PostServerEvent("CastSkillCancel - mMonsterSkillMap.GetAt( %d )", attacker.index ); continue; } if( pSkillObject->GetSkillState() == eSKILLPROCESS_CASTING ) { if( attributeType != eATTRIBUTETYPE_NONE && pSkillObject->GetAttributeType() != (eATTRIBUTETYPE)attributeType ) break; skillIndex = pSkillObject->GetUniqueIdx(); /// ij½ºÆÃ Ãë¼Òó¸® DeleteSkillObject( attacker.type, attacker.index, skillIndex ); pAttacker->CalcSkillWaitTime( NETWORK2->GetAccumTime() ); /// ij½ºÆÃ ¹ßµ¿ ½ÇÆÐ ¸Þ¼¼Áö Àü¼Û MSG_SYN_SKILL_CAST_ACTIVITY_FAIL failMsg; failMsg.Category = NM_SKILL; failMsg.Protocol = NM_SKILL_CAST_ACTIVITY_FAIL_SYN; failMsg.mAttacker = attacker; failMsg.mSkillIndex = skillIndex; failMsg.mFailCode = FAIL_SKILL_CASTING_DONT_OBSTACLE; NETWORK2->QuickSend( pAttacker, (char*)&failMsg, sizeof(failMsg) ); return; } } } } } void cSkillManager::ChannelingSkillCancel( sObject attacker, bool isObstacle, unsigned long attributeType, bool isDuelEndCancel ) { if( attacker.type == eOBJECTTYPE_PLAYER || attacker.type == eOBJECTTYPE_HERO ) { cPlayer* pAttacker = OBJECTMANAGER->GetPlayer(attacker.index); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::ChannelingSkillCancel - attacker[%d,%d]", attacker.type, attacker.index ); return; } unsigned long skillIndex = 0; bool isActivity = false; cArray* pSkillArray = (cArray*)mPlayerSkillMap.GetAt( attacker.index ); if( pSkillArray != NULL ) { cBaseSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cBaseSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("ChannelingSkillCancel - mPlayerSkillMap.GetAt( %d )", attacker.index ); continue; } if( pSkillObject->GetSkillState() == eSKILLPROCESS_ACTIVITY && pSkillObject->IsChanneling() == true ) { if( attributeType != eATTRIBUTETYPE_NONE && pSkillObject->GetAttributeType() != (eATTRIBUTETYPE)attributeType ) break; skillIndex = pSkillObject->GetUniqueIdx(); /// ij½ºÆÃ Ãë¼Òó¸® DeleteSkillObject( attacker.type, attacker.index, skillIndex ); if( pAttacker->ChangeState( eOBJECT_STATE_IDLE ) == false ) { if( pAttacker->GetStateDie() == false ) { NETWORK2->PostServerEvent("cSkillManager::ChannelingSkillCancel pAttacker[%d,%d,%d,%d]->ChangeState( eOBJECT_STATE_IDLE ) == false", attacker.index, pAttacker->GetState(), pAttacker->GetStateStop(), pAttacker->GetRequestRejection() ); } } isActivity = true; break; } } } /// ¾î¶² ½ºÅ³µµ ij½ºÆÃ ÁßÀ̾ƴϸé Ãë¼Ò¼º°ø ¸Þ¼¼Áö¸¦ º¸³»Áö ¾Ê´Â´Ù. if( isActivity == false ) return; if( isObstacle == false ) /// À¯Àú°¡ Á÷Á¢ ij½ºÆÃÀ» ²ö°æ¿ì { /// ij½ºÆÃ Ãë¼Ò ÀÀ´ä ¸Þ¼¼Áö´Â Ãë¼Ò ¼º°ø½Ã¿¡¸¸ ¹ß¼ÛµÈ´Ù. HANDLE handle = NULL; MSG_RES_CHANNELING_SKILL_CANCEL* pResMsg = (MSG_RES_CHANNELING_SKILL_CANCEL*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_CHANNELING_CANCEL_RES ); if ( pResMsg != NULL ) { pResMsg->mUniqueSkillIndex = skillIndex; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_CHANNELING_SKILL_CANCEL) ); } MSG_SYN_CHANNELING_SKILL_CANCEL pSynMsg; pSynMsg.Category = NM_SKILL; pSynMsg.Protocol = NM_SKILL_CHANNELING_CANCEL_SYN; pSynMsg.mUniqueSkillIndex = skillIndex; NETWORK2->QuickSendExcept( pAttacker, (char*)&pSynMsg, sizeof(pSynMsg) ); } else /// »óÅÂÀÌ»ó È¿°ú·Î ÀÎÇÑ Ä³½ºÆÃÀ» ÁßÁö´çÇÑ °æ¿ì { /// ij½ºÆÃ ¹ßµ¿ ½ÇÆÐ ¸Þ¼¼Áö Àü¼Û MSG_SYN_SKILL_CAST_ACTIVITY_FAIL failMsg; failMsg.Category = NM_SKILL; failMsg.Protocol = NM_SKILL_CAST_ACTIVITY_FAIL_SYN; failMsg.mAttacker = attacker; failMsg.mSkillIndex = skillIndex; failMsg.mFailCode = FAIL_SKILL_CASTING_DONT_OBSTACLE; if( isDuelEndCancel ) failMsg.mFailCode = FAIL_SKILL_CASTING_DONT_DUEL_END; NETWORK2->QuickSend( pAttacker, (char*)&failMsg, sizeof(failMsg) ); } } else if( attacker.type == eOBJECTTYPE_MONSTER ) { cMonster* pAttacker = OBJECTMANAGER->GetMonster(attacker.index); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::ChannelingSkillCancel - attacker[%d,%d]", attacker.type, attacker.index ); return; } unsigned long skillIndex = 0; cArray* pSkillArray = (cArray*)mMonsterSkillMap.GetAt( attacker.index ); if( pSkillArray != NULL ) { cBaseSkillObject* pSkillObject = NULL; for( unsigned int i = 0 ; i < pSkillArray->GetSize() ; ++i ) { pSkillObject = (cBaseSkillObject*)(*pSkillArray)[i]; if( pSkillObject == NULL ) { NETWORK2->PostServerEvent("ChannelingSkillCancel - mMonsterSkillMap.GetAt( %d )", attacker.index ); continue; } if( attributeType != eATTRIBUTETYPE_NONE && pSkillObject->GetAttributeType() != (eATTRIBUTETYPE)attributeType ) break; skillIndex = pSkillObject->GetUniqueIdx(); /// ij½ºÆÃ Ãë¼Òó¸® DeleteSkillObject( attacker.type, attacker.index, skillIndex ); pAttacker->CalcSkillWaitTime( NETWORK2->GetAccumTime() ); /// ij½ºÆÃ ¹ßµ¿ ½ÇÆÐ ¸Þ¼¼Áö Àü¼Û MSG_SYN_SKILL_CAST_ACTIVITY_FAIL failMsg; failMsg.Category = NM_SKILL; failMsg.Protocol = NM_SKILL_CAST_ACTIVITY_FAIL_SYN; failMsg.mAttacker = attacker; failMsg.mSkillIndex = skillIndex; failMsg.mFailCode = FAIL_SKILL_CASTING_DONT_OBSTACLE; NETWORK2->QuickSend( pAttacker, (char*)&failMsg, sizeof(failMsg) ); return; } } } } void cSkillManager::PlayerNormalAttackRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned char skillStep = pMsg->mSkillStep; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerNormalAttackRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } pAttacker->MoveStop(); pAttacker->SkillReqCntPlus(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ±âº» °ø°Ý ½ºÅ³ À妽º°¡ ¾Æ´Ô if( skillIdx > NORMAL_ATTACK_SKILL_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerNormalAttackRequest - skillIdx[%d] > NORMAL_ATTACK_SKILL_MAX", skillIdx ); throw SKILL_USED_ERR_SKILLTYPE; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// Ÿ°Ù °´Ã¼ üũ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; pAttacker->CalcDirection( pTarget->GetXPos(), pTarget->GetYPos() ); if( pTarget->GetStateDie() == true ) throw SKILL_USED_ERR_TARGETOBJECT; if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = pTarget->GetXPos( ); posMsg->mTargetPosY = pTarget->GetYPos( ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } /// ÀÌ¹Ì ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) { pAttacker->SkillCoolTimeFailPlus(); throw SKILL_USED_ERR_USING; } /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("playerNormalAttackRequest skillScript[%d]", skillIdx ); throw SKILL_ADD_ERR_SCRIPT; } /// ¾×Ƽºê ½ºÅ³ÀÌ ¾Æ´Ñ °æ¿ì if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { assert(NULL); NETWORK2->PostServerEvent("playerNormalAttackRequest eSKILLTYPE_PASSIVE[%d,%d]", skillIdx, pSkillInfo->mType ); throw SKILL_USED_ERR_PASSIVE; } /// ±âº» °ø°Ýµµ ÄðŸÀÓ Ã¼Å©¸¦ ÇØ¾ß Çϱ⠶§¹®¿¡ º¸À¯½ºÅ³ ¸®½ºÆ®¿¡ ´ëÇ¥¹øÈ£(1)·Î ³Ö´Â´Ù. cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( attacker.index, NORMAL_ATTACK_SKILL ); if( !pPlayerHaveSkill ) { assert(NULL); NETWORK2->PostServerEvent("playerNormalAttackRequest GetPlayerHaveSkill[%d,%d]", attacker.index, NORMAL_ATTACK_SKILL ); throw SKILL_USED_ERR_DONTHAVE; } /// ½ºÅ³ ½ºÅ©¸³Æ® ½ºÅÜÁ¤º¸ Àоî¿È unsigned int haveStep = pPlayerHaveSkill->GetSkillStep(); if( haveStep < skillStep ) { NETWORK2->PostServerEvent("cSkillManager::PlayerNormalAttackRequest haveStep < skillStep(%d,%d,%d)", NORMAL_ATTACK_SKILL, haveStep, skillStep ); throw SKILL_USED_ERR_DONTHAVE; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[skillStep]; /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ eWEAPON_STATE weaponState = pAttacker->GetWeaponState(); bool IsEquipment = true; if( pSkillInfo->mUseEquipment ) { /// Âø¿ë Àåºñ üũ switch( pSkillInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) IsEquipment = false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) IsEquipment = false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_CLOTH: if( pAttacker->GetArmorSets() != ARMOR_SETS_ROBES ) IsEquipment = false; break; case eEQUIPTYPE_LIGHTARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_LIGHT ) IsEquipment = false; break; case eEQUIPTYPE_HEAVYARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_HEAVY ) IsEquipment = false; break; } } if( IsEquipment == false ) { NETWORK2->PostServerEvent("player[%d]NormalAttack[%d]Request IsEquipment[%d,%d]== false", attacker.index, weaponState,pAttacker->GetArmorSets(), skillIdx ); throw SKILL_USED_ERR_EQUIPMENT; } /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { unsigned long attackerTeamType = pAttacker->GetPvPDMTeam(); if( ePVPDM_TEAMTYPE_MAX != attackerTeamType ) { if( attackerTeamType == ((cMonster*)pTarget)->GetDMTeamType() ) throw SKILL_USED_ERR_TARGETSELECT; } } else if( target.type == eOBJECTTYPE_PLAYER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pStepInfo->mTargetDist, pSkillInfo->mRangeType, true ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// Ŭ¶ó,¼­¹ö µµÂø ½Ã°£ Â÷À̸¸Å­ÀÇ °Å¸® Çã¿ëÄ¡ cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); NiPoint3 targetPos( pTarget->GetXPos(), pTarget->GetYPos(), pTarget->Height() ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = pTarget->GetXPos( ); posMsg->mTargetPosY = pTarget->GetYPos( ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } unsigned long currentTime = NETWORK2->GetAccumTime(); /// ÄðŸÀÓ if( pStepInfo->mCoolTime != 0 && pPlayerHaveSkill->GetEndCoolTime() > currentTime ) { pAttacker->SkillCoolTimeFailPlus(); throw SKILL_USED_ERR_COOLTIME; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "playerNormalAttackRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; unsigned char errorCode = pSkillObject->InitPlayerNormalAttack( characterIdx, target, skillIdx, skillStep, skillUniqueIdx ); if( errorCode != 0 ) { NETWORK2->PostServerEvent( "playerNormalAttackRequest new SkillObject[%d] == false", errorCode ); SAFE_DELETE( pSkillObject ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "playerNormalAttackRequest VehicleAttack[%d,%d,%d]", characterIdx, skillIdx, skillStep ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_USED_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; synMsg.Protocol = NM_SKILL_USED_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = pTarget->GetXPos(); synMsg.mTargetPosY = pTarget->GetYPos(); synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->SkillSuccessCntPlus(); // /// ¹ßµ¿ üũ // CheckActInfluence( eACTSTATUS_ACTIVESKILL, pAttacker, pTarget ); return; } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_USED_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::PlayerObjectSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg, bool casting ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned char skillStep = pMsg->mSkillStep; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerObjectSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } pAttacker->MoveStop(); pAttacker->SkillReqCntPlus(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ±âº» °ø°Ý ½ºÅ³ À妽ºÀΰæ¿ì ¿À·ù if( skillIdx <= NORMAL_ATTACK_SKILL_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest - skillIdx[%d] > NORMAL_ATTACK_SKILL_MAX", skillIdx ); throw SKILL_USED_ERR_SKILLTYPE; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ½ºÅ³ »ç¿ë ºÒ°¡ if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; if( pSkillInfo->mShotType == eSHOTTYPE_CASTING && casting != true ) { NETWORK2->PostServerEvent("PlayerObjectSkillRequest[%d] ShotType != eSHOTTYPE_CASTING[%d]", characterIdx, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } if( pSkillInfo->mShotType != eSHOTTYPE_CASTING && casting == true ) { NETWORK2->PostServerEvent("PlayerObjectSkillRequest[%d] ShotType == eSHOTTYPE_CASTING[%d]", characterIdx, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ¾×Ƽºê ½ºÅ³ÀÌ ¾Æ´Ñ °æ¿ì if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest eSKILLTYPE_PASSIVE[%d,%d]", skillIdx, pSkillInfo->mType ); throw SKILL_USED_ERR_PASSIVE; } /// °ø°ÝÀÚÀÇ º¸À¯½ºÅ³ÀÎÁö üũ cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( attacker.index, skillIdx ); if( !pPlayerHaveSkill ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest GetPlayerHaveSkill[%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_DONTHAVE; } unsigned char stepIdx = pPlayerHaveSkill->GetSkillStep(); if( stepIdx < skillStep ) { NETWORK2->PostServerEvent("PlayerObjectSkillRequest stepIdx < skillStep[%d,%d,%d,%d]", attacker.index, skillIdx, stepIdx, skillStep ); throw SKILL_USED_ERR_DONTHAVE; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[skillStep]; /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ bool IsEquipment = true; if( pSkillInfo->mUseEquipment ) { eWEAPON_STATE weaponState = pAttacker->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pSkillInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) IsEquipment = false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) IsEquipment = false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_CLOTH: if( pAttacker->GetArmorSets() != ARMOR_SETS_ROBES ) IsEquipment = false; break; case eEQUIPTYPE_LIGHTARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_LIGHT ) IsEquipment = false; break; case eEQUIPTYPE_HEAVYARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_HEAVY ) IsEquipment = false; break; } } if( IsEquipment == false ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest IsEquipment == false" ); throw SKILL_USED_ERR_EQUIPMENT; } /// ij¸¯ÅÍ »óÅ if( pSkillInfo->mUseState != eSKILL_USE_STATE_NONE ) // ¸ðµÎ { if( pAttacker->GetMaxHP() == 0 ) { NETWORK2->PostServerEvent("0 divide 1"); throw SKILL_USED_ERR_USEVALUE; } if( pAttacker->GetMaxMP() == 0 ) { NETWORK2->PostServerEvent("0 divide 2"); throw SKILL_USED_ERR_USEVALUE; } switch( pSkillInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // HPUP if( pStepInfo->mUseStateValue > ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_HP_PER_DOWN: // HPDONW: if( pStepInfo->mUseStateValue < ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_UP: // MPUP: if( pStepInfo->mUseStateValue > ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_DOWN: // MPDOWN: if( pStepInfo->mUseStateValue < ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_BUFF: // if( pAttacker->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_DEBUFF: // MPDOWN: if( pAttacker->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; default: assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest pSkillInfo->mUseState[%d]", pSkillInfo->mUseState ); throw SKILL_USED_ERR_SCRIPT; } } unsigned long useMP = pStepInfo->mUseMP; if( pStepInfo->mUseMPPer != 0 ) useMP += pAttacker->GetOriMPMax() * pStepInfo->mUseMPPer / 100; /// ¼Ò¸ð MP üũ if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( useMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð HP ¼öÄ¡ üũ if( pStepInfo->mUseHP >= pAttacker->GetHP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->IsItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) throw SKILL_USED_ERR_USEVALUE; } cBaseObject* pTarget = NULL; NiPoint3 targetPos = NiPoint3::ZERO; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_SELF_NOTARGET: /// ÀÚ½ÅÀÌ ¹üÀ§ ½ÃÀÛÀ§Ä¡¿©¼­ °Å¸®Ã¼Å© ¾ÈÇÔ { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; } break; case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ case eBOUNDTYPE_SELF_TARGET: /// ½ÃÀüÀÚ(ÀÚ½Å) ±âÁعüÀ§ - ¹ßµ¿½Ã Ÿ°Ù Á¸Àç { /// ÀڽŠÀϰæ¿ì °Å¸®Ã¼Å© ¾ÈÇÔ if( pSkillInfo->mApplyType == eAPPLYTYPE_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; break; } /// Ÿ°ÙÀÌ ÀÖ´Â ½ºÅ³ÀÇ »ç°Å¸®´Â 0ÀÌ µÉ¼ö ¾ø´Ù. - ½ºÅ©¸³Æ® ÀÛ¼º ¿À·ù if( pStepInfo->mTargetDist == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerObjectSkillRequest[%d] mTargetDist == 0", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); /// Ÿ°Ù °´Ã¼ È®ÀÎ if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); /// ºÎȰ ½ºÅ³ÀÎÁö üũ bool isResurrection = false; if( pSkillInfo->mApplyType == eAPPLYTYPE_DIEBUDDY ) { isResurrection = true; if( NETWORK2->GetServerType() == _E_ST_ID_PVP_ ) throw SKILL_USED_ERR_TARGETSELECT; } /// Ÿ°Ù »ýÁ¸ À¯¹« üũ if( pTarget->GetStateDie() == true && isResurrection == false ) throw SKILL_USED_ERR_TARGETOBJECT; else if( pTarget->GetStateDie() == false && isResurrection == true ) throw SKILL_USED_ERR_TARGETOBJECT; /// Ÿ°Ù ŸÀÔ Ã¼Å© switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: break; case eAPPLYTYPE_ENEMY: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { unsigned long attackerTeamType = pAttacker->GetPvPDMTeam(); if( ePVPDM_TEAMTYPE_MAX != attackerTeamType ) { if( attackerTeamType == ((cMonster*)pTarget)->GetDMTeamType() ) throw SKILL_USED_ERR_TARGETSELECT; } } else if( target.type == eOBJECTTYPE_PLAYER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUDDY: { /// pvpÀ¯Àú »©ÇؾßÇÔ if( target.type != eOBJECTTYPE_PLAYER ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) break; bool isParty = false; /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÎÁö üũ cParty* pParty = PARTYMAN->GetParty( ((cPlayer*)pAttacker)->GetPartyIndex() ); if( pParty && pParty->IsUser( target.index ) ) { isParty = true; } else { /// ÆÄƼ¿¬ÇÕÀÎÁö üũ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( ((cPlayer*)pAttacker)->GetPartyUnionIndex() ); if( partyUnion && partyUnion->IsUser( pAttacker->GetObjectID(), target.index ) ) { isParty = true; } } /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÌ ¾Æ´Ñ °æ¿ì if( isParty == false ) throw SKILL_USED_ERR_TARGETSELECT; } break; } /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pStepInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } pAttacker->CalcDirection( pTarget->GetXPos(), pTarget->GetYPos() ); /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); }break; /// ÇʵåÀΰæ¿ì´Â ÀÌÇÔ¼ö¿¡ µé¾î¿Ã¼ö ¾øÀ½ case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: default: { /// ½ºÅ©¸³Æ® ³»¿ëÀÌ À߸øµÆ´Ù. assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest mBoundType[%d,%d]", skillIdx, pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ if( pSkillInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_BUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; }//end switch( pSkillInfo->mApplyType ) } /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } unsigned long currentTime = NETWORK2->GetAccumTime(); /// ÄðŸÀÓ if( pStepInfo->mCoolTime != 0 && pPlayerHaveSkill->GetEndCoolTime() > currentTime ) { pAttacker->SkillCoolTimeFailPlus(); throw SKILL_USED_ERR_COOLTIME; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerObjectSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitPlayerSkill( skillIdx, skillStep, skillUniqueIdx, pAttacker, pTarget, pStepInfo->mCastingTime ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ assert(NULL); SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "PlayerObjectSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "PlayerObjectSkillRequest VehicleAttack[%d,%d,%d]", characterIdx, skillIdx, skillStep ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ij½ºÆÃÀ» ÇÏÁö ¾Ê´Â ½ºÅ³ÀÌ¸é ½ºÅ³»ç¿ë½Ã ¼Ò¸ðÇ׸ñ °¨¼Ò if( casting == false ) { /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// HP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( pStepInfo->mUseHP != 0 ) { /// HP ¼Ò¸ð & ¸Þ¼¼Áö ¹ß¼Û pAttacker->HPUse( pStepInfo->mUseHP, true ); } /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->ItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) { assert(NULL); NETWORK2->PostServerEvent("ERROR - item use skill itemidx[%d], itemcnd[%d]", pSkillInfo->mUseItem, pStepInfo->mUseItemCount ); } } /// ij½ºÆÃÀÌ ¾Æ´Ñ °æ¿ì ¹ßµ¿ üũ /// *** ij½ºÆÃÀÎ °æ¿ì´Â skillObjÀÇ RequireValue() ¿¡¼­ üũ *** switch( pSkillInfo->mType ) { case eSKILLTYPE_DAMAGE: case eSKILLTYPE_MPDAMAGE: CheckActInfluence( eACTSTATUS_ACTIVESKILL, pAttacker, pTarget ); break; case eSKILLTYPE_HEAL: CheckActInfluence( eACTSTATUS_HEALSKILL, pAttacker, pTarget ); break; } /// ½ºÅ³ ¹ßµ¿ È¿°ú if( pStepInfo->mActiveIdx != 0 ) SKILLMANAGER->CheckSkillActInfluence( pStepInfo->mActiveIdx, pAttacker, pTarget ); } /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) resMsg->Protocol = NM_SKILL_CAST_USED_RES; else resMsg->Protocol = NM_SKILL_USED_RES; resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) synMsg.Protocol = NM_SKILL_CAST_USED_SYN; else synMsg.Protocol = NM_SKILL_USED_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = targetPos.x; synMsg.mTargetPosY = targetPos.y; synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->SkillSuccessCntPlus(); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL ); if ( resMsg != NULL ) { if( casting == true ) resMsg->Protocol = NM_SKILL_CAST_USED_RES; else resMsg->Protocol = NM_SKILL_USED_RES; resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::PlayerPositionSkillRequest( unsigned long characterIdx, MSG_REQ_POS_USED* pMsg, bool casting ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â °ø°ÝÀÚÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; float targetXPos = pMsg->mTargetPosX; float targetYPos = pMsg->mTargetPosY; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned char skillStep = pMsg->mSkillStep; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerPositionSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } pAttacker->MoveStop(); pAttacker->SkillReqCntPlus(); pAttacker->CalcDirection( targetXPos, targetYPos ); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ±âº» °ø°Ý ½ºÅ³ À妽ºÀΰæ¿ì ¿À·ù if( skillIdx <= NORMAL_ATTACK_SKILL_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest - skillIdx[%d] > NORMAL_ATTACK_SKILL_MAX", skillIdx ); throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ë ºÒ°¡ if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ÀÌ¹Ì ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( eOBJECTTYPE_NONE, 0 ); /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos( pAttacker->GetXPos(), pAttacker->GetYPos() ); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget.type = eOBJECTTYPE_NONE; posMsg->mTargetPosX = 0.0f; posMsg->mTargetPosY = 0.0f; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } if( pSkillInfo->mShotType == eSHOTTYPE_CASTING && casting != true ) { assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest[%d] ShotType != eSHOTTYPE_CASTING[%d]", characterIdx, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } if( pSkillInfo->mShotType != eSHOTTYPE_CASTING && casting == true ) { assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest[%d] ShotType == eSHOTTYPE_CASTING[%d]", characterIdx, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ¾×Ƽºê ½ºÅ³ÀÌ ¾Æ´Ñ °æ¿ì if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest eSKILLTYPE_PASSIVE[%d,%d]", skillIdx, pSkillInfo->mType ); throw SKILL_USED_ERR_PASSIVE; } /// °ø°ÝÀÚÀÇ º¸À¯½ºÅ³ÀÎÁö üũ cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( attacker.index, skillIdx ); if( !pPlayerHaveSkill ) { assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest GetPlayerHaveSkill[%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_DONTHAVE; } unsigned char stepIdx = pPlayerHaveSkill->GetSkillStep(); if( stepIdx < skillStep ) { NETWORK2->PostServerEvent("PlayerPositionSkillRequest stepIdx < skillStep[%d,%d,%d,%d]", attacker.index, skillIdx, stepIdx, skillStep ); throw SKILL_USED_ERR_DONTHAVE; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[skillStep]; /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ bool IsEquipment = true; if( pSkillInfo->mUseEquipment ) { eWEAPON_STATE weaponState = pAttacker->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pSkillInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) IsEquipment = false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) IsEquipment = false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_CLOTH: if( pAttacker->GetArmorSets() != ARMOR_SETS_ROBES ) IsEquipment = false; break; case eEQUIPTYPE_LIGHTARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_LIGHT ) IsEquipment = false; break; case eEQUIPTYPE_HEAVYARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_HEAVY ) IsEquipment = false; break; } } if( IsEquipment == false ) { assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest IsEquipment == false" ); throw SKILL_USED_ERR_EQUIPMENT; } /// ij¸¯ÅÍ »óÅ if( pSkillInfo->mUseState != eSKILL_USE_STATE_NONE ) // ¸ðµÎ { switch( pSkillInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // HPUP if( pStepInfo->mUseStateValue > ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_HP_PER_DOWN: // HPDONW: if( pStepInfo->mUseStateValue < ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_UP: // MPUP: if( pStepInfo->mUseStateValue > ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_DOWN: // MPDOWN: if( pStepInfo->mUseStateValue < ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_BUFF: // if( pAttacker->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_DEBUFF: // MPDOWN: if( pAttacker->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; default: assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest pSkillInfo->mUseState[%d]", pSkillInfo->mUseState ); throw SKILL_USED_ERR_SCRIPT; } } unsigned long useMP = pStepInfo->mUseMP; if( pStepInfo->mUseMPPer != 0 ) useMP += pAttacker->GetOriMPMax() * pStepInfo->mUseMPPer / 100; /// ¼Ò¸ð MP üũ if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( useMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð HP if( pStepInfo->mUseHP >= pAttacker->GetHP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->IsItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) throw SKILL_USED_ERR_USEVALUE; } /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { /// ÇʵåÀΰæ¿ì¸¸ ÀÌÇÔ¼ö¿¡ µé¾î¿È case eBOUNDTYPE_AUTOFIELD: case eBOUNDTYPE_FIELD: { NiPoint3 targetPos( targetXPos, targetYPos, 0.0f ); AIMANAGER->CalcHeight( pAttacker->GetMapNumber(), &targetPos.z, targetXPos, targetYPos ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pStepInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, NULL, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos(); posMsg->mAttackerPosY = pAttacker->GetYPos(); posMsg->mTarget.type = eOBJECTTYPE_NONE; posMsg->mTargetPosX = 0.0f; posMsg->mTargetPosY = 0.0f; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } }break; default: { /// ½ºÅ©¸³Æ® ³»¿ëÀÌ À߸øµÆ´Ù. assert(NULL); NETWORK2->PostServerEvent("PlayerPositionSkillRequest pSkillInfo->mBoundType[%d]", pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ if( pSkillInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: NETWORK2->PostServerEvent("PlayerPositionSkillRequest pSkillInfo->mApplyValueType[%d] bad value", pSkillInfo->mApplyType ); throw SKILL_USED_ERR_APPLYVALUE_STATE; break; }//end switch( pSkillInfo->mApplyType ) } unsigned long currentTime = NETWORK2->GetAccumTime(); /// ÄðŸÀÓ if( pStepInfo->mCoolTime != 0 && pPlayerHaveSkill->GetEndCoolTime() > currentTime ) { pAttacker->SkillCoolTimeFailPlus(); throw SKILL_USED_ERR_COOLTIME; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerPositionSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitPlayerSkillPosition( characterIdx, targetXPos, targetYPos, skillIdx, skillStep, skillUniqueIdx, casting ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ assert(NULL); SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "PlayerPositionSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "PlayerPositionSkillRequest VehicleAttack[%d,%d,%d]", characterIdx, skillIdx, skillStep ); /// ½ºÅ³ ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ij½ºÆÃÀ» ÇÏÁö ¾Ê´Â ½ºÅ³ÀÌ¸é ½ºÅ³»ç¿ë½Ã ¼Ò¸ðÇ׸ñ °¨¼Ò if( casting == false ) { /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// HP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( pStepInfo->mUseHP != 0 ) { /// HP ¼Ò¸ð & ¸Þ¼¼Áö ¹ß¼Û pAttacker->HPUse( pStepInfo->mUseHP, true ); } /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->ItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) { assert(NULL); NETWORK2->PostServerEvent("ERROR - item use skill itemidx[%d], itemcnd[%d]", pSkillInfo->mUseItem, pStepInfo->mUseItemCount ); } } } /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) resMsg->Protocol = NM_SKILL_POS_CAST_USED_RES; else resMsg->Protocol = NM_SKILL_POS_USED_RES; resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_POS_USED synMsg; synMsg.Category = NM_SKILL; /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) synMsg.Protocol = NM_SKILL_POS_CAST_USED_SYN; else synMsg.Protocol = NM_SKILL_POS_USED_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTargetPosX = targetXPos; synMsg.mTargetPosY = targetYPos; synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->SkillSuccessCntPlus(); } catch( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL ); if ( resMsg != NULL ) { if( casting == true ) resMsg->Protocol = NM_SKILL_POS_CAST_USED_RES; else resMsg->Protocol = NM_SKILL_POS_USED_RES; resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::PlayerMonSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg, bool casting ) { eMONSTERATTACK_TYPE attackType = (eMONSTERATTACK_TYPE)pMsg->mSkillClassIndex; /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long clientIdx = pMsg->mManagedKey; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerMonSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } pAttacker->MonSkillReqCntPlus(); pAttacker->MoveStop(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ¸ó½ºÅÍ º¯½ÅÁßÀÌ ¾Æ´Ñµ¥ ¸ó½ºÅÍ °ø°ÝÀÌ µé¾î¿Â °æ¿ì - ¸Þ¼¼Áö ½Ã°£Â÷·Î ÀÎÇØ µé¾î¿Ã¼ö ÀÖÀ½ unsigned long monsterClassIdx = pAttacker->GetChgMonsterIdx(); if( monsterClassIdx == 0 ) throw SKILL_USED_ERR_SKILLTYPE; if( attackType >= eMONSTERATTACK_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonSkillRequest - attackType[%d] > eMONSTERATTACK_MAX", attackType ); throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³index üũ sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, attackType ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerMonSkillRequest skillScript[%d,%d]", monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ë ºÒ°¡ if( attackType > eMONSTERATTACK_NORMAL2 ) { /// ±âº» °ø°ÝÀº Á¦¿ÜÇϰí ó¸®ÇÑ´Ù. if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; } if( pAttacker->GetChgMonsterIdx() == 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) { pAttacker->MonSkillCoolTimeFailPlus(); throw SKILL_USED_ERR_USING; } if( pSkillInfo->mShotType == eSHOTTYPE_CASTING && casting != true ) { NETWORK2->PostServerEvent("PlayerMonSkillRequest[%d,%d] ShotType != eSHOTTYPE_CASTING[%d]", characterIdx, monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } if( pSkillInfo->mShotType != eSHOTTYPE_CASTING && casting == true ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonSkillRequest[%d,%d] ShotType == eSHOTTYPE_CASTING[%d]", characterIdx, monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } /// ¼Ò¸ð MP üũ unsigned long useMP = pSkillInfo->mUseMP; if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( pSkillInfo->mUseMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; cBaseObject* pTarget = NULL; NiPoint3 targetPos = NiPoint3::ZERO; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_SELF_NOTARGET: /// ÀÚ½ÅÀÌ ¹üÀ§ ½ÃÀÛÀ§Ä¡¿©¼­ °Å¸®Ã¼Å© ¾ÈÇÔ break; case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ case eBOUNDTYPE_SELF_TARGET: /// ½ÃÀüÀÚ(ÀÚ½Å) ±âÁعüÀ§ - ¹ßµ¿½Ã Ÿ°Ù Á¸Àç { /// ÀڽŠÀϰæ¿ì °Å¸®Ã¼Å© ¾ÈÇÔ if( pSkillInfo->mApplyType == eAPPLYTYPE_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; break; } /// Ÿ°ÙÀÌ ÀÖ´Â ½ºÅ³ÀÇ »ç°Å¸®´Â 0ÀÌ µÉ¼ö ¾ø´Ù. - ½ºÅ©¸³Æ® ÀÛ¼º ¿À·ù if( pSkillInfo->mTargetDist == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerMonSkillRequest pStepInfo[%d,%d]->mTargetDist == 0", monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); /// Ÿ°Ù °´Ã¼ È®ÀÎ if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); /// Ÿ°Ù »ýÁ¸ À¯¹« üũ if( pTarget->GetStateDie() == true ) throw SKILL_USED_ERR_TARGETOBJECT; /// Ÿ°Ù ŸÀÔ Ã¼Å© switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: break; case eAPPLYTYPE_ENEMY: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { unsigned long attackerTeamType = pAttacker->GetPvPDMTeam(); if( ePVPDM_TEAMTYPE_MAX != attackerTeamType ) { if( attackerTeamType == ((cMonster*)pTarget)->GetDMTeamType() ) throw SKILL_USED_ERR_TARGETSELECT; } } else if( target.type == eOBJECTTYPE_PLAYER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUDDY: { /// pvpÀ¯Àú »©ÇؾßÇÔ if( target.type != eOBJECTTYPE_PLAYER ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) break; bool isParty = false; /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÎÁö üũ cParty* pParty = PARTYMAN->GetParty( ((cPlayer*)pAttacker)->GetPartyIndex() ); if( pParty && pParty->IsUser( target.index ) ) { isParty = true; } else { /// ÆÄƼ¿¬ÇÕÀÎÁö üũ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( ((cPlayer*)pAttacker)->GetPartyUnionIndex() ); if( partyUnion && partyUnion->IsUser( pAttacker->GetObjectID(), target.index ) ) { isParty = true; } } /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÌ ¾Æ´Ñ °æ¿ì if( isParty == false ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DIEBUDDY: { /// ¸ó½ºÅÍ´Â ÆÄƼ³ª Á×Àºµ¿·á¸¦ ¼³Á¤ÇÏÁö ¾Ê´Â´Ù. NETWORK2->PostServerEvent("PlayerMonSkillRequest mBoundType[%d,%d]", pMsg->mSkillClassIndex, pSkillInfo->mApplyType ); throw SKILL_USED_ERR_SCRIPT; } break; } /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pSkillInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); pAttacker->CalcDirection( targetPos.x, targetPos.y ); }break; /// ÇʵåÀΰæ¿ì´Â ÀÌÇÔ¼ö¿¡ µé¾î¿Ã¼ö ¾øÀ½ case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: default: { /// ½ºÅ©¸³Æ® ³»¿ëÀÌ À߸øµÆ´Ù. assert(NULL); NETWORK2->PostServerEvent("PlayerMonSkillRequest mBoundType[%d,%d]", monsterClassIdx, pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } if( pAttacker->IsChgMonCoolTimeEnd( attackType ) == false ) { throw SKILL_USED_ERR_COOLTIME; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerMonSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerMonSkillObject* pSkillObject = new cPlayerMonSkillObject; bool init = pSkillObject->InitPlayerMonAttack( characterIdx, pAttacker->GetChgMonsterIdx(), attackType, target, skillUniqueIdx, casting, pAttacker->GetStatus2()->mAttackSpeed, pAttacker->GetMapNumber() ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ assert(NULL); SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "PlayerMonSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "PlayerMonSkillRequest VehicleAttack[%d,%d,%d]", characterIdx, pAttacker->GetChgMonsterIdx(), attackType ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ij½ºÆÃÀ» ÇÏÁö ¾Ê´Â ½ºÅ³ÀÌ¸é ½ºÅ³»ç¿ë½Ã ¼Ò¸ðÇ׸ñ °¨¼Ò if( casting == false ) { /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// ij½ºÆÃÀÌ ¾Æ´Ñ °æ¿ì ¹ßµ¿ üũ /// *** ij½ºÆÃÀÎ °æ¿ì´Â skillObjÀÇ RequireValue() ¿¡¼­ üũ *** if( attackType >= eMONSTERATTACK_SKILL1 ) { switch( pSkillInfo->mType ) { case eMONSTERSKILLTYPE_DAMAGE: case eMONSTERSKILLTYPE_MPDAMAGE: CheckActInfluence( eACTSTATUS_ACTIVESKILL, pAttacker, pTarget ); break; case eMONSTERSKILLTYPE_HEAL: CheckActInfluence( eACTSTATUS_HEALSKILL, pAttacker, pTarget ); break; } /// ½ºÅ³ ¹ßµ¿ È¿°ú if( pSkillInfo->mActiveIdx != 0 ) SKILLMANAGER->CheckSkillActInfluence( pSkillInfo->mActiveIdx, pAttacker, pTarget ); } } /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) resMsg->Protocol = NM_SKILL_CAST_USED_MON_RES; else resMsg->Protocol = NM_SKILL_USED_MON_RES; resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = pMsg->mSkillClassIndex; resMsg->mManagedKey = pMsg->mManagedKey; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) synMsg.Protocol = NM_SKILL_CAST_USED_SYN; else synMsg.Protocol = NM_SKILL_USED_SYN; synMsg.mSkillClassIndex = attackType; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = targetPos.x; synMsg.mTargetPosY = targetPos.y; synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->MonSkillSuccessCntPlus(); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL ); if ( resMsg != NULL ) { if( casting == true ) resMsg->Protocol = NM_SKILL_CAST_USED_MON_RES; else resMsg->Protocol = NM_SKILL_USED_MON_RES; resMsg->ErrorCode = error; resMsg->mSkillClassIndex = attackType; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::PlayerMonPosSkillRequest( unsigned long characterIdx, MSG_REQ_POS_USED* pMsg, bool casting ) { eMONSTERATTACK_TYPE attackType = (eMONSTERATTACK_TYPE)pMsg->mSkillClassIndex; /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â °ø°ÝÀÚÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; float targetXPos = pMsg->mTargetPosX; float targetYPos = pMsg->mTargetPosY; unsigned long clientIdx = pMsg->mManagedKey; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerPositionSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } pAttacker->MonSkillReqCntPlus(); pAttacker->MoveStop(); pAttacker->CalcDirection( targetXPos, targetYPos ); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ¸ó½ºÅÍ º¯½ÅÁßÀÌ ¾Æ´Ñµ¥ ¸ó½ºÅÍ °ø°ÝÀÌ µé¾î¿Â °æ¿ì - ¸Þ¼¼Áö ½Ã°£Â÷·Î ÀÎÇØ µé¾î¿Ã¼ö ÀÖÀ½ unsigned long monsterClassIdx = pAttacker->GetChgMonsterIdx(); if( monsterClassIdx == 0 ) throw SKILL_USED_ERR_SKILLTYPE; if( attackType >= eMONSTERATTACK_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonSkillRequest - attackType[%d] > eMONSTERATTACK_MAX", attackType ); throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³index üũ sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, attackType ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerMonSkillRequest skillScript[%d,%d]", monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ë ºÒ°¡ if( attackType > eMONSTERATTACK_NORMAL2 ) { /// ±âº» °ø°ÝÀº Á¦¿ÜÇϰí ó¸®ÇÑ´Ù. if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; } if( pAttacker->GetChgMonsterIdx() == 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) { pAttacker->MonSkillCoolTimeFailPlus(); throw SKILL_USED_ERR_USING; } /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( eOBJECTTYPE_NONE, 0 ); /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos( pAttacker->GetXPos(), pAttacker->GetYPos() ); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget.type = eOBJECTTYPE_NONE; posMsg->mTargetPosX = 0.0f; posMsg->mTargetPosY = 0.0f; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } if( pSkillInfo->mShotType == eSHOTTYPE_CASTING && casting != true ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonPosSkillRequest[%d] ShotType != eSHOTTYPE_CASTING[%d]", characterIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } if( pSkillInfo->mShotType != eSHOTTYPE_CASTING && casting == true ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonPosSkillRequest[%d] ShotType == eSHOTTYPE_CASTING[%d]", characterIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } /// ¼Ò¸ð MP üũ unsigned long useMP = pSkillInfo->mUseMP; if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( pSkillInfo->mUseMP ); } /// ¼Ò¸ð MP if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { /// ÇʵåÀΰæ¿ì¸¸ ÀÌÇÔ¼ö¿¡ µé¾î¿È case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: { NiPoint3 targetPos( targetXPos, targetYPos, 0.0f ); AIMANAGER->CalcHeight( pAttacker->GetMapNumber(), &targetPos.z, targetXPos, targetYPos ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pSkillInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, NULL, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos(); posMsg->mAttackerPosY = pAttacker->GetYPos(); posMsg->mTarget.type = eOBJECTTYPE_NONE; posMsg->mTargetPosX = 0.0f; posMsg->mTargetPosY = 0.0f; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } }break; default: { /// ½ºÅ©¸³Æ® ³»¿ëÀÌ À߸øµÆ´Ù. assert(NULL); NETWORK2->PostServerEvent("PlayerMonPosSkillRequest pSkillInfo->mBoundType[%d]", pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } if( pAttacker->IsChgMonCoolTimeEnd( attackType ) == false ) { throw SKILL_USED_ERR_COOLTIME; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerMonPosSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerMonSkillObject* pSkillObject = new cPlayerMonSkillObject; bool init = pSkillObject->InitPlayerMonPosition( characterIdx, monsterClassIdx, attackType, targetXPos, targetYPos, skillUniqueIdx, casting, pAttacker->GetMapNumber() ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ assert(NULL); SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "PlayerMonPosSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "PlayerMonPosSkillRequest VehicleAttack[%d,%d,%d]", characterIdx, monsterClassIdx, attackType ); /// ½ºÅ³ ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ij½ºÆÃÀ» ÇÏÁö ¾Ê´Â ½ºÅ³ÀÌ¸é ½ºÅ³»ç¿ë½Ã ¼Ò¸ðÇ׸ñ °¨¼Ò if( casting == false ) { /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); } /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) resMsg->Protocol = NM_SKILL_POS_CAST_USED_MON_RES; else resMsg->Protocol = NM_SKILL_POS_USED_MON_RES; resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = attackType; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_POS_USED synMsg; synMsg.Category = NM_SKILL; /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ if( casting == true ) synMsg.Protocol = NM_SKILL_POS_CAST_USED_MON_SYN; else synMsg.Protocol = NM_SKILL_POS_USED_MON_SYN; synMsg.mSkillClassIndex = attackType; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTargetPosX = targetXPos; synMsg.mTargetPosY = targetYPos; synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->SkillSuccessCntPlus(); } catch( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL ); if ( resMsg != NULL ) { if( casting == true ) resMsg->Protocol = NM_SKILL_POS_CAST_USED_MON_RES; else resMsg->Protocol = NM_SKILL_POS_USED_MON_RES; resMsg->ErrorCode = error; resMsg->mSkillClassIndex = attackType; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::MapChangeSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_ITEMMAPCHANGE* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::MapChangeSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); return; } pAttacker->MoveStop(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// »óÅ üũ if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_MAPCHANGE_STATE; if( pAttacker->IsRequestRejection() == true ) throw SKILL_USED_ERR_MAPCHANGE_STATE; /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù NETWORK2->PostServerEvent("cSkillManager::MapChangeSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[0]; if( pStepInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::MapChangeSkillRequest pStepInfo == NULL [%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// inventory °ËÁõ.. long useItemDBIdx = pAttacker->IsItemMapChange( pMsg->mSlotNumber, pSkillInfo->mUseItem, false, skillIdx ); if( useItemDBIdx == 0 ) throw SKILL_USED_ERR_USEVALUE; /// ¸ÊÀ̵¿ °¡´É üũ if( pStepInfo->mApplyValueType1 == eSTATUSPLUS_MAPCHANGE ) { if( pAttacker->IsItemMapChange( pStepInfo->mApplyValue1 ) == false ) throw SKILL_USED_ERR_MAPCHANGE_STATE; } else if( pStepInfo->mApplyValueType2 == eSTATUSPLUS_MAPCHANGE ) { if( pAttacker->IsItemMapChange( pStepInfo->mApplyValue2 ) == false ) throw SKILL_USED_ERR_MAPCHANGE_STATE; } else throw SKILL_USED_ERR_MAPCHANGE_STATE; /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { NETWORK2->PostServerEvent( "cSkillManager::MapChangeSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitPlayerMapChange( skillIdx, skillUniqueIdx, pAttacker, useItemDBIdx, pStepInfo->mCastingTime ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "cSkillManager::MapChangeSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "MapChangeSkillRequest VehicleAttack[%d,%d]", characterIdx, skillIdx ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_ITEMMAPCHANGE_RES ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; synMsg.Protocol = NM_SKILL_ITEMMAPCHANGE_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = pAttacker->GetXPos(); synMsg.mTargetPosY = pAttacker->GetYPos(); synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_ITEMMAPCHANGE_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::VehiCleSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_VEHICLE* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::VehicleSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); return; } pAttacker->MoveStop(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// »óÅ üũ if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù NETWORK2->PostServerEvent("cSkillManager::VehicleSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[0]; if( pStepInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::VehiCleSkillRequest pStepInfo == NULL [%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// inventory °ËÁõ.. long useItemDBIdx = pAttacker->IsItemVehicle( pMsg->mSlotNumber, pSkillInfo->mUseItem, skillIdx ); if( useItemDBIdx == 0 ) throw SKILL_USED_ERR_USEVALUE; /// ¸ó½ºÅÍ º¯½Å »óÅÂÀÌ¸é »ç¿ë ºÒ°¡ if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_ATTACKERSTATE; /// sInfluenceScript* pInf = SKILLSCRIPT->GetInfluenceInfo( pStepInfo->mInfulenceIdx ); if( pInf == 0 ) { throw SKILL_USED_ERR_ATTACKERSTATE; } if( pInf->mStatusPlusIdx1 != eSTATUSPLUS_VEHICLE && pInf->mStatusPlusIdx2 != eSTATUSPLUS_VEHICLE && pInf->mStatusPlusIdx3 != eSTATUSPLUS_VEHICLE ) { throw SKILL_USED_ERR_ATTACKERSTATE; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { NETWORK2->PostServerEvent( "cSkillManager::VehicleSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitPlayerVehicle( skillIdx, skillUniqueIdx, pAttacker, pSkillInfo->mUseItem, pStepInfo->mCastingTime ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "cSkillManager::VehicleSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "VehicleSkillRequest VehicleAttack[%d,%d]", characterIdx, skillIdx ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_ITEMVEHICLE_RES ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ resMsg->ErrorCode = SKILL_USED_ERR_SUCCESS; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; synMsg.Protocol = NM_SKILL_ITEMVEHICLE_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = pAttacker->GetXPos(); synMsg.mTargetPosY = pAttacker->GetYPos(); synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_ITEMVEHICLE_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::CashMapChangeSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_CASHMAPCHANGE* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned short targetMapNum = pMsg->mMapNumber; float targetX = pMsg->mPosX; float targetY = pMsg->mPosY; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::CashMapChangeSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); return; } pAttacker->MoveStop(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// »óÅ üũ if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_MAPCHANGE_STATE; if( pAttacker->IsRequestRejection() == true ) throw SKILL_USED_ERR_MAPCHANGE_STATE; /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù NETWORK2->PostServerEvent("cSkillManager::CashMapChangeSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[0]; if( pStepInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CashMapChangeSkillRequest pStepInfo == NULL [%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// inventory °ËÁõ.. long useItemDBIdx = pAttacker->IsItemMapChange( pMsg->mSlotNumber, pSkillInfo->mUseItem, true, skillIdx ); if( useItemDBIdx == 0 ) throw SKILL_USED_ERR_USEVALUE; /// ¸ÊÀ̵¿ °¡´É üũ if( !( pStepInfo->mApplyValueType1 == eSTATUSPLUS_CASHMAPCHANGE || pStepInfo->mApplyValueType2 == eSTATUSPLUS_CASHMAPCHANGE ) ) throw SKILL_USED_ERR_MAPCHANGE_STATE; if( pAttacker->IsAutoTrial() == true ) throw SKILL_USED_ERR_MAPCHANGE_STATE; if( targetMapNum < MAP_MIN || MAP_MAX < targetMapNum ) throw SKILL_USED_ERR_MAPCHANGE_STATE; if( NETWORK2->GetServerType() == _E_ST_ID_PVP_ || NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) throw SKILL_USED_ERR_MAPCHANGE_STATE; else if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { if( AIMANAGER->IsPossible( targetMapNum, targetX, targetY, attacker ) == false ) throw SKILL_USED_ERR_MAPCHANGE_STATE; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { NETWORK2->PostServerEvent( "cSkillManager::CashMapChangeSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitCashMapChange( skillIdx, skillUniqueIdx, pAttacker, pStepInfo->mCastingTime, pMsg->mMapNumber, pMsg->mPosX, pMsg->mPosY, useItemDBIdx ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "cSkillManager::CashMapChangeSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "cSkillManager::CashMapChangeSkillRequest VehicleAttack[%d,%d]", characterIdx, skillIdx ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_CASHMAPCHANGE_RES ); if ( resMsg != NULL ) { /// ij½ºÆÃ ¿©ºÎ¿¡ µû¸¥ ¸Þ¼¼Áö ³»¿ë Á¤ÀÇ resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; synMsg.Protocol = NM_SKILL_CASHMAPCHANGE_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = pAttacker->GetXPos(); synMsg.mTargetPosY = pAttacker->GetYPos(); synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_CASHMAPCHANGE_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } void cSkillManager::BlinkSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_BLINK* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::BlinkSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); return; } pAttacker->MoveStop(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// »óÅ üũ if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù NETWORK2->PostServerEvent("cSkillManager::BlinkSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[0]; if( pStepInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::BlinkSkillRequest pStepInfo == NULL [%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ¼ø°£À̵¿ ½ºÅ³¸¸ ¾µ¼ö ÀÖ´Ù if( pSkillInfo->mShotType != eSHOTTYPE_BLINK && pSkillInfo->mShotType != eSHOTTYPE_BLINK_BACK ) throw SKILL_USED_ERR_SCRIPT; /// ij¸¯ÅÍ »óÅ if( pSkillInfo->mUseState != eSKILL_USE_STATE_NONE ) // ¸ðµÎ { if( pAttacker->GetMaxHP() == 0 ) { NETWORK2->PostServerEvent("0 divide 1"); throw SKILL_USED_ERR_USEVALUE; } if( pAttacker->GetMaxMP() == 0 ) { NETWORK2->PostServerEvent("0 divide 2"); throw SKILL_USED_ERR_USEVALUE; } switch( pSkillInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // HPUP if( pStepInfo->mUseStateValue > ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_HP_PER_DOWN: // HPDONW: if( pStepInfo->mUseStateValue < ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_UP: // MPUP: if( pStepInfo->mUseStateValue > ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_DOWN: // MPDOWN: if( pStepInfo->mUseStateValue < ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_BUFF: // if( pAttacker->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_DEBUFF: // MPDOWN: if( pAttacker->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; default: assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest pSkillInfo->mUseState[%d]", pSkillInfo->mUseState ); throw SKILL_USED_ERR_SCRIPT; } } unsigned long useMP = pStepInfo->mUseMP; if( pStepInfo->mUseMPPer != 0 ) useMP += pAttacker->GetOriMPMax() * pStepInfo->mUseMPPer / 100; /// ¼Ò¸ð MP üũ if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( useMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð HP ¼öÄ¡ üũ if( pStepInfo->mUseHP >= pAttacker->GetHP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->IsItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) throw SKILL_USED_ERR_USEVALUE; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { NETWORK2->PostServerEvent( "cSkillManager::BlinkSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ¸ñÀûÁöÁ¡ NiPoint2 targetPos( pMsg->mTargetPosX, pMsg->mTargetPosY ); /// ¸ñÀûÁö±îÁöÀÇ ¹æÇâÁ¤º¸ NiPoint2 dir = targetPos - pAttacker->GetPos(); float range = dir.Unitize(); /// À̵¿Á¦ÇÑ °Å¸® üũ if( pStepInfo->mTargetDist + SYNC_MOVE_RANGE < range ) { /// ¹üÀ§¸¦ ¹þ¾î³ª´Â °æ¿ì¸é Çã¿ë¹üÀ§ ¾È±îÁö¸¸ À̵¿ ½ÃŲ´Ù. range = pStepInfo->mTargetDist + SYNC_MOVE_RANGE; targetPos = pAttacker->GetPos() + ( dir * range ); } /// ¸ñÀûÁöÁ¡±îÁö À̵¿ÀÌ °¡´ÉÇÑÁö üũ - ºÒ°¡´É ÇÒ°æ¿ì °Å¸®¸¦ ÂÎÇô°£´Ù. if( pAttacker->IsMovePossible( pAttacker->GetPos(), targetPos ) != 0 ) { /// ºÐÇÒ ¼ýÀÚ unsigned long divideCnt = 10; targetPos = pAttacker->GetPos(); /// À̵¿°Å¸®¸¦ ºÐÇÒ float divideRange = range / (float)divideCnt; for( unsigned long i = 1 ; i < divideCnt ; ++i ) /// ¾ç³¡Á¡À» Á¦¿ÜÇÏ°í ºÐÇÒµÈ À§Ä¡¸¸Å­ °¡´Éüũ { /// ¸ñÀûÁö¿¡¼­ ºÐÇÒÇÑ °Å¸®¸¸Å­ »©°¡¸é¼­ À̵¿°¡´ÉÇÑÁö üũÈÄ °¡´ÉÇÏ¸é ±×À§Ä¡·Î À̵¿ÇÑ´Ù. NiPoint2 pos = pAttacker->GetPos() + ( dir * ( range - ( divideRange * i ) ) ); if( pAttacker->IsMovePossible( pAttacker->GetPos(), pos ) == 0 ) { targetPos = pos; break; } } } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitPlayerBlink( skillIdx, skillUniqueIdx, pAttacker, targetPos ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "cSkillManager::BlinkSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "BlinkSkillRequest VehicleAttack[%d,%d]", characterIdx, skillIdx ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// HP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( pStepInfo->mUseHP != 0 ) { /// HP ¼Ò¸ð & ¸Þ¼¼Áö ¹ß¼Û pAttacker->HPUse( pStepInfo->mUseHP, true ); } /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->ItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) { assert(NULL); NETWORK2->PostServerEvent("ERROR - item use skill itemidx[%d], itemcnd[%d]", pSkillInfo->mUseItem, pStepInfo->mUseItemCount ); } } /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_BLINK* resMsg = (MSG_RES_SKILL_BLINK*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_BLINK_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = SKILL_USED_ERR_SUCCESS; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); resMsg->mTargetPosX = targetPos.x; resMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_BLINK) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_BLINK synMsg; synMsg.Category = NM_SKILL; synMsg.Protocol = NM_SKILL_BLINK_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mTargetPosX = targetPos.x; synMsg.mTargetPosY = targetPos.y; synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_BLINK* resMsg = (MSG_RES_SKILL_BLINK*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL, NM_SKILL_BLINK_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mTargetPosX = pAttacker->GetXPos(); resMsg->mTargetPosY = pAttacker->GetYPos(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_BLINK) ); } } } void cSkillManager::PlayerNonStopSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â °ø°ÝÀÚÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned char skillStep = pMsg->mSkillStep; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ùaa if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; mSendMsgSet.Clear(); /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerNonStopSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } /// °ø°ÝÀÚ ±×¸®µå¿¡ ÇØ´çÇÏ´Â Ç÷¹À̾ ¸ðµÎ ÀÐ¾î µ¥¹ÌÁö ¹ß¼ÛÀÚ ¸í´Ü¿¡ ³Ö´Â´Ù. cPlayer* pPlayer = GRIDMANAGER->FindFirstPlayer( pAttacker, true ); while( pPlayer != NULL ) { mSendMsgSet.Insert( pPlayer->GetConnectionIdx() ); pPlayer = GRIDMANAGER->FindNextPlayer( true ); } try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ±âº» °ø°Ý ½ºÅ³ À妽ºÀΰæ¿ì ¿À·ù if( skillIdx <= NORMAL_ATTACK_SKILL_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest - skillIdx[%d] > NORMAL_ATTACK_SKILL_MAX", skillIdx ); throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ½ºÅ³ »ç¿ë ºÒ°¡ if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ÀÌ¹Ì ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( eOBJECTTYPE_NONE, 0 ); /// ¾×Ƽºê ½ºÅ³ÀÌ ¾Æ´Ñ °æ¿ì if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest eSKILLTYPE_PASSIVE[%d,%d]", skillIdx, pSkillInfo->mType ); throw SKILL_USED_ERR_PASSIVE; } /// ¾×Ƽºê ŸÀÓµµ ¾ø´Âµ¥ ÄɽºÆÃÇÒÀÏÀº ¾ø´Ù. if( pSkillInfo->mShotType == eSHOTTYPE_CASTING ) { assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest[%d,%d] ShotType == eSHOTTYPE_CASTING", attacker.index, pMsg->mSkillClassIndex ); throw SKILL_USED_ERR_SCRIPT; } /// °ø°ÝÀÚÀÇ º¸À¯½ºÅ³ÀÎÁö üũ cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( attacker.index, skillIdx ); if( !pPlayerHaveSkill ) { assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest GetPlayerHaveSkill[%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_DONTHAVE; } /// ½ºÅ³ ½ºÅ©¸³Æ® ½ºÅÜÁ¤º¸ Àоî¿È unsigned int stepIdx = pPlayerHaveSkill->GetSkillStep(); if( stepIdx < skillStep ) { NETWORK2->PostServerEvent("cSkillManager::PlayerNonStopSkillRequest stepIdx >= pSkillInfo->mStepCount [%d,%d, (%d > %d)]", attacker.index, skillIdx, stepIdx, pSkillInfo->mStepCount ); throw SKILL_USED_ERR_SCRIPT; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[skillStep]; if( pStepInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerNonStopSkillRequest pStepInfo == NULL [%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ bool IsEquipment = true; if( pSkillInfo->mUseEquipment ) { eWEAPON_STATE weaponState = pAttacker->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pSkillInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) IsEquipment = false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) IsEquipment = false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_CLOTH: if( pAttacker->GetArmorSets() != ARMOR_SETS_ROBES ) IsEquipment = false; break; case eEQUIPTYPE_LIGHTARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_LIGHT ) IsEquipment = false; break; case eEQUIPTYPE_HEAVYARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_HEAVY ) IsEquipment = false; break; } } if( IsEquipment == false ) { assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest IsEquipment == false" ); throw SKILL_USED_ERR_EQUIPMENT; } /// ij¸¯ÅÍ »óÅ if( pSkillInfo->mUseState != eSKILL_USE_STATE_NONE ) // ¸ðµÎ { switch( pSkillInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // HPUP if( pStepInfo->mUseStateValue > ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_HP_PER_DOWN: // HPDONW: if( pStepInfo->mUseStateValue < ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_UP: // MPUP: if( pStepInfo->mUseStateValue > ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_DOWN: // MPDOWN: if( pStepInfo->mUseStateValue < ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_BUFF: // if( pAttacker->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_DEBUFF: // MPDOWN: if( pAttacker->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; default: assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest pSkillInfo->mUseState[%d]", pSkillInfo->mUseState ); throw SKILL_USED_ERR_SCRIPT; } } unsigned long useMP = pStepInfo->mUseMP; if( pStepInfo->mUseMPPer != 0 ) useMP += pAttacker->GetOriMPMax() * pStepInfo->mUseMPPer / 100; /// ¼Ò¸ð MP üũ if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( useMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð HP if( pStepInfo->mUseHP >= pAttacker->GetHP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->IsItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) throw SKILL_USED_ERR_USEVALUE; } NiPoint3 targetPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); cBaseObject* pTarget = NULL; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_SELF_NOTARGET: /// ÀÚ½ÅÀÌ ¹üÀ§ ½ÃÀÛÀ§Ä¡¿©¼­ °Å¸®Ã¼Å© ¾ÈÇÔ { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; } break; case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ case eBOUNDTYPE_SELF_TARGET: /// ½ÃÀüÀÚ(ÀÚ½Å) ±âÁعüÀ§ - ¹ßµ¿½Ã Ÿ°Ù Á¸Àç { /// ÀڽŠÀϰæ¿ì °Å¸®Ã¼Å© ¾ÈÇÔ if( pSkillInfo->mApplyType == eAPPLYTYPE_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; break; } /// Ÿ°ÙÀÌ ÀÖ´Â ½ºÅ³ÀÇ »ç°Å¸®´Â 0ÀÌ µÉ¼ö ¾ø´Ù. - ½ºÅ©¸³Æ® ÀÛ¼º ¿À·ù if( pStepInfo->mTargetDist == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerNonStopSkillRequest[%d] mTargetDist == 0", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); /// Ÿ°Ù °´Ã¼ È®ÀÎ if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); /// Ÿ°Ù »ýÁ¸ À¯¹« üũ if( pTarget->GetStateDie() == true ) throw SKILL_USED_ERR_TARGETOBJECT; /// Ÿ°Ù ŸÀÔ Ã¼Å© switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: break; case eAPPLYTYPE_ENEMY: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type != eOBJECTTYPE_MONSTER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } } break; case eAPPLYTYPE_BUDDY: { /// pvpÀ¯Àú »©ÇؾßÇÔ if( target.type != eOBJECTTYPE_PLAYER ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) break; bool isParty = false; /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÎÁö üũ cParty* pParty = PARTYMAN->GetParty( ((cPlayer*)pAttacker)->GetPartyIndex() ); if( pParty && pParty->IsUser( target.index ) ) { isParty = true; } else { /// ÆÄƼ¿¬ÇÕÀÎÁö üũ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( ((cPlayer*)pAttacker)->GetPartyUnionIndex() ); if( partyUnion && partyUnion->IsUser( pAttacker->GetObjectID(), target.index ) ) { isParty = true; } } /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÌ ¾Æ´Ñ °æ¿ì if( isParty == false ) throw SKILL_USED_ERR_TARGETSELECT; } break; } /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pStepInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } pAttacker->CalcDirection( pTarget->GetXPos(), pTarget->GetYPos() ); /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); }break; /// ³í½ºÅ¾À¸·Î Çʵ带 ÁöÁ¤Çϸ鼭 ¼³Á¤À» ÇÏÁø ¾Ê´Â´Ù. - ½ºÅ©¸³Æ®¿À·ù case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: default: { assert(NULL); NETWORK2->PostServerEvent("PlayerNonStopSkillRequest mBoundType[%d,%d]", skillIdx, pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ if( pSkillInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_BUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; }//end switch( pSkillInfo->mApplyType ) } /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } unsigned long currentTime = NETWORK2->GetAccumTime(); /// ÄðŸÀÓ if( pStepInfo->mCoolTime != 0 && pPlayerHaveSkill->GetEndCoolTime() > currentTime ) { pAttacker->SkillCoolTimeFailPlus(); throw SKILL_USED_ERR_COOLTIME; } /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// HP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( pStepInfo->mUseHP != 0 ) { /// HP ¼Ò¸ð & ¸Þ¼¼Áö ¹ß¼Û pAttacker->HPUse( pStepInfo->mUseHP, true ); } /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->ItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) { assert(NULL); NETWORK2->PostServerEvent("ERROR - item use skill itemidx[%d], itemcnd[%d]", pSkillInfo->mUseItem, pStepInfo->mUseItemCount ); } } /// ÄðŸÀÓ °»½Å SKILLMANAGER->UpdateSkillCoolTime( attacker, pMsg->mSkillClassIndex, (unsigned char)stepIdx, NETWORK2->GetAccumTime(), 1.0f ); unsigned char targetMaxCnt = pStepInfo->mApplyCnt; if( targetMaxCnt == 0 || targetMaxCnt > TARGET_CNT_MAX ) targetMaxCnt = TARGET_CNT_MAX; else { /// Àû¿ë ÀοøÀÌ Á¦ÇÑµÈ °æ¿ì °ø°ÝÀÚ°¡ ¹üÀ§ ½ºÅ³ Àû¿ë Àοø Áõ°¡ È¿°ú¿¡ °É·ÁÀÖ´ÂÁö üũ ÇÏ¿© ³Ö±â if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER || pAttacker->GetObjectType() == eOBJECTTYPE_MONSTER ) { long addApplyCnt = (long)pAttacker->GetStateOddity( eODDITYTYPE_ADD_APPLY_CNT ); if( addApplyCnt > 0 ) { if( (addApplyCnt + targetMaxCnt) > UCHAR_MAX ) { assert(0); targetMaxCnt = TARGET_CNT_MAX; } else { targetMaxCnt = targetMaxCnt + (unsigned char)addApplyCnt; if ( targetMaxCnt > TARGET_CNT_MAX ) { assert(0); targetMaxCnt = TARGET_CNT_MAX; } } } } } HANDLE handle = NULL; MSG_RES_SKILL_NONSTOP* resMsg = (MSG_RES_SKILL_NONSTOP*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_NONSTOP_RES ); if ( resMsg == NULL ) throw SKILL_USED_ERR_OBJECTINIT; resMsg->mSkillClassIndex = pMsg->mSkillClassIndex; resMsg->mManagedKey = pMsg->mManagedKey; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); resMsg->mCount = 0; /// Ÿ°Ù ¼±Á¤ if( pSkillInfo->mBoundType != eBOUNDTYPE_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pAttacker->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; } break; case eAPPLYTYPE_BUDDY: { tArray objectIdxAry; if( pStepInfo->mBoundDist2 == 0 ) { /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); float tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, pCheckTarget, pStepInfo->mBoundDist1 ); mRangeCheck.SetRadius( tempRange ); NiPoint3 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); targetPoint.z = pCheckTarget->Height(); /// Ç÷¹À̾ ¹üÀ§ ¾È¿¡ µé¾î¿Ô´ÂÁö üũ if ( mRangeCheck.IsRange( targetPos, targetPoint ) ) { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } else { NiPoint2 centerPos; centerPos.x = targetPos.x; centerPos.y = targetPos.y; float direction = pAttacker->GetDirection(); float cos = cosf( direction ); float sin = sinf( direction ); /// »ç°¢¹üÀ§ À§Ä¡ °è»ê NiPoint2 rectPos[4]; rectPos[0].x = ( ( -pStepInfo->mBoundDist1 * 0.5f ) * cos + ( +pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[0].y = ( ( +pStepInfo->mBoundDist2 * 0.5f ) * cos - ( -pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[1].x = ( ( -pStepInfo->mBoundDist1 * 0.5f ) * cos + ( -pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[1].y = ( ( -pStepInfo->mBoundDist2 * 0.5f ) * cos - ( -pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[2].x = ( ( +pStepInfo->mBoundDist1 * 0.5f ) * cos + ( -pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[2].y = ( ( -pStepInfo->mBoundDist2 * 0.5f ) * cos - ( +pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[3].x = ( ( +pStepInfo->mBoundDist1 * 0.5f ) * cos + ( +pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[3].y = ( ( +pStepInfo->mBoundDist2 * 0.5f ) * cos - ( +pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[0] = rectPos[0] + centerPos; rectPos[1] = rectPos[1] + centerPos; rectPos[2] = rectPos[2] + centerPos; rectPos[3] = rectPos[3] + centerPos; /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); NiPoint2 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); if( STAGESCRIPT->InsidePolygon( rectPos, 4, targetPoint ) == 1 ) continue; bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { unsigned long* userArr = NULL; unsigned int partyCount = 0; NiPoint2 attackerPos = pAttacker->GetPos(); /// ÆÄƼ¿ø °Ë»ö cParty* pParty = PARTYMAN->GetParty( ((cPlayer*)pAttacker)->GetPartyIndex() ); if( pParty != NULL ) { userArr = pParty->GetUserArr(); partyCount = pParty->GetCount(); } else { cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( ((cPlayer*)pAttacker)->GetPartyUnionIndex() ); if( partyUnion != NULL ) { userArr = partyUnion->GetGroupArr( pAttacker->GetObjectID() ); partyCount = MAX_PARTYUSER; } } /// ÆÄƼ³ª À¯´Ï¿ÂÀÌ ÀÖ´Â °æ¿ì if( userArr != NULL ) { for( unsigned int i = 0 ; i < partyCount ; ++i ) { /// ÆÄƼ°¡ ¾ø´Â °æ¿ì »ç¿ë½Ã¸¦ ó¸®ÇϱâÀ§ÇØ ÀÚ½ÅÀº À§¿¡¼­ ¸ÕÀú ³Ö¾úÀ½ if( pAttacker->GetObjectID() == userArr[i] ) continue; /// Ÿ°Ù °´Ã¼ È®ÀÎ cPlayer* partyUser = OBJECTMANAGER->GetPlayer( userArr[i] ); if( partyUser == NULL ) continue; float tempRange = OBJECTMANAGER->ObjectSizeRange( pAttacker, partyUser, pStepInfo->mBoundDist1 ); /// °Å¸® È®ÀÎ mRangeCheck.SetRadius( tempRange ); if( mRangeCheck.IsRange( attackerPos, partyUser->GetPos() ) == true ) { /// Ÿ°Ù¿¡ Ãß°¡ bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pAttacker->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; /// ±×¸®µå¿¡ ÇØ´çÇÏ´Â Ç÷¹À̾ ¸ðµÎ ÀÐ¾î µ¥¹ÌÁö ¹ß¼ÛÀÚ ¸í´Ü¿¡ ³Ö´Â´Ù. cPlayer* partyUser = GRIDMANAGER->FindFirstPlayer( pAttacker, true ); while( partyUser != NULL ) { mSendMsgSet.Insert( partyUser->GetConnectionIdx() ); partyUser = GRIDMANAGER->FindNextPlayer( true ); } if( resMsg->mCount >= targetMaxCnt ) break; } } } } break; case eAPPLYTYPE_ENEMY: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: { tArray objectIdxAry; if( pStepInfo->mBoundDist2 == 0 ) { /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( pCheckTarget->IsAttack( pAttacker->GetObjectID() ) == false ) continue; } float tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, pCheckTarget, pStepInfo->mBoundDist1 ); mRangeCheck.SetRadius( tempRange ); NiPoint3 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); targetPoint.z = pCheckTarget->Height(); /// Ç÷¹À̾ ¹üÀ§ ¾È¿¡ µé¾î¿Ô´ÂÁö üũ if ( mRangeCheck.IsRange( targetPos, targetPoint ) ) { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } else { NiPoint2 centerPos; centerPos.x = centerPos.x; centerPos.y = centerPos.y; float direction = pAttacker->GetDirection(); float cos = cosf( direction ); float sin = sinf( direction ); /// »ç°¢¹üÀ§ À§Ä¡ °è»ê NiPoint2 rectPos[4]; rectPos[0].x = ( ( -pStepInfo->mBoundDist1 * 0.5f ) * cos + ( +pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[0].y = ( ( +pStepInfo->mBoundDist2 * 0.5f ) * cos - ( -pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[1].x = ( ( -pStepInfo->mBoundDist1 * 0.5f ) * cos + ( -pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[1].y = ( ( -pStepInfo->mBoundDist2 * 0.5f ) * cos - ( -pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[2].x = ( ( +pStepInfo->mBoundDist1 * 0.5f ) * cos + ( -pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[2].y = ( ( -pStepInfo->mBoundDist2 * 0.5f ) * cos - ( +pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[3].x = ( ( +pStepInfo->mBoundDist1 * 0.5f ) * cos + ( +pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[3].y = ( ( +pStepInfo->mBoundDist2 * 0.5f ) * cos - ( +pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[0] = rectPos[0] + centerPos; rectPos[1] = rectPos[1] + centerPos; rectPos[2] = rectPos[2] + centerPos; rectPos[3] = rectPos[3] + centerPos; /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( pCheckTarget->IsAttack( pAttacker->GetObjectID() ) == false ) continue; } NiPoint2 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); if( STAGESCRIPT->InsidePolygon( rectPos, 4, targetPoint ) == 1 ) continue; bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } if( pStepInfo->mBoundDist2 == 0 ) { /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindMonsters( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cMonster* pCheckTarget = OBJECTMANAGER->GetMonster( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; float tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, pCheckTarget, pStepInfo->mBoundDist1 ); mRangeCheck.SetRadius( tempRange ); NiPoint3 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); targetPoint.z = pCheckTarget->Height(); /// Ç÷¹À̾ ¹üÀ§ ¾È¿¡ µé¾î¿Ô´ÂÁö üũ if ( mRangeCheck.IsRange( targetPos, targetPoint ) ) { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } else { NiPoint2 centerPos; centerPos.x = centerPos.x; centerPos.y = centerPos.y; float direction = pAttacker->GetDirection(); float cos = cosf( direction ); float sin = sinf( direction ); /// »ç°¢¹üÀ§ À§Ä¡ °è»ê NiPoint2 rectPos[4]; rectPos[0].x = ( ( -pStepInfo->mBoundDist1 * 0.5f ) * cos + ( +pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[0].y = ( ( +pStepInfo->mBoundDist2 * 0.5f ) * cos - ( -pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[1].x = ( ( -pStepInfo->mBoundDist1 * 0.5f ) * cos + ( -pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[1].y = ( ( -pStepInfo->mBoundDist2 * 0.5f ) * cos - ( -pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[2].x = ( ( +pStepInfo->mBoundDist1 * 0.5f ) * cos + ( -pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[2].y = ( ( -pStepInfo->mBoundDist2 * 0.5f ) * cos - ( +pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[3].x = ( ( +pStepInfo->mBoundDist1 * 0.5f ) * cos + ( +pStepInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[3].y = ( ( +pStepInfo->mBoundDist2 * 0.5f ) * cos - ( +pStepInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[0] = rectPos[0] + centerPos; rectPos[1] = rectPos[1] + centerPos; rectPos[2] = rectPos[2] + centerPos; rectPos[3] = rectPos[3] + centerPos; /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindMonsters( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cMonster* pCheckTarget = OBJECTMANAGER->GetMonster( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; NiPoint2 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); if( STAGESCRIPT->InsidePolygon( rectPos, 4, targetPoint ) == 1 ) continue; bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } break; } } else { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pAttacker->GetObject(), pStepInfo->mInfulenceIdx, skillIdx, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; } /// °ø°ÝÀÚ´Â ¸Þ¼¼Áö¸¦ µû·Î º¸³»´Ï±ñÁö¿î´Ù. mSendMsgSet.Erase( pAttacker->GetConnectionIdx() ); for( unsigned char j = 0 ; j < resMsg->mCount ; ++j ) { if( resMsg->mTarget[j].mTarget.type != eOBJECTTYPE_PLAYER ) continue; cPlayer* pTarget = OBJECTMANAGER->GetPlayer( resMsg->mTarget[j].mTarget.index ); if( pTarget == NULL ) continue; /// Ÿ°ÙÀº ¸Þ¼¼Áö¸¦ µû·Îº¸³»´Ï±ñ Áö¿î´Ù. mSendMsgSet.Erase( pTarget->GetConnectionIdx() ); if( attacker.index == resMsg->mTarget[j].mTarget.index ) continue; HANDLE handle = NULL; MSG_SYN_SKILL_NONSTOP_TARGET* targetMsg = (MSG_SYN_SKILL_NONSTOP_TARGET*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_SKILL, NM_SKILL_NONSTOP_TARGET_SYN ); if ( resMsg != NULL ) { targetMsg->mSkillClassIndex = resMsg->mSkillClassIndex; targetMsg->mAttacker = attacker; targetMsg->mObjectMP = pAttacker->GetMP(); targetMsg->mMaxMP = pAttacker->GetMaxMP(); targetMsg->mTargetApply.mTarget = resMsg->mTarget[j].mTarget; targetMsg->mTargetApply.mInfluenceMiss = resMsg->mTarget[j].mInfluenceMiss; } NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_SKILL_NONSTOP_TARGET) ); } /// ÁÖº¯ Äɸ¯Å͵鿡°Ô´Â ¸ñ·Ï¸¸ ¹ß¼ÛÇÑ´Ù. MSG_SYN_SKILL_NONSTOP_AROUND aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = NM_SKILL_NONSTOP_AROUND_SYN; aroundMsg.mSkillClassIndex = pMsg->mSkillClassIndex; aroundMsg.mAttacker = attacker; aroundMsg.mObjectMP = pAttacker->GetMP(); aroundMsg.mMaxMP = pAttacker->GetMaxMP(); mSendMsgSet.Erase( attacker.index ); cHashSet::cIterator sB = mSendMsgSet.Begin(); cHashSet::cIterator sE = mSendMsgSet.End(); for( ; sB != sE ; ++sB ) { NETWORK2->SendToUser( *sB, (char*)&aroundMsg, sizeof(MSG_SYN_SKILL_NONSTOP_AROUND) ); } NETWORK2->SendMsgRoot( handle, resMsg->GetLength() ); } catch( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_NONSTOP* resMsg = (MSG_RES_SKILL_NONSTOP*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_NONSTOP_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_NONSTOP) ); } } } void cSkillManager::PlayerMonNonStopSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg ) { eMONSTERATTACK_TYPE attackType = (eMONSTERATTACK_TYPE)pMsg->mSkillClassIndex; /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â °ø°ÝÀÚÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long clientIdx = pMsg->mManagedKey; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; mSendMsgSet.Clear(); /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerMonNonStopSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } /// °ø°ÝÀÚ ±×¸®µå¿¡ ÇØ´çÇÏ´Â Ç÷¹À̾ ¸ðµÎ ÀÐ¾î µ¥¹ÌÁö ¹ß¼ÛÀÚ ¸í´Ü¿¡ ³Ö´Â´Ù. cPlayer* pPlayer = GRIDMANAGER->FindFirstPlayer( pAttacker, true ); while( pPlayer != NULL ) { mSendMsgSet.Insert( pPlayer->GetConnectionIdx() ); pPlayer = GRIDMANAGER->FindNextPlayer( true ); } try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ¸ó½ºÅÍ º¯½ÅÁßÀÌ ¾Æ´Ñµ¥ ¸ó½ºÅÍ °ø°ÝÀÌ µé¾î¿Â °æ¿ì - ¸Þ¼¼Áö ½Ã°£Â÷·Î ÀÎÇØ µé¾î¿Ã¼ö ÀÖÀ½ unsigned long monsterClassIdx = pAttacker->GetChgMonsterIdx(); if( monsterClassIdx == 0 ) throw SKILL_USED_ERR_SKILLTYPE; if( attackType >= eMONSTERATTACK_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonNonStopSkillRequest - attackType[%d] > eMONSTERATTACK_MAX", attackType ); throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³index üũ sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, attackType ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerMonNonStopSkillRequest skillScript[%d,%d]", monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } /// ½ºÅ³ »ç¿ë ºÒ°¡ if( attackType > eMONSTERATTACK_NORMAL2 ) { /// ±âº» °ø°ÝÀº Á¦¿ÜÇϰí ó¸®ÇÑ´Ù. if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; } if( pAttacker->GetChgMonsterIdx() == 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( eOBJECTTYPE_NONE, 0 ); /// ¾×Ƽºê ŸÀÓµµ ¾ø´Âµ¥ ÄɽºÆÃÇÒÀÏÀº ¾ø´Ù. if( pSkillInfo->mShotType == eSHOTTYPE_CASTING ) { assert(NULL); NETWORK2->PostServerEvent("PlayerMonNonStopSkillRequest[%d,%d] ShotType == eSHOTTYPE_CASTING[%d]", characterIdx, monsterClassIdx, attackType ); throw SKILL_USED_ERR_SCRIPT; } /// ¼Ò¸ð MP üũ unsigned long useMP = pSkillInfo->mUseMP; if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( pSkillInfo->mUseMP ); } /// ¼Ò¸ð MP if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; NiPoint3 targetPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); cBaseObject* pTarget = NULL; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_SELF_NOTARGET: /// ÀÚ½ÅÀÌ ¹üÀ§ ½ÃÀÛÀ§Ä¡¿©¼­ °Å¸®Ã¼Å© ¾ÈÇÔ { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; } break; case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ case eBOUNDTYPE_SELF_TARGET: /// ½ÃÀüÀÚ(ÀÚ½Å) ±âÁعüÀ§ - ¹ßµ¿½Ã Ÿ°Ù Á¸Àç { /// ÀڽŠÀϰæ¿ì °Å¸®Ã¼Å© ¾ÈÇÔ if( pSkillInfo->mApplyType == eAPPLYTYPE_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; break; } /// Ÿ°ÙÀÌ ÀÖ´Â ½ºÅ³ÀÇ »ç°Å¸®´Â 0ÀÌ µÉ¼ö ¾ø´Ù. - ½ºÅ©¸³Æ® ÀÛ¼º ¿À·ù if( pSkillInfo->mTargetDist == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerMonNonStopSkillRequest[%d] mTargetDist == 0", pMsg->mSkillClassIndex ); throw SKILL_USED_ERR_SCRIPT; } pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); /// Ÿ°Ù °´Ã¼ È®ÀÎ if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); /// Ÿ°Ù »ýÁ¸ À¯¹« üũ if( pTarget->GetStateDie() == true ) throw SKILL_USED_ERR_TARGETOBJECT; /// Ÿ°Ù ŸÀÔ Ã¼Å© switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: break; case eAPPLYTYPE_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type != eOBJECTTYPE_MONSTER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } } break; case eAPPLYTYPE_BUDDY: { /// pvpÀ¯Àú »©ÇؾßÇÔ if( target.type != eOBJECTTYPE_PLAYER ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_DIEBUDDY: case eAPPLYTYPE_BUFF_SELF: // ÇöÀç´Â ¸ó½ºÅÍ º¯½Å ½ºÅ³»ó¿¡¼­´Â »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù [4/6/2010 Jo_Client] case eAPPLYTYPE_DEBUFF_SELF: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { /// ¸ó½ºÅÍ´Â ÆÄƼ³ª Á×Àºµ¿·á¸¦ ¼³Á¤ÇÏÁö ¾Ê´Â´Ù. NETWORK2->PostServerEvent("PlayerMonNonStopSkillRequest mBoundType[%d,%d]", pMsg->mSkillClassIndex, pSkillInfo->mApplyType ); throw SKILL_USED_ERR_SCRIPT; } break; } /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pSkillInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } pAttacker->CalcDirection( pTarget->GetXPos(), pTarget->GetYPos() ); /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); }break; /// ³í½ºÅ¾À¸·Î Çʵ带 ÁöÁ¤Çϸ鼭 ¼³Á¤À» ÇÏÁø ¾Ê´Â´Ù. - ½ºÅ©¸³Æ®¿À·ù case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: default: { assert(NULL); NETWORK2->PostServerEvent("PlayerMonNonStopSkillRequest mBoundType[%d,%d]", pMsg->mSkillClassIndex, pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } if( pAttacker->IsChgMonCoolTimeEnd( attackType ) == false ) { throw SKILL_USED_ERR_COOLTIME; } /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// ij½ºÆÃÀÌ ¾Æ´Ñ °æ¿ì ¹ßµ¿ üũ /// *** ij½ºÆÃÀÎ °æ¿ì´Â skillObjÀÇ RequireValue() ¿¡¼­ üũ *** switch( pSkillInfo->mType ) { case eMONSTERSKILLTYPE_DAMAGE: case eMONSTERSKILLTYPE_MPDAMAGE: CheckActInfluence( eACTSTATUS_ACTIVESKILL, pAttacker, pTarget ); break; case eMONSTERSKILLTYPE_HEAL: CheckActInfluence( eACTSTATUS_HEALSKILL, pAttacker, pTarget ); break; } /// ½ºÅ³ ¹ßµ¿ È¿°ú if( pSkillInfo->mActiveIdx != 0 ) SKILLMANAGER->CheckSkillActInfluence( pSkillInfo->mActiveIdx, pAttacker, pTarget ); /// ÄðŸÀÓ °»½Å pAttacker->UpdateChgMonCoolTime( attackType ); unsigned char targetMaxCnt = pSkillInfo->mApplyCnt; if( targetMaxCnt == 0 || targetMaxCnt > TARGET_CNT_MAX ) targetMaxCnt = TARGET_CNT_MAX; else { /// Àû¿ë ÀοøÀÌ Á¦ÇÑµÈ °æ¿ì °ø°ÝÀÚ°¡ ¹üÀ§ ½ºÅ³ Àû¿ë Àοø Áõ°¡ È¿°ú¿¡ °É·ÁÀÖ´ÂÁö üũ ÇÏ¿© ³Ö±â if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER || pAttacker->GetObjectType() == eOBJECTTYPE_MONSTER ) { long addApplyCnt = (long)pAttacker->GetStateOddity( eODDITYTYPE_ADD_APPLY_CNT ); if( addApplyCnt > 0 ) { if( (addApplyCnt + targetMaxCnt) > UCHAR_MAX ) { assert(0); targetMaxCnt = TARGET_CNT_MAX; } else { targetMaxCnt = targetMaxCnt + (unsigned char)addApplyCnt; if ( targetMaxCnt > TARGET_CNT_MAX ) { assert(0); targetMaxCnt = TARGET_CNT_MAX; } } } } } /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_NONSTOP* resMsg = (MSG_RES_SKILL_NONSTOP*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_NONSTOP_MON_RES ); if ( resMsg == NULL ) throw SKILL_USED_ERR_OBJECTINIT; resMsg->mSkillClassIndex = pMsg->mSkillClassIndex; resMsg->mManagedKey = pMsg->mManagedKey; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); resMsg->mCount = 0; /// Ÿ°Ù ¼±Á¤ if( pSkillInfo->mBoundType != eBOUNDTYPE_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pAttacker->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; } break; case eAPPLYTYPE_BUDDY: { tArray objectIdxAry; if( pSkillInfo->mBoundDist2 == 0 ) { /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); float tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, pCheckTarget, pSkillInfo->mBoundDist1 ); mRangeCheck.SetRadius( tempRange ); NiPoint3 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); targetPoint.z = pCheckTarget->Height(); /// Ç÷¹À̾ ¹üÀ§ ¾È¿¡ µé¾î¿Ô´ÂÁö üũ if ( mRangeCheck.IsRange( targetPos, targetPoint ) ) { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } else { NiPoint2 centerPos; centerPos.x = targetPos.x; centerPos.y = targetPos.y; float direction = pAttacker->GetDirection(); float cos = cosf( direction ); float sin = sinf( direction ); /// »ç°¢¹üÀ§ À§Ä¡ °è»ê NiPoint2 rectPos[4]; rectPos[0].x = ( ( -pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( +pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[0].y = ( ( +pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( -pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[1].x = ( ( -pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( -pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[1].y = ( ( -pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( -pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[2].x = ( ( +pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( -pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[2].y = ( ( -pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( +pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[3].x = ( ( +pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( +pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[3].y = ( ( +pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( +pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[0] = rectPos[0] + centerPos; rectPos[1] = rectPos[1] + centerPos; rectPos[2] = rectPos[2] + centerPos; rectPos[3] = rectPos[3] + centerPos; /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); NiPoint2 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); if( STAGESCRIPT->InsidePolygon( rectPos, 4, targetPoint ) == 1 ) continue; bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } break; case eAPPLYTYPE_ENEMY: { tArray objectIdxAry; if( pSkillInfo->mBoundDist2 == 0 ) { /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( pCheckTarget->IsAttack( pAttacker->GetObjectID() ) == false ) continue; } float tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, pCheckTarget, pSkillInfo->mBoundDist1 ); mRangeCheck.SetRadius( tempRange ); NiPoint3 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); targetPoint.z = pCheckTarget->Height(); /// Ç÷¹À̾ ¹üÀ§ ¾È¿¡ µé¾î¿Ô´ÂÁö üũ if ( mRangeCheck.IsRange( targetPos, targetPoint ) ) { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } else { NiPoint2 centerPos; centerPos.x = centerPos.x; centerPos.y = centerPos.y; float direction = pAttacker->GetDirection(); float cos = cosf( direction ); float sin = sinf( direction ); /// »ç°¢¹üÀ§ À§Ä¡ °è»ê NiPoint2 rectPos[4]; rectPos[0].x = ( ( -pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( +pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[0].y = ( ( +pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( -pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[1].x = ( ( -pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( -pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[1].y = ( ( -pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( -pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[2].x = ( ( +pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( -pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[2].y = ( ( -pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( +pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[3].x = ( ( +pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( +pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[3].y = ( ( +pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( +pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[0] = rectPos[0] + centerPos; rectPos[1] = rectPos[1] + centerPos; rectPos[2] = rectPos[2] + centerPos; rectPos[3] = rectPos[3] + centerPos; /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindPlayers( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cPlayer* pCheckTarget = OBJECTMANAGER->GetPlayer( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; mSendMsgSet.Insert( pCheckTarget->GetConnectionIdx() ); if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( pCheckTarget->IsAttack( pAttacker->GetObjectID() ) == false ) continue; } NiPoint2 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); if( STAGESCRIPT->InsidePolygon( rectPos, 4, targetPoint ) == 1 ) continue; bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } if( pSkillInfo->mBoundDist2 == 0 ) { /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindMonsters( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cMonster* pCheckTarget = OBJECTMANAGER->GetMonster( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; float tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, pCheckTarget, pSkillInfo->mBoundDist1 ); mRangeCheck.SetRadius( tempRange ); NiPoint3 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); targetPoint.z = pCheckTarget->Height(); /// Ç÷¹À̾ ¹üÀ§ ¾È¿¡ µé¾î¿Ô´ÂÁö üũ if ( mRangeCheck.IsRange( targetPos, targetPoint ) ) { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } else { NiPoint2 centerPos; centerPos.x = centerPos.x; centerPos.y = centerPos.y; float direction = pAttacker->GetDirection(); float cos = cosf( direction ); float sin = sinf( direction ); /// »ç°¢¹üÀ§ À§Ä¡ °è»ê NiPoint2 rectPos[4]; rectPos[0].x = ( ( -pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( +pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[0].y = ( ( +pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( -pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[1].x = ( ( -pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( -pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[1].y = ( ( -pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( -pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[2].x = ( ( +pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( -pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[2].y = ( ( -pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( +pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[3].x = ( ( +pSkillInfo->mBoundDist1 * 0.5f ) * cos + ( +pSkillInfo->mBoundDist2 * 0.5f ) * sin ); rectPos[3].y = ( ( +pSkillInfo->mBoundDist2 * 0.5f ) * cos - ( +pSkillInfo->mBoundDist1 * 0.5f ) * sin ); rectPos[0] = rectPos[0] + centerPos; rectPos[1] = rectPos[1] + centerPos; rectPos[2] = rectPos[2] + centerPos; rectPos[3] = rectPos[3] + centerPos; /// Áß½ÉÀ§Ä¡·Î °Ë»öÇϵµ·Ï ¹Ù²ã¾ß ÇÑ´Ù GRIDMANAGER->FindMonsters( pTarget, &objectIdxAry ); for( unsigned long i = 0 ; i < objectIdxAry.GetSize() ; ++i ) { cMonster* pCheckTarget = OBJECTMANAGER->GetMonster( objectIdxAry[i] ); if( pCheckTarget == NULL || pCheckTarget->GetStateDie() == true ) continue; NiPoint2 targetPoint; targetPoint.x = pCheckTarget->GetXPos(); targetPoint.y = pCheckTarget->GetYPos(); if( STAGESCRIPT->InsidePolygon( rectPos, 4, targetPoint ) == 1 ) continue; bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pCheckTarget->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; if( resMsg->mCount >= targetMaxCnt ) break; } } } break; /* ///ÇöÀç´Â ¸ó½ºÅÍ º¯½Å ½ºÅ³»ó¿¡¼­´Â »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù. case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: */ } } else { bool isInf = SKILLMANAGER->AddInfluence( pAttacker->GetObject(), pAttacker->GetObject(), pSkillInfo->mInfulenceIdx, pMsg->mSkillClassIndex, true ); resMsg->mTarget[resMsg->mCount].mTarget = pAttacker->GetObject(); resMsg->mTarget[resMsg->mCount].mInfluenceMiss = isInf == false; ++resMsg->mCount; } mSendMsgSet.Erase( pAttacker->GetConnectionIdx() ); for( unsigned char j = 0 ; j < resMsg->mCount ; ++j ) { if( resMsg->mTarget[j].mTarget.type != eOBJECTTYPE_PLAYER ) continue; cPlayer* pTarget = OBJECTMANAGER->GetPlayer( resMsg->mTarget[j].mTarget.index ); if( pTarget == NULL ) continue; mSendMsgSet.Erase( pTarget->GetConnectionIdx() ); HANDLE handle = NULL; MSG_SYN_SKILL_NONSTOP_TARGET* targetMsg = (MSG_SYN_SKILL_NONSTOP_TARGET*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_SKILL, NM_SKILL_NONSTOP_MON_TARGET_SYN ); if ( resMsg == NULL ) { targetMsg->mSkillClassIndex = resMsg->mSkillClassIndex; targetMsg->mAttacker = attacker; targetMsg->mObjectMP = pAttacker->GetMP(); targetMsg->mMaxMP = pAttacker->GetMaxMP(); targetMsg->mTargetApply = resMsg->mTarget[j]; } NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_SKILL_NONSTOP_TARGET) ); } /// ÁÖº¯ Äɸ¯Å͵鿡°Ô´Â ¸ñ·Ï¸¸ ¹ß¼ÛÇÑ´Ù. MSG_SYN_SKILL_NONSTOP_AROUND aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = NM_SKILL_NONSTOP_MON_AROUND_SYN; aroundMsg.mSkillClassIndex = pMsg->mSkillClassIndex; aroundMsg.mAttacker = attacker; aroundMsg.mObjectMP = pAttacker->GetMP(); aroundMsg.mMaxMP = pAttacker->GetMaxMP(); mSendMsgSet.Erase( attacker.index ); cHashSet::cIterator sB = mSendMsgSet.Begin(); cHashSet::cIterator sE = mSendMsgSet.End(); for( ; sB != sE ; ++sB ) { NETWORK2->SendToUser( *sB, (char*)&aroundMsg, sizeof(MSG_SYN_SKILL_NONSTOP_AROUND) ); } NETWORK2->SendMsgRoot( handle, resMsg->GetLength() ); } catch( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_NONSTOP* resMsg = (MSG_RES_SKILL_NONSTOP*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_NONSTOP_MON_RES ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = pMsg->mSkillClassIndex; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_NONSTOP) ); } } } void cSkillManager::PlayerRushSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg, bool blink ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â °ø°ÝÀÚÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned char skillStep = pMsg->mSkillStep; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ùaa if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } char protocol = NM_SKILL_RUSH_RES; char syncProtocol = NM_SKILL_RUSH_SYN; if( blink == true ) { protocol = NM_SKILL_RUSHBLINK_RES; syncProtocol = NM_SKILL_RUSHBLINK_SYN; } try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ±âº» °ø°Ý ½ºÅ³ À妽ºÀΰæ¿ì ¿À·ù if( skillIdx <= NORMAL_ATTACK_SKILL_MAX ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest - skillIdx[%d] > NORMAL_ATTACK_SKILL_MAX", skillIdx ); throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } if( blink == true ) { if( pSkillInfo->mShotType != eSHOTTYPE_RUSHBLINK ) throw SKILL_USED_ERR_SKILLTYPE; } else { if( pSkillInfo->mShotType != eSHOTTYPE_RUSHRUN ) throw SKILL_USED_ERR_SKILLTYPE; } /// ½ºÅ³ »ç¿ë ºÒ°¡ if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ÀÌ¹Ì ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( eOBJECTTYPE_NONE, 0 ); /// ¾×Ƽºê ½ºÅ³ÀÌ ¾Æ´Ñ °æ¿ì if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest eSKILLTYPE_PASSIVE[%d,%d]", skillIdx, pSkillInfo->mType ); throw SKILL_USED_ERR_PASSIVE; } /// ¾×Ƽºê ŸÀÓµµ ¾ø´Âµ¥ ÄɽºÆÃÇÒÀÏÀº ¾ø´Ù. if( pSkillInfo->mShotType == eSHOTTYPE_CASTING ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest[%d,%d] ShotType == eSHOTTYPE_CASTING", attacker.index, pMsg->mSkillClassIndex ); throw SKILL_USED_ERR_SCRIPT; } /// °ø°ÝÀÚÀÇ º¸À¯½ºÅ³ÀÎÁö üũ cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( attacker.index, skillIdx ); if( !pPlayerHaveSkill ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest GetPlayerHaveSkill[%d,%d]", attacker.index, skillIdx ); throw SKILL_USED_ERR_DONTHAVE; } /// ½ºÅ³ ½ºÅ©¸³Æ® ½ºÅÜÁ¤º¸ Àоî¿È unsigned int stepIdx = pPlayerHaveSkill->GetSkillStep(); if( stepIdx < skillStep ) { NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest stepIdx >= pSkillInfo->mStepCount [%d,%d,(%d >= %d)]", attacker.index, skillIdx, stepIdx, pSkillInfo->mStepCount ); throw SKILL_USED_ERR_DONTHAVE; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[skillStep]; /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ bool IsEquipment = true; if( pSkillInfo->mUseEquipment ) { eWEAPON_STATE weaponState = pAttacker->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pSkillInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) IsEquipment = false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) IsEquipment = false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_CLOTH: if( pAttacker->GetArmorSets() != ARMOR_SETS_ROBES ) IsEquipment = false; break; case eEQUIPTYPE_LIGHTARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_LIGHT ) IsEquipment = false; break; case eEQUIPTYPE_HEAVYARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_HEAVY ) IsEquipment = false; break; } } if( IsEquipment == false ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest IsEquipment == false" ); throw SKILL_USED_ERR_EQUIPMENT; } /// ij¸¯ÅÍ »óÅ if( pSkillInfo->mUseState != eSKILL_USE_STATE_NONE ) // ¸ðµÎ { switch( pSkillInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // HPUP if( pStepInfo->mUseStateValue > ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_HP_PER_DOWN: // HPDONW: if( pStepInfo->mUseStateValue < ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_UP: // MPUP: if( pStepInfo->mUseStateValue > ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_DOWN: // MPDOWN: if( pStepInfo->mUseStateValue < ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_BUFF: // if( pAttacker->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_DEBUFF: // MPDOWN: if( pAttacker->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; default: assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest pSkillInfo->mUseState[%d]", pSkillInfo->mUseState ); throw SKILL_USED_ERR_SCRIPT; } } unsigned long useMP = pStepInfo->mUseMP; if( pStepInfo->mUseMPPer != 0 ) useMP += pAttacker->GetOriMPMax() * pStepInfo->mUseMPPer / 100; /// ¼Ò¸ð MP üũ if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( useMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð HP if( pStepInfo->mUseHP >= pAttacker->GetHP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->IsItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) throw SKILL_USED_ERR_USEVALUE; } NiPoint3 targetPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); cBaseObject* pTarget = NULL; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ { /// Ÿ°ÙÀÌ ÀÖ´Â ½ºÅ³ÀÇ »ç°Å¸®´Â 0ÀÌ µÉ¼ö ¾ø´Ù. - ½ºÅ©¸³Æ® ÀÛ¼º ¿À·ù if( pStepInfo->mTargetDist == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "cSkillManager::PlayerRushSkillRequest[%d] mTargetDist == 0", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); /// Ÿ°Ù °´Ã¼ È®ÀÎ if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); /// Ÿ°Ù »ýÁ¸ À¯¹« üũ if( pTarget->GetStateDie() == true ) throw SKILL_USED_ERR_TARGETOBJECT; /// Ÿ°Ù ŸÀÔ Ã¼Å© switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: break; case eAPPLYTYPE_ENEMY: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type != eOBJECTTYPE_MONSTER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } } break; case eAPPLYTYPE_BUDDY: { /// pvpÀ¯Àú »©ÇؾßÇÔ if( target.type != eOBJECTTYPE_PLAYER ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) break; bool isParty = false; /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÎÁö üũ cParty* pParty = PARTYMAN->GetParty( ((cPlayer*)pAttacker)->GetPartyIndex() ); if( pParty && pParty->IsUser( target.index ) ) { isParty = true; } else { /// ÆÄƼ¿¬ÇÕÀÎÁö üũ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( ((cPlayer*)pAttacker)->GetPartyUnionIndex() ); if( partyUnion && partyUnion->IsUser( pAttacker->GetObjectID(), target.index ) ) { isParty = true; } } /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÌ ¾Æ´Ñ °æ¿ì if( isParty == false ) throw SKILL_USED_ERR_TARGETSELECT; } break; } /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( pStepInfo->mTargetDist + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } pAttacker->CalcDirection( pTarget->GetXPos(), pTarget->GetYPos() ); /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); }break; /// ³í½ºÅ¾À¸·Î Çʵ带 ÁöÁ¤Çϸ鼭 ¼³Á¤À» ÇÏÁø ¾Ê´Â´Ù. - ½ºÅ©¸³Æ®¿À·ù case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: default: { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushSkillRequest mBoundType[%d,%d]", skillIdx, pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ if( pSkillInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_BUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; }//end switch( pSkillInfo->mApplyType ) } /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } unsigned long currentTime = NETWORK2->GetAccumTime(); /// ÄðŸÀÓ if( pStepInfo->mCoolTime != 0 && pPlayerHaveSkill->GetEndCoolTime() > currentTime ) { pAttacker->SkillCoolTimeFailPlus(); throw SKILL_USED_ERR_COOLTIME; } if( pAttacker->IsMovePossible( pAttacker->GetPos(), pTarget->GetPos() ) != 0 ) throw SKILL_USED_ERR_RUSH_OBSTRUCTION; /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// HP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( pStepInfo->mUseHP != 0 ) { /// HP ¼Ò¸ð & ¸Þ¼¼Áö ¹ß¼Û pAttacker->HPUse( pStepInfo->mUseHP, true ); } /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->ItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) { assert(NULL); NETWORK2->PostServerEvent("ERROR - item use skill itemidx[%d], itemcnd[%d]", pSkillInfo->mUseItem, pStepInfo->mUseItemCount ); } } /// ÄðŸÀÓ °»½Å SKILLMANAGER->UpdateSkillCoolTime( attacker, pMsg->mSkillClassIndex, (unsigned char)stepIdx, NETWORK2->GetAccumTime(), 1.0f ); unsigned char targetMaxCnt = pStepInfo->mApplyCnt; if( targetMaxCnt == 0 || targetMaxCnt > TARGET_CNT_MAX ) targetMaxCnt = TARGET_CNT_MAX; else { /// Àû¿ë ÀοøÀÌ Á¦ÇÑµÈ °æ¿ì °ø°ÝÀÚ°¡ ¹üÀ§ ½ºÅ³ Àû¿ë Àοø Áõ°¡ È¿°ú¿¡ °É·ÁÀÖ´ÂÁö üũ ÇÏ¿© ³Ö±â if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER || pAttacker->GetObjectType() == eOBJECTTYPE_MONSTER ) { long addApplyCnt = (long)pAttacker->GetStateOddity( eODDITYTYPE_ADD_APPLY_CNT ); if( addApplyCnt > 0 ) { if( (addApplyCnt + targetMaxCnt) > UCHAR_MAX ) { assert(0); targetMaxCnt = TARGET_CNT_MAX; } else { targetMaxCnt = targetMaxCnt + (unsigned char)addApplyCnt; if ( targetMaxCnt > TARGET_CNT_MAX ) { assert(0); targetMaxCnt = TARGET_CNT_MAX; } } } } } unsigned long nextSkill = SKILLSCRIPT->GetBridgeSkillMap( pMsg->mSkillClassIndex, skillStep ); /// µ¹Áø ¼³Á¤ NiPoint2 sendPos = pAttacker->SetSkillRush( pTarget, blink, nextSkill, (unsigned char)skillStep ); HANDLE handle = NULL; MSG_RES_SKILL_RUSH* resMsg = (MSG_RES_SKILL_RUSH*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, protocol ); if ( resMsg == NULL ) throw SKILL_USED_ERR_OBJECTINIT; resMsg->mSkillClassIndex = pMsg->mSkillClassIndex; resMsg->mNextSkill = nextSkill; resMsg->mNextStep = (unsigned char)skillStep; resMsg->mManagedKey = pMsg->mManagedKey; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); resMsg->mTarget = pTarget->GetObject(); resMsg->mPosX = sendPos.x; resMsg->mPosY = sendPos.y; resMsg->mBlink = blink; NETWORK2->SendMsgRoot( handle, sizeof( MSG_RES_SKILL_RUSH ) ); /// ÁÖº¯ Äɸ¯Å͵鿡°Ô´Â ¸ñ·Ï¸¸ ¹ß¼ÛÇÑ´Ù. MSG_SYN_SKILL_RUSH aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = syncProtocol; aroundMsg.mSkillClassIndex = pMsg->mSkillClassIndex; aroundMsg.mAttacker = attacker; aroundMsg.mObjectMP = pAttacker->GetMP(); aroundMsg.mMaxMP = pAttacker->GetMaxMP(); aroundMsg.mTarget = pTarget->GetObject(); aroundMsg.mPosX = sendPos.x; aroundMsg.mPosY = sendPos.y; aroundMsg.mBlink = blink; NETWORK2->QuickSendExcept( pAttacker, (char*)&aroundMsg, sizeof( MSG_SYN_SKILL_RUSH ) ); } catch( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_RUSH* resMsg = (MSG_RES_SKILL_RUSH*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, protocol ); if ( resMsg != NULL ) { resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_RUSH) ); } } } void cSkillManager::PlayerRushAfterSkillRequest( unsigned long characterIdx, MSG_REQ_SKILL_USED* pMsg ) { /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº Ç÷¹ÀÌ¾î »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_PLAYER, characterIdx }; sObject target = pMsg->mTarget; unsigned long skillIdx = pMsg->mSkillClassIndex; unsigned long clientIdx = pMsg->mManagedKey; unsigned char skillStep = pMsg->mSkillStep; /// ¼­¹ö¿¡´Â hero°¡ ¾ø´Ù if( target.type == eOBJECTTYPE_HERO ) target.type = eOBJECTTYPE_PLAYER; /// °ø°ÝÀÚ °´Ã¼ üũ cPlayer* pAttacker = (cPlayer*)OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("PlayerObjectSkillRequest - GetObject( %d, %d )", attacker.type, attacker.index ); assert(NULL); return; } pAttacker->MoveStop(); pAttacker->SkillReqCntPlus(); try { if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ±âº» °ø°Ý ½ºÅ³ À妽ºÀΰæ¿ì ¿À·ù if( skillIdx <= NORMAL_ATTACK_SKILL_MAX ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest - skillIdx[%d] > NORMAL_ATTACK_SKILL_MAX", skillIdx ); throw SKILL_USED_ERR_SKILLTYPE; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_ATTACK, eCHANGESTATEOPTION_RUSH ) == false ) throw SKILL_USED_ERR_ATTACKERSTATE; /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest skillScript[%d]", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ½ºÅ³ »ç¿ë ºÒ°¡ if( pAttacker->IsCantSkill( pSkillInfo->mAttributeType ) == true ) throw SKILL_USED_ERR_USEVALUE; if( pAttacker->GetChgMonsterIdx() != 0 ) throw SKILL_USED_ERR_CHG_MONSTER; /// ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) throw SKILL_USED_ERR_USING; if( pSkillInfo->mShotType == eSHOTTYPE_CASTING ) { NETWORK2->PostServerEvent("PlayerObjectSkillRequest[%d] ShotType != eSHOTTYPE_CASTING[%d]", characterIdx, skillIdx ); throw SKILL_USED_ERR_SCRIPT; } /// ¾×Ƽºê ½ºÅ³ÀÌ ¾Æ´Ñ °æ¿ì if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest eSKILLTYPE_PASSIVE[%d,%d]", skillIdx, pSkillInfo->mType ); throw SKILL_USED_ERR_PASSIVE; } /// ½ºÅ³ ½ºÅ©¸³Æ® ½ºÅÜÁ¤º¸ Àоî¿È unsigned int stepIdx = pMsg->mSkillStep; if( stepIdx >= pSkillInfo->mStepCount ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::PlayerRushAfterSkillRequest stepIdx >= pSkillInfo->mStepCount [%d,%d,(%d >= %d)]", attacker.index, skillIdx, stepIdx, pSkillInfo->mStepCount ); throw SKILL_USED_ERR_DONTHAVE; } sPlayerSkillStepInfo* pStepInfo = &pSkillInfo->mpSetpInfoArray[pMsg->mSkillStep]; /// µ¹ÁøÈÄ À̾îÁö´Â ½ºÅ³Àº µ¹Áø¿¡¼­ ¼³Á¤µÈ °ªÀ» üũÈÄ »ç¿ë ÇÑ´Ù. if( pAttacker->GetRushAfterSkillIdx() != skillIdx ) throw SKILL_USED_ERR_DONTHAVE; if( pAttacker->GetRushAfterSkillStep() != stepIdx ) throw SKILL_USED_ERR_DONTHAVE; /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ bool IsEquipment = true; if( pSkillInfo->mUseEquipment ) { eWEAPON_STATE weaponState = pAttacker->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pSkillInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) IsEquipment = false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) IsEquipment = false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) IsEquipment = false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) IsEquipment = false; break; case eEQUIPTYPE_CLOTH: if( pAttacker->GetArmorSets() != ARMOR_SETS_ROBES ) IsEquipment = false; break; case eEQUIPTYPE_LIGHTARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_LIGHT ) IsEquipment = false; break; case eEQUIPTYPE_HEAVYARMOR: if( pAttacker->GetArmorSets() != ARMOR_SETS_HEAVY ) IsEquipment = false; break; } } if( IsEquipment == false ) { assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest IsEquipment == false" ); throw SKILL_USED_ERR_EQUIPMENT; } /// ij¸¯ÅÍ »óÅ if( pSkillInfo->mUseState != eSKILL_USE_STATE_NONE ) // ¸ðµÎ { if( pAttacker->GetMaxHP() == 0 ) { NETWORK2->PostServerEvent("0 divide 1"); throw SKILL_USED_ERR_USEVALUE; } if( pAttacker->GetMaxMP() == 0 ) { NETWORK2->PostServerEvent("0 divide 2"); throw SKILL_USED_ERR_USEVALUE; } switch( pSkillInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // HPUP if( pStepInfo->mUseStateValue > ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_HP_PER_DOWN: // HPDONW: if( pStepInfo->mUseStateValue < ( pAttacker->GetHP() * PERCENT_HUNDRED / pAttacker->GetMaxHP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_UP: // MPUP: if( pStepInfo->mUseStateValue > ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_MP_PER_DOWN: // MPDOWN: if( pStepInfo->mUseStateValue < ( pAttacker->GetMP() * PERCENT_HUNDRED / pAttacker->GetMaxMP() ) ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_BUFF: // if( pAttacker->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; case eSKILL_USE_STATE_SELF_DEBUFF: // MPDOWN: if( pAttacker->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) { throw SKILL_USED_ERR_USEVALUE; }break; default: assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest pSkillInfo->mUseState[%d]", pSkillInfo->mUseState ); throw SKILL_USED_ERR_SCRIPT; } } unsigned long useMP = pStepInfo->mUseMP; if( pStepInfo->mUseMPPer != 0 ) useMP += pAttacker->GetOriMPMax() * pStepInfo->mUseMPPer / 100; /// ¼Ò¸ð MP üũ if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( useMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð HP ¼öÄ¡ üũ if( pStepInfo->mUseHP >= pAttacker->GetHP() ) throw SKILL_USED_ERR_USEVALUE; /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->IsItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) throw SKILL_USED_ERR_USEVALUE; } cBaseObject* pTarget = NULL; NiPoint3 targetPos = NiPoint3::ZERO; /// Ÿ°Ù »ç°Å¸® üũ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_SELF_NOTARGET: /// ÀÚ½ÅÀÌ ¹üÀ§ ½ÃÀÛÀ§Ä¡¿©¼­ °Å¸®Ã¼Å© ¾ÈÇÔ { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; } break; case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ case eBOUNDTYPE_SELF_TARGET: /// ½ÃÀüÀÚ(ÀÚ½Å) ±âÁعüÀ§ - ¹ßµ¿½Ã Ÿ°Ù Á¸Àç { /// ÀڽŠÀϰæ¿ì °Å¸®Ã¼Å© ¾ÈÇÔ if( pSkillInfo->mApplyType == eAPPLYTYPE_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pSkillInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) { /// ÀÚ½ÅÀ» Ÿ°ÙÀ¸·Î ¼±Á¤ target = attacker; targetPos.x = pAttacker->GetXPos(); targetPos.y = pAttacker->GetYPos(); targetPos.z = pAttacker->Height(); pTarget = pAttacker; break; } /// Ÿ°ÙÀÌ ÀÖ´Â ½ºÅ³ÀÇ »ç°Å¸®´Â 0ÀÌ µÉ¼ö ¾ø´Ù. - ½ºÅ©¸³Æ® ÀÛ¼º ¿À·ù if( pStepInfo->mTargetDist == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerObjectSkillRequest[%d] mTargetDist == 0", skillIdx ); throw SKILL_USED_ERR_SCRIPT; } pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); /// Ÿ°Ù °´Ã¼ È®ÀÎ if( pTarget == NULL ) throw SKILL_USED_ERR_TARGETOBJECT; targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); /// ºÎȰ ½ºÅ³ÀÎÁö üũ bool isResurrection = false; if( pSkillInfo->mApplyType == eAPPLYTYPE_DIEBUDDY ) { isResurrection = true; if( NETWORK2->GetServerType() == _E_ST_ID_PVP_ ) throw SKILL_USED_ERR_TARGETSELECT; } /// Ÿ°Ù »ýÁ¸ À¯¹« üũ if( pTarget->GetStateDie() == true && isResurrection == false ) throw SKILL_USED_ERR_TARGETOBJECT; else if( pTarget->GetStateDie() == false && isResurrection == true ) throw SKILL_USED_ERR_TARGETOBJECT; /// Ÿ°Ù ŸÀÔ Ã¼Å© switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: break; case eAPPLYTYPE_ENEMY: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { unsigned long attackerTeamType = pAttacker->GetPvPDMTeam(); if( ePVPDM_TEAMTYPE_MAX != attackerTeamType ) { if( attackerTeamType == ((cMonster*)pTarget)->GetDMTeamType() ) throw SKILL_USED_ERR_TARGETSELECT; } } else if( target.type == eOBJECTTYPE_PLAYER ) { if( pAttacker->IsAttack( target.index ) == false ) throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUDDY: { /// pvpÀ¯Àú »©ÇؾßÇÔ if( target.type != eOBJECTTYPE_PLAYER ) throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_PARTY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) break; bool isParty = false; /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÎÁö üũ cParty* pParty = PARTYMAN->GetParty( ((cPlayer*)pAttacker)->GetPartyIndex() ); if( pParty && pParty->IsUser( target.index ) ) { isParty = true; } else { /// ÆÄƼ¿¬ÇÕÀÎÁö üũ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( ((cPlayer*)pAttacker)->GetPartyUnionIndex() ); if( partyUnion && partyUnion->IsUser( pAttacker->GetObjectID(), target.index ) ) { isParty = true; } } /// Ÿ°ÙÀÌ ÆÄƼ¿øÀÌ ¾Æ´Ñ °æ¿ì if( isParty == false ) throw SKILL_USED_ERR_TARGETSELECT; } break; } /// ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® float range = pAttacker->CalcStatusSkillRange( pStepInfo->mTargetDist, pSkillInfo->mRangeType, false ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range + SYNC_MOVE_RANGE ); NiPoint3 attackerPos( pAttacker->GetXPos(), pAttacker->GetYPos(), pAttacker->Height() ); if( !skillRangeCheck.IsRange( attackerPos, targetPos ) ) { HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_TARGETDIST; } pAttacker->CalcDirection( pTarget->GetXPos(), pTarget->GetYPos() ); /// °ø°ÝÀÚ¿¡°Ô Ÿ°ÙÀ» ¼³Á¤ÇÑ´Ù pAttacker->SetTarget( target.type, target.index ); }break; /// ÇʵåÀΰæ¿ì´Â ÀÌÇÔ¼ö¿¡ µé¾î¿Ã¼ö ¾øÀ½ case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: default: { /// ½ºÅ©¸³Æ® ³»¿ëÀÌ À߸øµÆ´Ù. assert(NULL); NETWORK2->PostServerEvent("PlayerObjectSkillRequest mBoundType[%d,%d]", skillIdx, pSkillInfo->mBoundType ); throw SKILL_USED_ERR_SCRIPT; } } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ if( pSkillInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } break; case eAPPLYTYPE_BUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( target.type == eOBJECTTYPE_MONSTER ) { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cMonster*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else if( target.type == eOBJECTTYPE_PLAYER ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pTarget ) { if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_BUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; case eAPPLYTYPE_DEBUFF_PARTY: { /// ÀÚ½ÅÀº ¹«Á¶°Ç °¡´É if( target.index == pAttacker->GetObjectID() && target.type == pAttacker->GetObjectType() ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( pAttacker->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; else break; } if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( ((cPlayer*)pTarget)->IsHaveApplyDeBuffType( pSkillInfo->mApplyValueType ) == false ) throw SKILL_USED_ERR_APPLYVALUE_STATE; } else throw SKILL_USED_ERR_TARGETSELECT; } break; }//end switch( pSkillInfo->mApplyType ) } /// Ç÷¹À̾ ¸ñÀûÁö¿¡ µµÂøÇϱâÀü¿¡ °ø°Ý¸Þ¼¼Áö°¡ µé¾î¿À´Â °æ¿ì Çã¿ë¹üÀ§ °è»ê mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); NiPoint2 clientPos( pMsg->mClientPosX, pMsg->mClientPosY ); NiPoint2 serverPos = pAttacker->GetPos(); if( mRangeCheck.IsRange( serverPos, clientPos ) == false ) { /// À̵¿ ÁßÀÌ´ø »óÅ Á¤Áö pAttacker->SetMoveTargetPos( serverPos.x, serverPos.y ); pAttacker->ClearMoveSyncCalc(); HANDLE handle = NULL; MSG_RES_SKILL_POS* posMsg = (MSG_RES_SKILL_POS*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx( ), NM_SKILL, NM_SKILL_USED_POS_ERROR_RES ); if ( posMsg != NULL ) { posMsg->mAttacker = attacker; posMsg->mAttackerPosX = pAttacker->GetXPos( ); posMsg->mAttackerPosY = pAttacker->GetYPos( ); posMsg->mTarget = target; posMsg->mTargetPosX = targetPos.x; posMsg->mTargetPosY = targetPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_POS) ); } throw SKILL_USED_ERR_ATTAKCERPOS; } /// °íÀ¯Å° »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "PlayerObjectSkillRequest GeneratIdx[%d]", skillUniqueIdx ); throw SKILL_USED_ERR_UNIQUEIDX; } /// ½ºÅ³ °´Ã¼ »ý¼º cPlayerSkillObject* pSkillObject = new cPlayerSkillObject; bool init = pSkillObject->InitRushAfterSkill( skillIdx, skillStep, skillUniqueIdx, pAttacker, pTarget, pStepInfo->mCastingTime ); if( init == false ) { /// ½ºÅ³ °´Ã¼ »ý¼º ½ÇÆÐ assert(NULL); SAFE_DELETE( pSkillObject ); NETWORK2->PostServerEvent( "PlayerObjectSkillRequest new SkillObject" ); throw SKILL_USED_ERR_OBJECTINIT; } /// Ç÷¹À̾îÀÇ »óÅ üũÇÑ´Ù. if( pAttacker->ChangeState( eOBJECT_STATE_ATTACK, eCHANGESTATEOPTION_RUSH ) == false ) assert(NULL); if( pAttacker->GetVehicleAttack() == true ) NETWORK2->PostServerEvent( "PlayerObjectSkillRequest VehicleAttack[%d,%d,%d]", characterIdx, skillIdx, skillStep ); /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertPlayerSkillMap( characterIdx, pSkillObject ); /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); /// HP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( pStepInfo->mUseHP != 0 ) { /// HP ¼Ò¸ð & ¸Þ¼¼Áö ¹ß¼Û pAttacker->HPUse( pStepInfo->mUseHP, true ); } /// ¼Ò¸ð¾ÆÀÌÅÛ IDX if( pStepInfo->mUseItemCount != 0 ) { if( pAttacker->ItemUse( pSkillInfo->mUseItem, pStepInfo->mUseItemCount ) == false ) { assert(NULL); NETWORK2->PostServerEvent("ERROR - item use skill itemidx[%d], itemcnd[%d]", pSkillInfo->mUseItem, pStepInfo->mUseItemCount ); } } /// ij½ºÆÃÀÌ ¾Æ´Ñ °æ¿ì ¹ßµ¿ üũ /// *** ij½ºÆÃÀÎ °æ¿ì´Â skillObjÀÇ RequireValue() ¿¡¼­ üũ *** switch( pSkillInfo->mType ) { case eSKILLTYPE_DAMAGE: case eSKILLTYPE_MPDAMAGE: CheckActInfluence( eACTSTATUS_ACTIVESKILL, pAttacker, pTarget ); break; case eSKILLTYPE_HEAL: CheckActInfluence( eACTSTATUS_HEALSKILL, pAttacker, pTarget ); break; } /// ½ºÅ³ ¹ßµ¿ È¿°ú if( pStepInfo->mActiveIdx != 0 ) SKILLMANAGER->CheckSkillActInfluence( pStepInfo->mActiveIdx, pAttacker, pTarget ); /// ½ºÅ³ »ý¼º ¼º°ø ¸Þ¼¼Áö¸¦ ÇØ´ç È÷¾î·Î¿¡°Ô Àü´Þ HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL ); if ( resMsg != NULL ) { resMsg->Protocol = NM_SKILL_RUSHAFTER_RES; resMsg->ErrorCode = 0; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; resMsg->mSkillIndex = skillUniqueIdx; resMsg->mObjectMP = pAttacker->GetMP(); resMsg->mMaxMP = pAttacker->GetMaxMP(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_SKILL_USED synMsg; synMsg.Category = NM_SKILL; synMsg.Protocol = NM_SKILL_RUSHAFTER_SYN; synMsg.mSkillClassIndex = skillIdx; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker = attacker; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTarget = target; synMsg.mTargetPosX = targetPos.x; synMsg.mTargetPosY = targetPos.y; synMsg.mObjectMP = pAttacker->GetMP(); synMsg.mObjectMaxMP = pAttacker->GetMaxMP(); NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->SkillSuccessCntPlus(); } catch ( int error ) { /// ½ºÅ³ ½ÇÆÐ ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_SKILL_USED* resMsg = (MSG_RES_SKILL_USED*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_SKILL ); if ( resMsg != NULL ) { resMsg->Protocol = NM_SKILL_RUSHAFTER_RES; resMsg->ErrorCode = error; resMsg->mSkillClassIndex = skillIdx; resMsg->mManagedKey = clientIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_USED) ); } } } bool cSkillManager::MonsterAttack( unsigned long monsterIdx, eMONSTERATTACK_TYPE attackType, sObject target ) { if( attackType == eMONSTERATTACK_MAX ) return false; /// ÀÌÇÔ¼ö¸¦ ÅëÇØ µé¾î¿À´Â À¯ÀúÀÇ Å¸ÀÔÀº ¸ó½ºÅÍ »ÓÀÌ´Ù. sObject attacker = { eOBJECTTYPE_MONSTER, monsterIdx }; /// °ø°ÝÀÚ °´Ã¼ üũ cMonster* pAttacker = OBJECTMANAGER->GetMonster( attacker.index ); if( pAttacker == NULL ) { assert(NULL); NETWORK2->PostServerEvent("MonsterAttack - attacker.index[%d]", attacker.index ); return false; } if( pAttacker->GetStateDie() == true || pAttacker->IsSkillPushPull() == true ) return false; /// ÀÌ¹Ì ½ºÅ³ »ç¿ëÁßÀÎÁö üũ if( IsUsingSkill( pAttacker->GetObjectType(), pAttacker->GetObjectID() ) == true ) return false; /// Ÿ°Ù °´Ã¼ üũ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL || pTarget->GetStateDie() == true ) return false; /// ½ºÅ³index üũ sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( pAttacker->GetRaceGender(), attackType ); if( pSkillInfo == NULL ) { /// ½ºÅ³ ½ºÅ©¸³Æ® µ¥ÀÌÅÍ È¹µæ ¿À·ù assert(NULL); NETWORK2->PostServerEvent("MonsterAttack - GetMonsterSkillInfo[%d,%d]", pAttacker->GetRaceGender(), attackType ); return false; } switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: { if( target.type != eOBJECTTYPE_MONSTER ) return false; if( monsterIdx != target.index ) return false; } break; case eAPPLYTYPE_ENEMY: { /// Ÿ°Ù ¼³Á¤ üũ if( target.type != eOBJECTTYPE_PLAYER ) return false; } break; case eAPPLYTYPE_BUDDY: { if( target.type != eOBJECTTYPE_MONSTER ) return false; } break; case eAPPLYTYPE_PARTY: { return false; } break; case eAPPLYTYPE_DIEBUDDY: { assert(NULL); return false; } break; // ÇöÀç´Â ¸ó½ºÅÍ ÂÊ¿¡¼­ »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù [4/6/2010 Jo_Client] case eAPPLYTYPE_BUFF_SELF: case eAPPLYTYPE_DEBUFF_SELF: case eAPPLYTYPE_BUFF_ENEMY: case eAPPLYTYPE_DEBUFF_ENEMY: case eAPPLYTYPE_BUFF_PARTY: case eAPPLYTYPE_DEBUFF_PARTY: return false; break; } /// ¼Ò¸ð MP üũ unsigned long useMP = pSkillInfo->mUseMP; if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMP = ((cPlayer*)pAttacker)->CalcUseMPExt( pSkillInfo->mUseMP ); } /// ¼Ò¸ð MP ¼öÄ¡ üũ if( useMP > pAttacker->GetMP() ) return false; bool casting = false; if( pSkillInfo->mShotType == eMONSTERSHOTTYPE_CASTING ) casting = true; /// ½ºÅ³ °íÀ¯¹øÈ£ »ý¼º unsigned long skillUniqueIdx = mSkillGen.GeneratIdx(); if( skillUniqueIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "MonsterAttack skillUniqueIdx[%d]", skillUniqueIdx ); return false; } float attackSpeed = 1.0f; /// ÀÏ¹Ý °ø°Ý¸¸ °ø¼Ó°ª º¯°æ if( eMONSTERATTACK_NORMAL1 == attackType || eMONSTERATTACK_NORMAL2 == attackType ) { attackSpeed = pAttacker->GetAttackSpeed(); } cMonsterSkillObject* pSkillObject = new cMonsterSkillObject; /// ÀÓÀÇ À§Ä¡ ÁöÁ¤ if( pSkillInfo->mBoundType == eBOUNDTYPE_FIELD || pSkillInfo->mBoundType == eBOUNDTYPE_AUTOFIELD ) { float radian = pAttacker->GetDirection(); NiPoint2 dir = NiPoint2( -sinf(radian), -cosf(radian) ); dir.Unitize(); NiPoint2 pos = pAttacker->GetPos() + dir*pSkillInfo->mTargetDist; /// ¸ø°¡´Â Áö¿ª¿¡ ½î´Â °æ¿ì¸¦ À§ÇØ °ËÁõÄÚµå - ¼³Á¤ ºÎºÐÀ» ±âȹÆÀ¿¡¼­ ´«À¸·Î º¼¼öÀÖ°Ô µû·Î ¿¹¿Ü󸮸¦ ÇÏÁø ¾Ê´Â´Ù. if( AIMANAGER->CalcPathCnt( pAttacker->GetMapNumber(), pAttacker->GetPos(), pos ) == 0 ) NETWORK2->PostServerEvent( "cSkillManager::MonsterAttack pSkillInfo->mBoundType == eBOUNDTYPE_FIELD[%d,%d] NotPath", pAttacker->GetRaceGender(), attackType ); /// ½ºÅ³ °´Ã¼ »ý¼º bool init = pSkillObject->InitMonsterSkillPosition( monsterIdx, pAttacker->GetRaceGender(), attackType, pos.x, pos.y, skillUniqueIdx, casting, pAttacker->GetMapNumber() ); if( init == false ) { assert(NULL); NETWORK2->PostServerEvent( "MonsterAttack new SkillObject pSkillInfo->mBoundType == eBOUNDTYPE_FIELD" ); SAFE_DELETE( pSkillObject ); return false; } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_POS_MONSTER_SKILL_USED synMsg; synMsg.Category = NM_SKILL; if( casting == true ) synMsg.Protocol = NM_SKILL_POS_MONSTER_CAST_USED_SYN; else synMsg.Protocol = NM_SKILL_POS_MONSTER_USED_SYN; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker.type = eOBJECTTYPE_MONSTER; synMsg.mAttackType = (unsigned char)attackType; synMsg.mAttacker.index = monsterIdx; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mTargetPosX = pos.x; synMsg.mTargetPosY = pos.y; NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); } else { float range = pAttacker->CalcStatusSkillRange( pSkillInfo->mTargetDist, pSkillInfo->mRangeType ); range = OBJECTMANAGER->ObjectSizeRange( pAttacker, pTarget, range ); /// ½ºÅ³ »ç°Å¸® ¹Û¿¡ Ÿ°ÙÀÌ ÀÖ´Ù. cRangeCheck skillRangeCheck( range ); if( !skillRangeCheck.IsRange( pAttacker->GetPos(), pTarget->GetPos() ) ) { SAFE_DELETE( pSkillObject ); return false; } /// ½ºÅ³ °´Ã¼ »ý¼º bool init = pSkillObject->InitMonsterAttack( monsterIdx, pAttacker->GetRaceGender(), attackType, target, skillUniqueIdx, casting, attackSpeed, pAttacker->GetMapNumber() ); if( init == false ) { assert(NULL); NETWORK2->PostServerEvent( "MonsterAttack new SkillObject pSkillInfo->mBoundType != eBOUNDTYPE_FIELD" ); SAFE_DELETE( pSkillObject ); return false; } /// ½ºÅ³ »ý¼º ¸Þ¼¼Áö¸¦ ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü´Þ MSG_SYN_MONSTER_SKILL_USED synMsg; synMsg.Category = NM_SKILL; if( casting == true ) synMsg.Protocol = NM_SKILL_MONSTER_CAST_USED_SYN; else synMsg.Protocol = NM_SKILL_MONSTER_USED_SYN; synMsg.mSkillIndex = skillUniqueIdx; synMsg.mAttacker.type = eOBJECTTYPE_MONSTER; synMsg.mAttackType = (unsigned char)attackType; synMsg.mAttacker.index = monsterIdx; synMsg.mAttackerPosX = pAttacker->GetXPos(); synMsg.mAttackerPosY = pAttacker->GetYPos(); synMsg.mAttackSpeedFactor = attackSpeed; synMsg.mTarget = target; NETWORK2->QuickSendExcept( pAttacker, (char*)&synMsg, sizeof(synMsg) ); pAttacker->CalcDirection( pTarget->GetPos() ); } /// ij½ºÆÃÀ» ÇÏÁö ¾Ê´Â ½ºÅ³ÀÌ¸é ½ºÅ³»ç¿ë½Ã ¼Ò¸ðÇ׸ñ °¨¼Ò if( casting == false ) { /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMP != 0 ) pAttacker->MPUse( useMP, false ); pAttacker->UpdateSkillCoolTime( attackType ); } /// ½ºÅ³À» ¸®½ºÆ®¿¡ µî·Ï InsertMonsterSkillMap( monsterIdx, pSkillObject ); pAttacker->SetAttackType( attackType ); pAttacker->ModeSkillEnd(); /// ¸ðµå½ºÅ³À» Á¦¿ÜÇÑ ½ºÅ³¸¸ ´ë»ç¸¦ Ãâ·ÂÇÑ´Ù. /// ¡Ø ¸ðµå ½ºÅ³Àº µû·Î Ãâ·ÂÇÏÁö ¾Ê°í ¸ðµå Àüȯ½Ã ¸ðµå¿¡ ÇØ´çÇÏ´Â ´ë»ç¸¸ ÇÑ´Ù. if( eMONSTERATTACK_NORMAL1 <= attackType && attackType <= eMONSTERATTACK_SKILL3 ) pAttacker->SendSpeech( attackType + eMONSTERTALK_ATTACKSTART ); pAttacker->MoveStop( false ); unsigned long attackEndTime = 0; if( pAttacker->GetAttackType() == eMONSTERATTACK_NORMAL1 || pAttacker->GetAttackType() == eMONSTERATTACK_NORMAL2 ) attackEndTime = NETWORK2->GetAccumTime() + (unsigned long)( pSkillInfo->mAttackSpd * ( 2.0f - pAttacker->GetAttackSpeed() ) ); else attackEndTime = NETWORK2->GetAccumTime() + pSkillInfo->mAttackSpd; pAttacker->CalcSkillWaitTime( attackEndTime ); return true; } bool cSkillManager::DeleteSkillObject( unsigned char type, unsigned long objectIdx, unsigned long skillUniqueIdx ) { switch( type ) { case eOBJECTTYPE_MONSTER: { cMonsterSkillObject* pSkillObject = NULL; cArray* pArray = (cArray*)mMonsterSkillMap.GetAt( objectIdx ); if( pArray == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::DeleteSkillObject(%d,%d,%d) pArray == NULL", type, objectIdx, skillUniqueIdx ); return false; } bool eraseOK = false; for( unsigned int i = pArray->GetSize() ; i > 0 ; --i ) { pSkillObject = (cMonsterSkillObject*)(*pArray)[i-1]; if( pSkillObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::DeleteSkillObject(%d,%d,%d) pSkillObject == NULL", type, objectIdx, skillUniqueIdx ); pArray->PopAt( i-1 ); continue; } if( pSkillObject->GetUniqueIdx() == skillUniqueIdx ) { /// ¸ó½ºÅͰ¡ ¸¶Áö¸·À¸·Î »ç¿ëÇÑ ½ºÅ³À» ±â·ÏÇÑ´Ù. cMonster* pMonster = OBJECTMANAGER->GetMonster( objectIdx ); if( pMonster != NULL ) pMonster->SetLastUsedSkillIdx( pSkillObject->GetSkillIdx() ); SAFE_DELETE( pSkillObject ); pArray->PopAt( i-1 ); eraseOK = true; break;; } } if( pArray->GetSize() == 0 ) { SAFE_DELETE( pArray ); mMonsterSkillMap.Erase( objectIdx ); } if( eraseOK == true ) return true; } break; case eOBJECTTYPE_HERO: case eOBJECTTYPE_PLAYER: { cBaseSkillObject* pSkillObject = NULL; cArray* pArray = (cArray*)mPlayerSkillMap.GetAt( objectIdx ); if( pArray == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::DeleteSkillObject(%d,%d,%d) pArray == NULL", type, objectIdx, skillUniqueIdx ); return false; } bool eraseOK = false; for( unsigned int i = pArray->GetSize() ; i > 0 ; --i ) { pSkillObject = (cBaseSkillObject*)(*pArray)[i-1]; if( pSkillObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::DeleteSkillObject(%d,%d,%d) pSkillObject == NULL", type, objectIdx, skillUniqueIdx ); pArray->PopAt( i-1 ); continue; } if( pSkillObject->GetUniqueIdx() == skillUniqueIdx ) { SAFE_DELETE( pSkillObject ); pArray->PopAt( i-1 ); eraseOK = true; break; } } if( pArray->GetSize() == 0 ) { SAFE_DELETE( pArray ); mPlayerSkillMap.Erase( objectIdx ); } if( eraseOK == true ) return true; } break; default: return false; } return false; } void cSkillManager::InsertDeleteSkillObject( sObject skillUser, unsigned long skillUniqueIdx ) { sDelSkillInfo info; info.skillUser = skillUser; info.mSkillIdx = skillUniqueIdx; mDeleteSkillAry.PushBack( info ); } unsigned char cSkillManager::AddPlayerHaveSkill( unsigned long playerIdx, unsigned long skillIdx, unsigned char skillStep, unsigned long cooltime ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkill - playerIdx[%d]", playerIdx ); return SKILL_ADD_ERR_PLAYER; } /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( !pSkillInfo ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkill - skillIdx[%d]", skillIdx ); return SKILL_ADD_ERR_SCRIPT; } /// ½ºÅ³ ´Ü°è °ª üũ if( skillStep < 0 || pSkillInfo->mStepCount <= skillStep ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkill - skillStep[%d]", skillStep ); return SKILL_ADD_ERR_SKILLSTEP; } sPlayerSkillStepInfo* pSkillStep = &pSkillInfo->mpSetpInfoArray[skillStep]; /*--------------- skilllist_pc ---------------*/ /// ÀüÁ÷¾÷ »ç¿ë SP·® if( pSkillInfo->mJobStep > 0 && pSkillInfo->mJobStep < MAX_JOBSTEP ) { unsigned long point = pPlayer->GetJobUsedSkillPoint( pSkillInfo->mJobStep-1 ); if( point < pSkillInfo->mBeforeReqSP ) return SKILL_ADD_ERR_JOBSP; } /// Á¾Á· ±¸ºÐ Àִ°æ¿ì if( pSkillInfo->mRace != 0 ) /// 0 = ALL { /// Á¾Á· üũ switch( pPlayer->GetRace() ) { case eRACE_HUMAN: if( !( pSkillInfo->mRace == eSKILLRACE_HUMAN || pSkillInfo->mRace == eSKILLRACE_HUMAN_BEAST || pSkillInfo->mRace == eSKILLRACE_HUMAN_ELF ) ) { return SKILL_ADD_ERR_RACE; }break; case eRACE_BEAST: if( !( pSkillInfo->mRace == eSKILLRACE_BEAST || pSkillInfo->mRace == eSKILLRACE_HUMAN_BEAST || pSkillInfo->mRace == eSKILLRACE_BEAST_ELF ) ) { return SKILL_ADD_ERR_RACE; }break; case eRACE_ELF: if( !( pSkillInfo->mRace == eSKILLRACE_ELF || pSkillInfo->mRace == eSKILLRACE_HUMAN_ELF || pSkillInfo->mRace == eSKILLRACE_BEAST_ELF ) ) { return SKILL_ADD_ERR_RACE; }break; default: assert(NULL); return SKILL_ADD_ERR_SCRIPT; } } /// ¼±Çà ½ºÅ³1 ÇÊ¿ä if( pSkillStep->mLearnSkillIdx1 != 0 ) { /// ¼±Çà º¸À¯ ½ºÅ³ üũ cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( playerIdx, pSkillStep->mLearnSkillIdx1 ); if( !pPlayerHaveSkill ) return SKILL_ADD_ERR_LEARNSKILL; /// ¼±Çà º¸À¯ ½ºÅ³ÀÇ ½ºÅÜ if( pSkillStep->mLearnSkillStep1 > pPlayerHaveSkill->GetSkillStep() + 1 ) return SKILL_ADD_ERR_LEARNSTEP; } /// ¼±Çà ½ºÅ³2 ÇÊ¿ä if( pSkillStep->mLearnSkillIdx2 != 0 ) { /// ¼±Çà º¸À¯ ½ºÅ³ üũ cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( playerIdx, pSkillStep->mLearnSkillIdx2 ); if( !pPlayerHaveSkill ) return SKILL_ADD_ERR_LEARNSKILL; /// ¼±Çà º¸À¯ ½ºÅ³ÀÇ ½ºÅÝ if( pSkillStep->mLearnSkillStep2 > pPlayerHaveSkill->GetSkillStep() + 1 ) return SKILL_ADD_ERR_LEARNSTEP; } ///*--------------- skilllist_sub ---------------*/ /// Á÷¾÷±¸ºÐ ÀÖ´Â °æ¿ì if( pSkillInfo->mpSetpInfoArray->mJobType != 0 ) { /// Á÷¾÷À» üũ if( !SKILLSCRIPT->IsPlayerSkillJob( pSkillInfo->mpSetpInfoArray->mJobType, static_cast(pPlayer->GetJob()) ) ) return SKILL_ADD_ERR_JOB; } /// ij¸¯ÅÍ ÇÊ¿ä level if( pSkillInfo->mpSetpInfoArray->mPlayerLevel > pPlayer->GetLevel() ) return SKILL_ADD_ERR_LEVEL; ///*---------------------------------------------*/ /// Ãß°¡ÇÒ ½ºÅ³ÀÌ º¸À¯¸®½ºÆ®¿¡ ÀÖ´ÂÁö Àоî¿È cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( playerIdx, skillIdx ); /// »õ·Î ¹è¿ì´Â ½ºÅ³ÀÎÁö üũ if( skillStep == SKILL_START_STEP ) { /// ÀÌ¹Ì ½ºÅ³ÀÌ ÀÖÀ¸¸é ¿À·ù if( pPlayerHaveSkill ) { NETWORK2->PostServerEvent("AddPlayerHaveSkill -alreay have skill[%d](mSkillStep[%d]) skillStep[%d]", skillIdx, pPlayerHaveSkill->GetSkillStep(), skillStep ); return SKILL_ADD_ERR_SKILLSTEP; } /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { /// »õ·Î¿î ½ºÅ³¸®½ºÆ®¸¦ ¸¸µë pPlayerHaveSkillMap = new cPointerHashMap; /// »õ·Î ¸¸µç ½ºÅ³¸®½ºÆ®¸¦ ±â·Ï if( !( mPlayerHaveSkillMap.Insert( playerIdx, pPlayerHaveSkillMap ) ) ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkill[%d,%d,%d] - mPlayerHaveSkillMap.Insert error", playerIdx, skillIdx, skillStep ); SAFE_DELETE( pPlayerHaveSkillMap ); return SKILL_ADD_ERR_MAPINSERT; } } /// º¸À¯½ºÅ³¸®½ºÆ® Á¤º¸¸¦ ±â·Ï cHaveSkillObject* pPlayerHaveSkill = new cHaveSkillObject; pPlayerHaveSkill->Init( skillIdx, 0, cooltime ); if( !(pPlayerHaveSkillMap->Insert( skillIdx, pPlayerHaveSkill ) ) ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkill[%d,%d,%d] - mPlayerHaveSkillMap.Insert error", playerIdx, skillIdx, skillStep ); SAFE_DELETE( pPlayerHaveSkill ); return SKILL_ADD_ERR_MAPINSERT; } } else /// ´Ü°è¸¦ ¾÷½ÃŰ´Â °æ¿ì { /// º¸À¯½ºÅ³ÀÌ ¾øÀ¸¸é ¿À·ù if( pPlayerHaveSkill == 0 ) { return SKILL_ADD_ERR_SKILLSTEP; } /// ´Ü°è ¾÷Á¶°ÇÀÌ ¸¸Á·ÇÏÁö ¾ÊÀ¸¸é ¿À·ù if( pPlayerHaveSkill->StepUp( skillStep, cooltime ) == false ) { return SKILL_ADD_ERR_SKILLSTEP; } } /// ÆÐ½Ãºê Àϰæ¿ì ½ºÅÝ Àç°è»ê if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { /// ±âº»Ç׸ñÀ» Á¦¿ÜÇÑ È®Àå(+,%) Ç׸ñ¸¸ °è»ê STATUSCALC->CalcPlayerExtensionGlobal( pPlayer->GetObject() ); } /// ¿À¶ó½ºÅ³ÀÌ¸é ±âÁ¸ ½ºÅ³ ²û if( pSkillInfo->mShotType == eSHOTTYPE_AURA ) AuraInfluenceOff( playerIdx, skillIdx ); return SKILL_ADD_ERR_SUCCESS; } unsigned char cSkillManager::AddPlayerHaveSkillByCheat( unsigned long playerIdx, unsigned long skillIdx, unsigned char skillStep, unsigned long cooltime ) { /// À¯Àú üũ cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkillByCheat - playerIdx[%d]", playerIdx ); return ERROR_CHEAT_SKILL_ADD_ERR_PLAYER; } /// ½ºÅ³index üũ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( !pSkillInfo ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkillByCheat - skillIdx[%d]", skillIdx ); return ERROR_CHEAT_SKILL_ADD_ERR_SCRIPT; } /// ½ºÅ³ ´Ü°è °ª üũ if( skillStep < 0 || pSkillInfo->mStepCount <= skillStep ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkillByCheat - skillStep[%d]", skillStep ); return ERROR_CHEAT_SKILL_ADD_ERR_SKILLSTEP; } /*--------------- skilllist_pc ---------------*/ /// Á¾Á· ±¸ºÐ Àִ°æ¿ì if( pSkillInfo->mRace != 0 ) /// 0 = ALL { /// Á¾Á· üũ switch( pPlayer->GetRace() ) { case eRACE_HUMAN: if( !( pSkillInfo->mRace == eSKILLRACE_HUMAN || pSkillInfo->mRace == eSKILLRACE_HUMAN_BEAST || pSkillInfo->mRace == eSKILLRACE_HUMAN_ELF ) ) { return ERROR_CHEAT_SKILL_ADD_ERR_RACE; }break; case eRACE_BEAST: if( !( pSkillInfo->mRace == eSKILLRACE_BEAST || pSkillInfo->mRace == eSKILLRACE_HUMAN_BEAST || pSkillInfo->mRace == eSKILLRACE_BEAST_ELF ) ) { return ERROR_CHEAT_SKILL_ADD_ERR_RACE; }break; case eRACE_ELF: if( !( pSkillInfo->mRace == eSKILLRACE_ELF || pSkillInfo->mRace == eSKILLRACE_HUMAN_ELF || pSkillInfo->mRace == eSKILLRACE_BEAST_ELF ) ) { return ERROR_CHEAT_SKILL_ADD_ERR_RACE; }break; default: assert(NULL); return ERROR_CHEAT_SKILL_ADD_ERR_SCRIPT; } } ///*--------------- skilllist_sub ---------------*/ /// Á÷¾÷±¸ºÐ ÀÖ´Â °æ¿ì if( pSkillInfo->mpSetpInfoArray->mJobType != 0 ) { /// Á÷¾÷À» üũ if( !SKILLSCRIPT->IsPlayerSkillJob( pSkillInfo->mpSetpInfoArray->mJobType, static_cast(pPlayer->GetJob()) ) ) return ERROR_CHEAT_SKILL_ADD_ERR_JOB; } ///*---------------------------------------------*/ /// Ãß°¡ÇÒ ½ºÅ³ÀÌ º¸À¯¸®½ºÆ®¿¡ ÀÖ´ÂÁö Àоî¿È cHaveSkillObject* pPlayerHaveSkill = GetPlayerHaveSkill( playerIdx, skillIdx ); /// »õ·Î ¹è¿ì´Â ½ºÅ³ÀÎÁö üũ if( pPlayerHaveSkill == NULL ) { /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { /// »õ·Î¿î ½ºÅ³¸®½ºÆ®¸¦ ¸¸µë pPlayerHaveSkillMap = new cPointerHashMap; /// »õ·Î ¸¸µç ½ºÅ³¸®½ºÆ®¸¦ ±â·Ï if( !( mPlayerHaveSkillMap.Insert( playerIdx, pPlayerHaveSkillMap ) ) ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkillCheat[%d,%d,%d] - mPlayerHaveSkillMap.Insert error", playerIdx, skillIdx, skillStep ); SAFE_DELETE( pPlayerHaveSkillMap ); return ERROR_CHEAT_SKILL_ADD_ERR_MAPINSERT; } } /// º¸À¯½ºÅ³¸®½ºÆ® Á¤º¸¸¦ ±â·Ï cHaveSkillObject* pPlayerHaveSkill = new cHaveSkillObject; pPlayerHaveSkill->Init( skillIdx, skillStep, cooltime ); if( !(pPlayerHaveSkillMap->Insert( skillIdx, pPlayerHaveSkill ) ) ) { assert(NULL); NETWORK2->PostServerEvent("AddPlayerHaveSkillCheat[%d,%d,%d] - mPlayerHaveSkillMap.Insert error", playerIdx, skillIdx, skillStep ); SAFE_DELETE( pPlayerHaveSkill ); return ERROR_CHEAT_SKILL_ADD_ERR_MAPINSERT; } } else /// ´Ü°è¸¦ ¾÷½ÃŰ´Â °æ¿ì { pPlayerHaveSkill->StepUpByCheat( skillStep, cooltime ); } /// ÆÐ½Ãºê Àϰæ¿ì ½ºÅÝ Àç°è»ê if( pSkillInfo->mType == eSKILLTYPE_PASSIVE ) { /// ±âº»Ç׸ñÀ» Á¦¿ÜÇÑ È®Àå(+,%) Ç׸ñ¸¸ °è»ê STATUSCALC->CalcPlayerExtensionGlobal( pPlayer->GetObject() ); } /// ¿À¶ó½ºÅ³ÀÌ¸é ±âÁ¸ ½ºÅ³ ²û if( pSkillInfo->mShotType == eSHOTTYPE_AURA ) AuraInfluenceOff( playerIdx, skillIdx ); return ERROR_CHEAT_SKILL_ADD_SUCCESS; } void cSkillManager::InsertPlayerSkillMap( unsigned long characterIdx, cBaseSkillObject* pSkillObject ) { cArray* pSkillArray = (cArray*)mPlayerSkillMap.GetAt( characterIdx ); if( pSkillArray == NULL ) { pSkillArray = new cArray; mPlayerSkillMap.Insert( characterIdx, pSkillArray ); } pSkillArray->PushBack( pSkillObject ); } void cSkillManager::InsertMonsterSkillMap( unsigned long monsterIdx, cMonsterSkillObject* pSkillObject ) { cArray* pSkillArray = (cArray*)mMonsterSkillMap.GetAt( monsterIdx ); if( pSkillArray == NULL ) { pSkillArray = new cArray; mMonsterSkillMap.Insert( monsterIdx, pSkillArray ); } pSkillArray->PushBack( pSkillObject ); } cHaveSkillObject* cSkillManager::GetPlayerHaveSkill( unsigned long playerIdx, unsigned long skillIdx ) { cPointerHashMap* cPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); if ( !cPlayerHaveSkillMap ) { return NULL; } /// ±âº» °ø°ÝÀÎ °æ¿ì LBSÃß°¡ if( skillIdx < NORMAL_ATTACK_SKILL_MAX ) return (cHaveSkillObject*)cPlayerHaveSkillMap->GetAt( NORMAL_ATTACK_SKILL ); return (cHaveSkillObject*)cPlayerHaveSkillMap->GetAt( skillIdx ); } void* cSkillManager::GetPlayerHaveSkill( unsigned long playerIdx ) { return mPlayerHaveSkillMap.GetAt( playerIdx ); } bool cSkillManager::DelPlayerHaveSkill( unsigned long playerIdx, unsigned long skillIdx ) { /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::DelPlayerHaveSkill pPlayer[%d]HaveSkillMap == NULL", playerIdx ); return false; } if( !(pPlayerHaveSkillMap->Erase( skillIdx ) ) ) { return false; } return true; } void cSkillManager::RollBackPlayerHaveSkill( unsigned long playerIdx, unsigned long skillIdx ) { cHaveSkillObject* pHaveSkillObject = GetPlayerHaveSkill( playerIdx, skillIdx ); if( !pHaveSkillObject ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::RollBackPlayerHaveSkill pHaveSkillObject[%d,%d] == NULL", playerIdx, skillIdx ); return; } if( pHaveSkillObject->GetSkillStep() == SKILL_START_STEP ) { cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); if( !pPlayerHaveSkillMap ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::RollBackPlayerHaveSkill pPlayerHaveSkillMap[%d] == NULL", playerIdx ); return; } SAFE_DELETE( pHaveSkillObject ); pPlayerHaveSkillMap->Erase( skillIdx ); } else { /// ½ºÅÜ ÇÑ´Ü°è °¨¼Ò pHaveSkillObject->StepDown(); } } void cSkillManager::ReleasePlayerHaveSkill() { cPointerHashMap::cIterator startPlayer = mPlayerHaveSkillMap.Begin(); cPointerHashMap::cIterator endPlayer = mPlayerHaveSkillMap.End(); for( ; startPlayer != endPlayer ; ++startPlayer ) { cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)(*startPlayer).mSecond; if ( !pPlayerHaveSkillMap ) { continue; } cPointerHashMap::cIterator startSkill = pPlayerHaveSkillMap->Begin(); cPointerHashMap::cIterator endSkill = pPlayerHaveSkillMap->End(); cHaveSkillObject* p; for( ; startSkill != endSkill ; ++startSkill ) { p = (cHaveSkillObject*)(*startSkill).mSecond; SAFE_DELETE( p ); } SAFE_DELETE( pPlayerHaveSkillMap ); } mPlayerHaveSkillMap.Clear(); } void cSkillManager::ReleaseInfluence() { cPointerHashMap::cIterator startInfluence = mInfluenceMap.Begin(); cPointerHashMap::cIterator endInfluence = mInfluenceMap.End(); cInfluenceObject* pInfluenceObject; for( ; startInfluence != endInfluence ; ++startInfluence ) { pInfluenceObject = (cInfluenceObject*)(*startInfluence).mSecond; SAFE_DELETE( pInfluenceObject ); } mInfluenceMap.Clear(); } bool cSkillManager::SaveAllPlayerInfluence( unsigned long playerIdx, SKILL_INFLUENCE_UPDATE* pInfluenceUpdate ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SavePlayerInfluence pPlayer[%d] == NULL", playerIdx ); return false; } tHashSet* pInfluenceAry = pPlayer->GetInfluenceSet(); if( !pInfluenceAry ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SavePlayerInfluence pInfluenceAry == NULL" ); return false; } cInfluenceObject* pInfluenceObject = NULL; tHashSet::cIterator start = pInfluenceAry->Begin(); tHashSet::cIterator end = pInfluenceAry->End(); /// ·Î±×·Î ¹ß¼ÛÇÒ ¸Þ¼¼Áö »ý¼º HANDLE handle = NULL; TB_CHARACTER_INFLUENCE* pLogTable = NULL; SKILL_INFLUENCE_UPDATE* pLogMsg = (SKILL_INFLUENCE_UPDATE*)NETWORK2->GetMsgRoot( &handle, pPlayer->GetConnectionIdx( ) ); if( pLogMsg != NULL ) { pLogMsg->mCharacterIdx = playerIdx; pLogMsg->mCycleSave = false; pLogMsg->mRetvalue = -1; pLogMsg->mRowCount = 0; pLogTable = pLogMsg->mTable; } else NETWORK2->PostServerEvent("cSkillManager::SaveAllPlayerInfluence pLogMsg = NULL" ); // 08/03/11 ¼öÁ¤ TB_CHARACTER_INFLUENCE* table = pInfluenceUpdate->mTable; // long i = 0; for( ; start != end ; ++start ) { pInfluenceObject = GetInfluence( (*start) ); if( !pInfluenceObject ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SavePlayerInfluence pInfluenceObject[%d] == NULL", (*start) ); //-/-//InsertDeleteInfluenceObject( pInfluenceObject ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } if( pInfluenceObject->IsSavePlayerInfluence( false ) == false ) continue; if( pLogMsg != NULL && pLogTable != NULL ) { sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInfluenceObject->GetInfluenceClassIdx() ); if( pScript != NULL && pScript->mType == eINFLUENCETYPE_CASH ) { pInfluenceObject->SavePlayerInfluence( pLogTable ); ++pLogMsg->mRowCount; ++pLogTable; } } // 08/03/11 ¼öÁ¤ pInfluenceObject->SavePlayerInfluence( table ); // pInfluenceObject->SavePlayerInfluence( &pInfluenceUpdate->mTable[i] ); table++; // i++; pInfluenceUpdate->mRowCount++; } // 08/03/11 ¼öÁ¤ // pInfluenceUpdate->mRowCount = i; pInfluenceUpdate->mCharacterIdx = playerIdx; pInfluenceUpdate->mCycleSave = false; pPlayer->SetCashInfSave( true ); /// ·Î±×±â·Ï unsigned long releaseSize = 0; if( pLogMsg != NULL ) { if( pLogMsg->mRowCount > 0 ) NETWORK2->PostInfCashEvent( pPlayer->GetObjectID(), EVENT_INFCASH_LOGOUT, pLogMsg ); releaseSize = sizeof(SKILL_INFLUENCE_UPDATE) - sizeof(pLogMsg->mTable) + ( pLogMsg->mRowCount * sizeof(TB_CHARACTER_INFLUENCE) ); NETWORK2->ReleaseMsgRoot( (PerIoContext*)handle, releaseSize ); } return true; } void cSkillManager::SavePlayerInfluence( unsigned long playerIdx, unsigned long infObjectIdx, bool del ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer == NULL ) return; cInfluenceObject* pInf = GetInfluence( infObjectIdx ); if( pInf == NULL ) { NETWORK2->PostServerEvent("cSkillManager::SavePlayerInfluence pInfluenceObject[%d] == NULL", playerIdx ); return; } if( pInf->IsSavePlayerInfluence( false ) == false ) return; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript == NULL ) return; HANDLE handle = NULL; SKILL_INFLUENCE_UPDATE* pUpdate = (SKILL_INFLUENCE_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INFLUENCE_UPDATE ); unsigned long length = sizeof(SKILL_INFLUENCE_UPDATE) - sizeof(pUpdate->mTable); pInf->SavePlayerInfluence( pUpdate->mTable ); pUpdate->mTable[0].mDel = del == true ? 1 : 0; pUpdate->mRowCount = 1; pUpdate->mCharacterIdx = playerIdx; pUpdate->mCycleSave = false; pPlayer->SetCashInfSave( true ); char logType = EVENT_INFCASH_INSERT; if( del == true ) logType = EVENT_INFCASH_DELETE; /// ·Î±×±â·Ï if( pScript->mType == eINFLUENCETYPE_CASH ) NETWORK2->PostInfCashEvent( pPlayer->GetObjectID(), logType, pUpdate ); length += pUpdate->mRowCount * sizeof(TB_CHARACTER_INFLUENCE); NETWORK2->SendSQL( pPlayer->GetConnectionIdx(), handle, length ); } void cSkillManager::CycleSaveCashInfluence( cPlayer* pPlayer ) { if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CycleSaveCashInfluence pPlayer[] == NULL" ); return; } tHashSet* pInfluenceAry = pPlayer->GetInfluenceSet(); if( !pInfluenceAry ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CycleSaveCashInfluence pInfluenceAry == NULL" ); return; } tHashSet::cIterator start = pInfluenceAry->Begin(); tHashSet::cIterator end = pInfluenceAry->End(); HANDLE handle = NULL; SKILL_INFLUENCE_UPDATE* pUpdate = (SKILL_INFLUENCE_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INFLUENCE_UPDATE ); unsigned long length = sizeof(SKILL_INFLUENCE_UPDATE) - sizeof(pUpdate->mTable); pUpdate->mCharacterIdx = pPlayer->GetObjectID(); pUpdate->mCycleSave = true; // 08/03/11 ¼öÁ¤ TB_CHARACTER_INFLUENCE* table = pUpdate->mTable; for( ; start != end ; ++start ) { cInfluenceObject* pInf = GetInfluence( (*start) ); if( !pInf ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SavePlayerInfluence pInfluenceObject[%d] == NULL", (*start) ); //-/-//InsertDeleteInfluenceObject( pInfluenceObject ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } if( pInf->IsSavePlayerInfluence( true ) == false ) continue; if( pInf->IsDelReady() == true ) continue; // 08/03/11 ¼öÁ¤ pInf->SavePlayerInfluence( table ); table++; pUpdate->mRowCount++; } if( pUpdate->mRowCount == 0 ) { NETWORK2->ReleaseSQL( handle, length ); return; } /// ·Î±×±â·Ï NETWORK2->PostInfCashEvent( pPlayer->GetObjectID(), EVENT_INFCASH_CYCLE, pUpdate ); pPlayer->SetCashInfSaveCycle( true ); length += pUpdate->mRowCount * sizeof(TB_CHARACTER_INFLUENCE); NETWORK2->SendSQL( pPlayer->GetConnectionIdx(), handle, length ); return; } void cSkillManager::RestorePlayerInfluence( unsigned long playerIdx, SKILL_INFLUENCE_SELECT* pInfluenceSelect, unsigned long rowCnt ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::RestorePlayerInfluence pPlayer[%d] == NULL", playerIdx ); return; } unsigned long uniqueIdx = 0; cInfluenceObject* pInf = NULL; for( unsigned long i = 0 ; i < rowCnt ; ++i ) { sInfluence* pInfluence = &pInfluenceSelect->mTable[i]; if( pInfluence == NULL ) continue; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInfluence->mInfluenceClassIdx ); if( pScript == NULL ) continue; /// ½Å±Ô »ý¼º pInf = new cInfluenceObject; uniqueIdx = mInfluenceGen.GeneratIdx(); if( pInf->RestorePlayerInfluence( playerIdx, uniqueIdx, pInfluence ) == false ) { assert(NULL); SAFE_DELETE( pInf ); continue; } if( !( mInfluenceMap.Insert( uniqueIdx, pInf ) ) ) { assert(NULL); SAFE_DELETE( pInf ); NETWORK2->PostServerEvent( "cSkillManager::RestorePlayerInfluence mInfluenceMap.Insert Duplicate" ); continue; } //if( pPlayer->AddInfluence( uniqueIdx, pInf->GetInfluenceClassIdx() ) == false ) if( pPlayer->AddInfluence( pInf ) == false ) { assert(NULL); NETWORK2->PostServerEvent( "cSkillManager::RestorePlayer[%d]Influence[%d] pPlayer->AddSkillInfluence[%d] == false", playerIdx, uniqueIdx, pInf->GetInfluenceClassIdx() ); NETWORK2->PostServerEvent( "cSkillManager::RestorePlayer[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]", pInfluence->mUniqueIdx, pInfluence->mDbIdx, pInfluence->mInfluenceClassIdx, pInfluence->mAttacker.type, pInfluence->mAttacker.index, pInfluence->mIsRealTime, pInfluence->mRestTime, pInfluence->mTime1, pInfluence->mTime2, pInfluence->mInfluenceValue1, pInfluence->mInfluenceValue2 ); continue; } } } void cSkillManager::ReleasePlayerHaveSkill( unsigned long playerIdx ) { /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { return; } cPointerHashMap::cIterator startSkill = pPlayerHaveSkillMap->Begin(); cPointerHashMap::cIterator endSkill = pPlayerHaveSkillMap->End(); cHaveSkillObject* p = NULL; for( ; startSkill != endSkill ; ++startSkill ) { p = (cHaveSkillObject*)(*startSkill).mSecond; SAFE_DELETE( p ); } SAFE_DELETE( pPlayerHaveSkillMap ); mPlayerHaveSkillMap.Erase( playerIdx ); } bool cSkillManager::AddInfluence( sObject attacker, sObject target, unsigned long infClassIdx, unsigned long skillClassIdx, bool msgSend, sInfluenceCreate* pInf ) { ////////////////////////////////////////////////////////////////////////// /// ÂüÁ¶ µ¥ÀÌŸ ·Îµå /// ½Å±ÔÈ¿°ú ½ºÅ©¸³Æ® sInfluenceScript* pNewScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pNewScript == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pNewScript[%d]==NULL", infClassIdx ); return false; } const int colNum = 3; long type[colNum] = { pNewScript->mStatusPlusIdx1, pNewScript->mStatusPlusIdx2, pNewScript->mStatusPlusIdx3 }; long value[colNum] = { pNewScript->mValue1, pNewScript->mValue2, pNewScript->mValue3 }; /// °ø°ÝÀÚ, Ÿ°Ù Æ÷ÀÎÅÍ cBaseObject* pAttacker = OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pAttacker[%d,%d]==NULL", attacker.type, attacker.index ); return false; } if( pAttacker->GetStateDie() == true ) return false; cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( !pTarget ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pTarget[%d,%d]==NULL", target.type, target.index ); return false; } // ¿ÀÅä ´õ¹Ì üũ if( target.type == eOBJECTTYPE_MONSTER ) { cMonster* mon = (cMonster*)pTarget; if( mon->IsAutoDummy() == true ) return false; } ////////////////////////////////////////////////////////////////////////// /// ¹ßµ¿ È®·ü üũºÎ unsigned long skillRate = pNewScript->mActivityPer; if( skillRate != 0 ) { /// È®·ü °ª unsigned long checkPer = skillRate; if( skillClassIdx != 0 ) { /// °ø°ÝÀÚ¿Í Å¸°Ù°£ÀÇ »óÅÂÀÌ»ó °ø½ÄÀ» Àû¿ë ÇØ¾ß ÇÏ´ÂÁö À¯¹« bool isBadInfluence = false; for( int i = 0 ; i < colNum ; ++i ) { if( eSTATUSPLUS_DISPEL <= type[i] && type[i] <= eSTATUSPLUS_CONDITIONINDISPOSITION_MAX ) { isBadInfluence = true; break; } } /// »óÅ ÀÌ»ó È®·ü°ª »êÃâ if( isBadInfluence == true ) checkPer = pAttacker->ConditionOdd( target, skillRate, skillClassIdx ); } /// È®·ü üũ unsigned long activityRand = rand() % 100; if( checkPer <= activityRand ) return false; } bool EndVehicle = false; ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼º üũºÎ bool createInfluence = false; for( int i = 0 ; i < colNum ; ++i ) { /// ¸é¿ªÃ¼Å© if( target.type == eOBJECTTYPE_MONSTER ) { /// ¸é¿ª üũ if( ((cMonster*)pTarget)->IsImmuneApplyType( pNewScript->mType, type[i] ) == true ) return false; if( ((cMonster*)pTarget)->IsImmuneKind( pNewScript->mTypeDetail ) == true ) return false; if( eSTATUSPLUS_CHANGE_MONSTER == type[i] ) return false; } else if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayer = (cPlayer*)pTarget; /// Å»°Í ź»óÅ¿¡¼± ¸ó½ºÅÍ º¯½Å ºÒ°¡ if( type[i] == eSTATUSPLUS_CHANGE_MONSTER ) { if( pPlayer->IsVehicle() == true ) EndVehicle = true; if( (pPlayer->GetState() == eOBJECT_STATE_IDLE || pPlayer->GetState() == ePLAYER_STATE_ITEMPICK ) == false ) return false; } else if( type[i] == eSTATUSPLUS_VEHICLE ) { /// Á¡ÇÁÁß¿¡ Å»°ÍŸ´Â °æ¿ì È¿°ú»ý¼º(Å»°ÍŸ±â)ºÒ°¡ if( pPlayer->GetJumpEndTime() > NETWORK2->GetAccumTime() ) return false; } /// ¸é¿ª üũ if( pPlayer->IsImmuneApplyType( pNewScript->mType, type[i] ) == true ) return false; if( pPlayer->IsImmuneKind( pNewScript->mTypeDetail ) == true ) return false; } /// ½ºÅ³¿¡¼­¸¸ »ç¿ë - ±âÀÔ ¿¡·¯ else if( eSTATUSPLUS_INSTANTPERHIT <= type[i] && type[i] <= eSTATUSPLUS_DELETE_TARGETING ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence type[%d,%d] error", infClassIdx, type[i] ); return false; } ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼¸¦ »ý¼ºÇÏ´ÂÁö üũ if( ( eSTATUSPLUS_STR_PLUS <= type[i] && type[i] <= eSTATUSPLUS_BASE_MAX ) || // ( eSTATUSPLUS_STR_PERCENT <= type && type <= eSTATUSPLUS_BASE_PERCENT_MAX ) || // ¾ÆÁ÷ %¿É¼ÇÀÌ Àû¿ëµÇ´Â ½ÃÁ¡ÀÌ ¾Æ´Ô [7/13/2010 JO_CLIENT] ( eSTATUSPLUS_BASEALL_PLUS == type[i] ) || ( eSTATUSPLUS_ATK_PLUS <= type[i] && type[i] <= eSTATUSPLUS_BUFF_ETC_MAX ) || ( eSTATUSPLUS_DOT_HPCHANGE_PLUS <= type[i] && type[i] <= eSTATUSPLUS_DOT_MAX ) || ( eSTATUSPLUS_STOPMOVE <= type[i] && type[i] <= eSTATUSPLUS_CONDITIONINDISPOSITION_MAX ) || eSTATUSPLUS_CHAR_SIZE == type[i] || eSTATUSPLUS_ATTACKERTARGETING == type[i] || eSTATUSPLUS_CASHEXPGUARDCNT == type[i] || ( eSTATUSPLUS_NEED_STATE_ICE <= type[i] && type[i] <= eSTATUSPLUS_NEED_STATE_MAX ) ) { createInfluence = true; } } /// ÀÌÆåÆ®¸¸ ºÙÀÌ´Â È¿°ú if( type[0] == 0 && type[1] == 0 && type[2] == 0 && pNewScript->mContinuanceTime > 0 ) createInfluence = true; ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼ººÎ unsigned long uniqueIdx = 0; if( createInfluence == true ) { cHashSet* pInfluenceSet = pTarget->GetInfluenceSet(); /// Áߺ¹/±×·ì üũ tHashSet::cIterator begin = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceObject==NULL" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceScript==NULL" ); continue; } bool notOverLap = false; /// Áߺ¹ ºÒ°¡ÀÎÁö üũ if( pNewScript->mNotOverlapGroupIdx != 0 ) { /// ±âº» Áߺ¹ºÒ°¡ ±×·ì üũ °°Àº°æ¿ì¸é °É¼ö ¾ø´Ù. if( pHaveScript->mNotOverlapGroupIdx == pNewScript->mNotOverlapGroupIdx ) notOverLap = true; if( notOverLap == false ) { if( pNewScript->mOverlapScriptIdx != 0 ) { if( SKILLSCRIPT->IsInfOverLap( pNewScript->mOverlapScriptIdx, pHaveScript->mNotOverlapGroupIdx ) == true ) notOverLap = true; } } if( notOverLap == false ) { if( pHaveScript->mOverlapScriptIdx != 0 ) { if( SKILLSCRIPT->IsInfOverLap( pHaveScript->mOverlapScriptIdx, pNewScript->mNotOverlapGroupIdx ) == true ) notOverLap = true; } } } /// ¹öÇÁÁ¾·ùº° ¿ì¼±¼øÀ§ : ij½Ã > PC > ¹öÇÁ,µð¹öÇÁ /// °°Àº [Áߺ¹ºÒ°¡±×·ì] ÀÎ °æ¿ì if( notOverLap == true ) { /// °°Àº Áߺ¹ºÒ°¡¿¡ ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return false; /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pNewScript->mType == eINFLUENCETYPE_BUF || pNewScript->mType == eINFLUENCETYPE_DEBUF ) ) return false; /// pc¹æ ¹öÇÁ°¡ Áߺ¹ºÒ°¡ ±×·ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pNewScript->mType == eINFLUENCETYPE_PC ) return false; if( pNewScript->mType == eINFLUENCETYPE_CASH || pNewScript->mType == eINFLUENCETYPE_PC ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } /// [±×·ì ¹øÈ£] ºñ±³ if( pNewScript->mGroupIdx != 0 ) { if( pNewScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// [±×·ìÈ¿·Â°ª] ºñ±³ if( pNewScript->mGroupOrder >= pHaveScript->mGroupOrder || pNewScript->mType == eINFLUENCETYPE_PC || pNewScript->mType == eINFLUENCETYPE_CASH ) { pHaveInf->NoStatusCalc(); /// ±âÁ¸ÀÌ ÀÛÀ¸¸é ±âÁ¸ »èÁ¦ DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } else /// ±âÁ¸ÀÌ Å«°æ¿ì ½Å±Ô »ý¼º¾ÈÇϰí Á¾·á return false; } else /// [±×·ì ¹øÈ£]°¡ ´Ù¸£¸é { pHaveInf->NoStatusCalc(); /// ±âÁ¸ È¿°ú Á¦°Å DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } } } else /// ´Ù¸¥ [Áߺ¹ºÒ°¡±×·ì]ÀÎ °æ¿ì { /// [±×·ì¹øÈ£] ºñ±³ if( pNewScript->mGroupIdx != 0 && pNewScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// °°Àº ±×·ì¿¡ ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return false; /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pNewScript->mType == eINFLUENCETYPE_BUF || pNewScript->mType == eINFLUENCETYPE_DEBUF ) ) return false; /// pc¹æ ¹öÇÁ°¡ ±×·ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pNewScript->mType == eINFLUENCETYPE_PC ) return false; if( pNewScript->mType == eINFLUENCETYPE_CASH || pNewScript->mType == eINFLUENCETYPE_PC ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } /// [±×·ìÈ¿·Â°ª] ºñ±³ if( pNewScript->mGroupOrder >= pHaveScript->mGroupOrder ) { pHaveInf->NoStatusCalc(); /// ±âÁ¸ÀÌ ÀÛÀ¸¸é ±âÁ¸ »èÁ¦ DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } else /// ±âÁ¸ÀÌ Å«°æ¿ì ½Å±Ô »ý¼º¾ÈÇϰí Á¾·á return false; } } } /// »ý¼º unsigned long plusTime = 0; cInfluenceObject* pNewObject = new cInfluenceObject; uniqueIdx = mInfluenceGen.GeneratIdx(); if( !pNewObject->Init( attacker, target, uniqueIdx, infClassIdx, skillClassIdx, eSWITCHTYPE_NORMAL, 0, 0, &plusTime ) ) { SAFE_DELETE( pNewObject ); return false; } if( !( mInfluenceMap.Insert( uniqueIdx, pNewObject ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence mInfluenceMap duplicate"); SAFE_DELETE( pNewObject ); return false; } /// Ÿ°Ù È¿°ú ¸®½ºÆ®¿¡ Ãß°¡ if( pTarget->AddInfluence( pNewObject ) == false ) { NETWORK2->PostServerEvent( "cSkillManager::AddInfluence pTarget[%d,%d]->AddSkillInfluence[%d,%d] == false", target.type, target.index, uniqueIdx, infClassIdx ); return false; } if( pNewScript->mType == eINFLUENCETYPE_CASH && target.type == eOBJECTTYPE_PLAYER ) SKILLMANAGER->SavePlayerInfluence( target.index, uniqueIdx, false ); if( msgSend == true ) { if( pInf != NULL ) { pInf->mTarget = target; pInf->mAttacker = attacker; pInf->mUniqueIdx = uniqueIdx; pInf->mInfluenceClassIdx = infClassIdx; pInf->mAuraSkillClassIdx = 0; pInf->mDeleteType = pNewObject->GetDeleteType(); pInf->mPlusTime = plusTime; pInf->mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); pInf->mRealEndTime = tTime; } else { MSG_SYN_INFLUENCE_CREATE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_CREATE_SYN; msg.mTarget = target; msg.mAttacker = attacker; msg.mUniqueIdx = uniqueIdx; msg.mInfluenceClassIdx = infClassIdx; msg.mAuraSkillClassIdx = 0; msg.mDeleteType = pNewObject->GetDeleteType(); msg.mPlusTime = plusTime; msg.mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); msg.mRealEndTime = tTime; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } } } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ bool calcStatus = false; for( int i = 0 ; i < colNum ; ++i ) { if( ApplyInfluence( pAttacker, pTarget, uniqueIdx, infClassIdx, type[i], value[i] ) == true ) calcStatus = true; } ////////////////////////////////////////////////////////////////////////// /// ½ºÅÝ °è»ê if( calcStatus == true ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) STATUSCALC->CalcPlayerExtensionGlobal( pTarget->GetObject() ); else if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) STATUSCALC->CalcMonster( target.index ); else assert(NULL); } if( EndVehicle == true ) { ((cPlayer*)pTarget)->EndVehicleClient( false ); } return true; } unsigned long cSkillManager::AddInfSwitch( sObject attacker, sObject target, unsigned long infClassIdx, unsigned long skillClassIdx, bool msgSend ) { ////////////////////////////////////////////////////////////////////////// /// ÂüÁ¶ µ¥ÀÌŸ ·Îµå /// ½Å±ÔÈ¿°ú ½ºÅ©¸³Æ® sInfluenceScript* pNewScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pNewScript == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pNewScript[%d]==NULL", infClassIdx ); return 0; } const int colNum = 3; long type[colNum] = { pNewScript->mStatusPlusIdx1, pNewScript->mStatusPlusIdx2, pNewScript->mStatusPlusIdx3 }; long value[colNum] = { pNewScript->mValue1, pNewScript->mValue2, pNewScript->mValue3 }; /// °ø°ÝÀÚ, Ÿ°Ù Æ÷ÀÎÅÍ cBaseObject* pAttacker = OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfSwitch pAttacker[%d,%d]==NULL", attacker.type, attacker.index ); return 0; } if( pAttacker->GetStateDie() == true ) return 0; cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( !pTarget ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pTarget[%d,%d]==NULL", target.type, target.index ); return 0; } ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼ººÎ cHashSet* pInfluenceSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); /// ÀÚ½ÅÀÌ ÄѵР¿À¶ó ¸ÕÀú üũ while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceObject==NULL Aura" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveScript ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceScript==NULL Aura" ); continue; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ Áߺ¹Ã¼Å© if( pHaveScript->mNotOverlapGroupIdx != 0 && pHaveScript->mNotOverlapGroupIdx == pNewScript->mNotOverlapGroupIdx ) { /// °ø°ÝÀÚµµ °°À¸¸é È¿°ú Á¦°Å if( pHaveInf->GetAttacker().index == attacker.index && pHaveInf->GetAttacker().type == attacker.type ) { /// Áߺ¹ ºÒ°¡ Àε¥ ±âÁ¸ º¸À¯È¿°ú°¡ ij½Ã ¹öÇÁÀÌ¸é ½Å±ÔÈ¿°ú »ý¼º ¾È½ÃÅ´ if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return 0; DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } } } begin = pInfluenceSet->Begin(); end = pInfluenceSet->End(); while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceObject==NULL" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveScript ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceScript==NULL" ); continue; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ È¿·Â±×·ì ºñ±³ if( pNewScript->mGroupIdx != 0 && pNewScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// °°Àº Áߺ¹ºÒ°¡¿¡ ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return false; /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pNewScript->mType == eINFLUENCETYPE_BUF || pNewScript->mType == eINFLUENCETYPE_DEBUF ) ) return false; /// pc¹æ ¹öÇÁ°¡ Áߺ¹ºÒ°¡ ±×·ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pNewScript->mType == eINFLUENCETYPE_PC ) return false; if( pNewScript->mType == eINFLUENCETYPE_CASH || pNewScript->mType == eINFLUENCETYPE_PC ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } /// ½Å±Ô °¡ ´õ ³ô°Å³ª °°À¸¸é ½Å±Ô »ý¼º(±âÁ¸»èÁ¦) if( pNewScript->mGroupOrder >= pHaveScript->mGroupOrder ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } else return 0; } } cInfluenceObject* pNewObject = new cInfluenceObject; unsigned long uniqueIdx = mInfluenceGen.GeneratIdx(); if( !pNewObject->Init( attacker, target, uniqueIdx, infClassIdx, skillClassIdx, eSWITCHTYPE_PARENT, 0, 0, NULL ) ) { SAFE_DELETE( pNewObject ); return 0; } if( !( mInfluenceMap.Insert( uniqueIdx, pNewObject ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence mInfluenceMap duplicate"); SAFE_DELETE( pNewObject ); return 0; } /// Ÿ°Ù È¿°ú ¸®½ºÆ®¿¡ Ãß°¡ if( pTarget->AddInfluence( pNewObject ) == false ) { NETWORK2->PostServerEvent( "cSkillManager::AddInfluence pTarget[%d,%d]->AddSkillInfluence[%d,%d] == false", target.type, target.index, uniqueIdx, infClassIdx ); return 0; } if( msgSend == true ) { MSG_SYN_INFLUENCE_CREATE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_CREATE_SYN; msg.mTarget = target; msg.mAttacker = attacker; msg.mUniqueIdx = uniqueIdx; msg.mInfluenceClassIdx = infClassIdx; msg.mAuraSkillClassIdx = skillClassIdx; msg.mDeleteType = pNewObject->GetDeleteType(); msg.mPlusTime = 0; msg.mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); msg.mRealEndTime = tTime; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ bool calcStatus = false; for( int i = 0 ; i < colNum ; ++i ) { if( ApplyInfluence( pAttacker, pTarget, uniqueIdx, infClassIdx, type[i], value[i] ) == true ) calcStatus = true; } ////////////////////////////////////////////////////////////////////////// /// ½ºÅÝ °è»ê if( calcStatus == true ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) STATUSCALC->CalcPlayerExtensionGlobal( pTarget->GetObject() ); else if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) STATUSCALC->CalcMonster( target.index ); else assert(NULL); } return uniqueIdx; } bool cSkillManager::AddInfChildAura( sObject attacker, sObject target, unsigned long infClassIdx, unsigned long skillClassIdx, unsigned long parentIdx, bool msgSend ) { ////////////////////////////////////////////////////////////////////////// /// ÂüÁ¶ µ¥ÀÌŸ ·Îµå /// ½Å±ÔÈ¿°ú ½ºÅ©¸³Æ® sInfluenceScript* pNewScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pNewScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura pNewScript[%d]==NULL", infClassIdx ); return false; } const int colNum = 3; long type[colNum] = { pNewScript->mStatusPlusIdx1, pNewScript->mStatusPlusIdx2, pNewScript->mStatusPlusIdx3 }; long value[colNum] = { pNewScript->mValue1, pNewScript->mValue2, pNewScript->mValue3 }; /// °ø°ÝÀÚ, Ÿ°Ù Æ÷ÀÎÅÍ cBaseObject* pAttacker = OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura pAttacker[%d,%d]==NULL", attacker.type, attacker.index ); return false; } if( pAttacker->GetStateDie() == true ) return false; cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( !pTarget ) { NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura pTarget[%d,%d]==NULL", target.type, target.index ); return false; } ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼ººÎ cHashSet* pInfluenceSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura pHaveInfluenceObject==NULL" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveScript ) { NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura pHaveInfluenceScript==NULL" ); continue; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ È¿·Â±×·ì ºñ±³ if( pNewScript->mGroupIdx != 0 && pNewScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// °°Àº Áߺ¹ºÒ°¡¿¡ ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return false; /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pNewScript->mType == eINFLUENCETYPE_BUF || pNewScript->mType == eINFLUENCETYPE_DEBUF ) ) return false; /// pc¹æ ¹öÇÁ°¡ Áߺ¹ºÒ°¡ ±×·ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pNewScript->mType == eINFLUENCETYPE_PC ) return false; if( pNewScript->mType == eINFLUENCETYPE_CASH || pNewScript->mType == eINFLUENCETYPE_PC ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } /// ½Å±Ô °¡ ´õ ³ôÀ¸¸é ½Å±Ô »ý¼º(±âÁ¸»èÁ¦) if( pNewScript->mGroupOrder > pHaveScript->mGroupOrder ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } else return false; } } cInfluenceObject* pNewObject = new cInfluenceObject; unsigned long uniqueIdx = mInfluenceGen.GeneratIdx(); if( !pNewObject->Init( attacker, target, uniqueIdx, infClassIdx, skillClassIdx, eSWITCHTYPE_CHILD, parentIdx, 0, NULL ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura pNewInfluenceObject->Init err"); SAFE_DELETE( pNewObject ); return false; } if( !( mInfluenceMap.Insert( uniqueIdx, pNewObject ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfChildAura mInfluenceMap duplicate"); SAFE_DELETE( pNewObject ); return false; } /// Ÿ°Ù È¿°ú ¸®½ºÆ®¿¡ Ãß°¡ if( pTarget->AddInfluence( pNewObject ) == false ) { NETWORK2->PostServerEvent( "cSkillManager::AddInfChildAura pTarget[%d,%d]->AddSkillInfluence[%d,%d] == false", target.type, target.index, uniqueIdx, infClassIdx ); return false; } if( msgSend == true ) { MSG_SYN_INFLUENCE_CREATE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_CREATE_SYN; msg.mTarget = target; msg.mAttacker = attacker; msg.mUniqueIdx = uniqueIdx; msg.mInfluenceClassIdx = infClassIdx; msg.mAuraSkillClassIdx = 0; msg.mDeleteType = pNewObject->GetDeleteType(); msg.mPlusTime = 0; msg.mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); msg.mRealEndTime = tTime; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ bool calcStatus = false; for( int i = 0 ; i < colNum ; ++i ) { if( ApplyInfluence( pAttacker, pTarget, uniqueIdx, infClassIdx, type[i], value[i] ) == true ) calcStatus = true; } ////////////////////////////////////////////////////////////////////////// /// ½ºÅÝ °è»ê if( calcStatus == true ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) STATUSCALC->CalcPlayerExtensionGlobal( pTarget->GetObject() ); else if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) STATUSCALC->CalcMonster( target.index ); else assert(NULL); } return true; } bool cSkillManager::AddInfluenceTotem( sObject attacker, sObject target, unsigned long infClassIdx, unsigned long skillClassIdx, unsigned long parentIdx, bool msgSend, unsigned long continuanceTime, sInfluenceCreate* pInf ) { ////////////////////////////////////////////////////////////////////////// /// ÂüÁ¶ µ¥ÀÌŸ ·Îµå sInfluenceScript* pNewScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pNewScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::AddInfluence pNewScript[%d]==NULL", infClassIdx ); return false; } const int colNum = 3; long type[colNum] = { pNewScript->mStatusPlusIdx1, pNewScript->mStatusPlusIdx2, pNewScript->mStatusPlusIdx3 }; long value[colNum] = { pNewScript->mValue1, pNewScript->mValue2, pNewScript->mValue3 }; /// °ø°ÝÀÚ, Ÿ°Ù Æ÷ÀÎÅÍ cBaseObject* pAttacker = OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) return false; if( pAttacker->GetStateDie() == true ) return false; cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( !pTarget ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pTarget[%d,%d]==NULL", target.type, target.index ); return false; } ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼º üũºÎ for( int i = 0 ; i < colNum ; ++i ) { /// ¸é¿ªÃ¼Å© if( target.type == eOBJECTTYPE_MONSTER ) { /// ¸é¿ª üũ if( ((cMonster*)pTarget)->IsImmuneApplyType( pNewScript->mType, type[i] ) == true ) return false; if( ((cMonster*)pTarget)->IsImmuneKind( pNewScript->mTypeDetail ) == true ) return false; if( eSTATUSPLUS_CHANGE_MONSTER == type[i] ) return false; } else if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayer = (cPlayer*)pTarget; /// ¸é¿ª üũ if( pPlayer->IsImmuneApplyType( pNewScript->mType, type[i] ) == true ) return false; if( pPlayer->IsImmuneKind( pNewScript->mTypeDetail ) == true ) return false; } } ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼ººÎ cHashSet* pInfluenceSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceObject==NULL" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveScript ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceScript==NULL" ); continue; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ È¿·Â±×·ì ºñ±³ if( pNewScript->mGroupIdx != 0 && pNewScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// °°Àº Áߺ¹ºÒ°¡¿¡ ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return false; /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pNewScript->mType == eINFLUENCETYPE_BUF || pNewScript->mType == eINFLUENCETYPE_DEBUF ) ) return false; /// pc¹æ ¹öÇÁ°¡ Áߺ¹ºÒ°¡ ±×·ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pNewScript->mType == eINFLUENCETYPE_PC ) return false; if( pNewScript->mType == eINFLUENCETYPE_CASH || pNewScript->mType == eINFLUENCETYPE_PC ) { pHaveInf->NoStatusCalc(); DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } /// ½Å±Ô °¡ ´õ ³ôÀ¸¸é ½Å±Ô »ý¼º(±âÁ¸»èÁ¦) if( pNewScript->mGroupOrder > pHaveScript->mGroupOrder ) { DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } else return false; } } cInfluenceObject* pNewObject = new cInfluenceObject; unsigned long uniqueIdx = mInfluenceGen.GeneratIdx(); if( !pNewObject->Init( attacker, target, uniqueIdx, infClassIdx, skillClassIdx, eSWITCHTYPE_TOTEM, parentIdx, continuanceTime, NULL ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pNewInfluenceObject->Init err"); SAFE_DELETE( pNewObject ); return false; } if( !( mInfluenceMap.Insert( uniqueIdx, pNewObject ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence mInfluenceMap duplicate"); SAFE_DELETE( pNewObject ); return false; } /// Ÿ°Ù È¿°ú ¸®½ºÆ®¿¡ Ãß°¡ if( pTarget->AddInfluence( pNewObject ) == false ) { NETWORK2->PostServerEvent( "cSkillManager::AddInfluence pTarget[%d,%d]->AddSkillInfluence[%d,%d] == false", target.type, target.index, uniqueIdx, infClassIdx ); return false; } if( msgSend == true ) { if( pInf != NULL ) { pInf->mTarget = target; pInf->mAttacker = attacker; pInf->mUniqueIdx = uniqueIdx; pInf->mInfluenceClassIdx = infClassIdx; pInf->mAuraSkillClassIdx = 0; pInf->mDeleteType = pNewObject->GetDeleteType(); pInf->mPlusTime = 0; pInf->mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); pInf->mRealEndTime = tTime; } else { MSG_SYN_INFLUENCE_CREATE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_CREATE_SYN; msg.mTarget = target; msg.mAttacker = attacker; msg.mUniqueIdx = uniqueIdx; msg.mInfluenceClassIdx = infClassIdx; msg.mAuraSkillClassIdx = 0; msg.mDeleteType = pNewObject->GetDeleteType(); msg.mPlusTime = 0; msg.mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); msg.mRealEndTime = tTime; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ bool calcStatus = false; for( int i = 0 ; i < colNum ; ++i ) { if( ApplyInfluence( pAttacker, pTarget, uniqueIdx, infClassIdx, type[i], value[i] ) == true ) calcStatus = true; } ////////////////////////////////////////////////////////////////////////// /// ½ºÅÝ °è»ê if( calcStatus == true ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) STATUSCALC->CalcPlayerExtensionGlobal( pTarget->GetObject() ); else if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) STATUSCALC->CalcMonster( target.index ); else assert(NULL); } return true; } unsigned long cSkillManager::AddInfMode( sObject attacker, sObject target, unsigned long infClassIdx, bool enemyApply, unsigned short range, bool msgSend ) { ////////////////////////////////////////////////////////////////////////// /// ÂüÁ¶ µ¥ÀÌŸ ·Îµå /// ½Å±ÔÈ¿°ú ½ºÅ©¸³Æ® sInfluenceScript* pNewScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pNewScript == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pNewScript[%d]==NULL", infClassIdx ); return 0; } const int colNum = 3; long type[colNum] = { pNewScript->mStatusPlusIdx1, pNewScript->mStatusPlusIdx2, pNewScript->mStatusPlusIdx3 }; long value[colNum] = { pNewScript->mValue1, pNewScript->mValue2, pNewScript->mValue3 }; /// °ø°ÝÀÚ, Ÿ°Ù Æ÷ÀÎÅÍ cBaseObject* pAttacker = OBJECTMANAGER->GetObject( attacker.type, attacker.index ); if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddInfSwitch pAttacker[%d,%d]==NULL", attacker.type, attacker.index ); return 0; } if( pAttacker->GetStateDie() == true ) return 0; cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( !pTarget ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pTarget[%d,%d]==NULL", target.type, target.index ); return 0; } ////////////////////////////////////////////////////////////////////////// /// È¿°ú °´Ã¼ »ý¼ººÎ cHashSet* pInfluenceSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); /// ÀÚ½ÅÀÌ ÄѵР¿À¶ó ¸ÕÀú üũ while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceObject==NULL Aura" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveScript ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceScript==NULL Aura" ); continue; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ Áߺ¹Ã¼Å© if( pHaveScript->mNotOverlapGroupIdx != 0 && pHaveScript->mNotOverlapGroupIdx == pNewScript->mNotOverlapGroupIdx ) { /// °ø°ÝÀÚµµ °°À¸¸é È¿°ú Á¦°Å if( pHaveInf->GetAttacker().index == attacker.index && pHaveInf->GetAttacker().type == attacker.type ) { /// Áߺ¹ ºÒ°¡ Àε¥ ±âÁ¸ º¸À¯È¿°ú°¡ ij½Ã ¹öÇÁÀÌ¸é ½Å±ÔÈ¿°ú »ý¼º ¾È½ÃÅ´ if( pHaveScript->mType == eINFLUENCETYPE_CASH ) return 0; DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } } } begin = pInfluenceSet->Begin(); end = pInfluenceSet->End(); while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceObject==NULL" ); continue; } /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveScript ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pHaveInfluenceScript==NULL" ); continue; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ È¿·Â±×·ì ºñ±³ if( pNewScript->mGroupIdx != 0 && pNewScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// ½Å±Ô °¡ ´õ ³ô°Å³ª °°À¸¸é ½Å±Ô »ý¼º(±âÁ¸»èÁ¦) if( pNewScript->mGroupOrder >= pHaveScript->mGroupOrder ) { DeleteInfluence( target, pHaveInf->GetUniqueIdx() ); break; } else return 0; } } cInfluenceObject* pNewObject = new cInfluenceObject; unsigned long uniqueIdx = mInfluenceGen.GeneratIdx(); if( !pNewObject->Init( attacker, target, uniqueIdx, infClassIdx, 0, eSWITCHTYPE_PARENT, 0, 0, NULL ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence pNewInfluenceObject->Init err"); SAFE_DELETE( pNewObject ); return 0; } if( enemyApply == true ) pNewObject->AddModeType( eAPPLYTYPE_ENEMY, range ); else pNewObject->AddModeType( eAPPLYTYPE_BUDDY, range ); if( !( mInfluenceMap.Insert( uniqueIdx, pNewObject ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddInfluence mInfluenceMap duplicate"); SAFE_DELETE( pNewObject ); return 0; } /// Ÿ°Ù È¿°ú ¸®½ºÆ®¿¡ Ãß°¡ if( pTarget->AddInfluence( pNewObject ) == false ) { NETWORK2->PostServerEvent( "cSkillManager::AddInfluence pTarget[%d,%d]->AddSkillInfluence[%d,%d] == false", target.type, target.index, uniqueIdx, infClassIdx ); return 0; } if( msgSend == true ) { MSG_SYN_INFLUENCE_CREATE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_CREATE_SYN; msg.mTarget = target; msg.mAttacker = attacker; msg.mUniqueIdx = uniqueIdx; msg.mInfluenceClassIdx = infClassIdx; msg.mAuraSkillClassIdx = 0; msg.mDeleteType = pNewObject->GetDeleteType(); msg.mPlusTime = 0; msg.mIsRealTime = pNewObject->IsRealTime(); tm tmTime = TIMER->ConvertTStoTM( pNewObject->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); msg.mRealEndTime = tTime; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ bool calcStatus = false; for( int i = 0 ; i < colNum ; ++i ) { if( ApplyInfluence( pAttacker, pTarget, uniqueIdx, infClassIdx, type[i], value[i] ) == true ) calcStatus = true; } ////////////////////////////////////////////////////////////////////////// /// ½ºÅÝ °è»ê if( calcStatus == true ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) STATUSCALC->CalcPlayerExtensionGlobal( pTarget->GetObject() ); else if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) STATUSCALC->CalcMonster( target.index ); else assert(NULL); } return uniqueIdx; } int cSkillManager::ItemCheckAddInf( cBaseObject* pAttacker, cBaseObject* pTarget, unsigned long infClassIdx ) { if( pAttacker == NULL ) { NETWORK2->PostServerEvent("cSkillManager::ItemCheckAddInf pAttacker == NULL"); return ERROR_ITEM_USE_SKILL_SYSTEM; } if( pTarget == NULL ) { NETWORK2->PostServerEvent("cSkillManager::ItemCheckAddInf pTarget == NULL"); return ERROR_ITEM_USE_SKILL_SYSTEM; } if( pAttacker->GetStateDie() == true ) { NETWORK2->PostServerEvent("cSkillManager::ItemCheckAddInf pAttacker->GetStateDie() == true"); return ERROR_ITEM_USE_SKILL_SYSTEM; } const int colNum = 3; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pScript == NULL ) { NETWORK2->PostServerEvent("cSkillManager::ItemCheckAddInf pScript == NULL[%d]", infClassIdx); return ERROR_ITEM_USE_SKILL_SYSTEM; } long type[colNum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; long value[colNum] = { pScript->mValue1, pScript->mValue2, pScript->mValue3 }; for( int i = 0 ; i < colNum ; ++i ) { /// Á×¾úÀ»¶§¸¸ °¡´ÉÇÑ È¿°ú üũ if( pTarget->GetStateDie() == true ) { switch( type[i] ) { case eSTATUSPLUS_RESURRECTION_HP_PLUS: case eSTATUSPLUS_RESURRECTION_HP_PER: case eSTATUSPLUS_RESURRECTION_MP_PLUS: case eSTATUSPLUS_RESURRECTION_MP_PER: if( pTarget->GetObjectType() != eOBJECTTYPE_PLAYER || value[i] <= 0 ) return ERROR_ITEM_USE_SKILL_STATE; default: return ERROR_ITEM_USE_SKILL_STATE; } } /// Á¤»óÀûÀÎ »óÅÂÀ϶§ È¿°ú üũ switch( type[i] ) { case eSTATUSPLUS_CHANGE_MONSTER: if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayer = (cPlayer*)pTarget; if( !(pPlayer->GetState() == eOBJECT_STATE_IDLE || pPlayer->GetState() == ePLAYER_STATE_ITEMPICK ) ) return ERROR_ITEM_USE_SKILL_STATE; if( pPlayer->GetJumpEndTime() > NETWORK2->GetAccumTime() ) return ERROR_ITEM_USE_SKILL_STATE; /// //if( pPlayer->IsVehicle() == true ) //{ // return false; //} } break; } } cHashSet* pInfluenceSet = pTarget->GetInfluenceSet(); /// Áߺ¹/±×·ì üũ tHashSet::cIterator begin = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); while( begin != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® cInfluenceObject* pHaveInf = GetInfluence( *begin++ ); if( !pHaveInf ) continue; /// º¸À¯ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸ sInfluenceScript* pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveInf->GetInfluenceClassIdx() ); if( !pHaveInf ) continue; bool notOverLap = false; /// Áߺ¹ ºÒ°¡ÀÎÁö üũ if( pScript->mNotOverlapGroupIdx != 0 ) { /// ±âº» Áߺ¹ºÒ°¡ ±×·ì üũ °°Àº°æ¿ì¸é °É¼ö ¾ø´Ù. if( pHaveScript->mNotOverlapGroupIdx == pScript->mNotOverlapGroupIdx ) notOverLap = true; if( notOverLap == false ) { if( pScript->mOverlapScriptIdx != 0 ) { if( SKILLSCRIPT->IsInfOverLap( pScript->mOverlapScriptIdx, pHaveScript->mNotOverlapGroupIdx ) == true ) notOverLap = true; } } if( notOverLap == false ) { if( pHaveScript->mOverlapScriptIdx != 0 ) { if( SKILLSCRIPT->IsInfOverLap( pHaveScript->mOverlapScriptIdx, pScript->mNotOverlapGroupIdx ) == true ) notOverLap = true; } } } /// ¹öÇÁÁ¾·ùº° ¿ì¼±¼øÀ§ : ij½Ã > PC > ¹öÇÁ,µð¹öÇÁ /// °°Àº [Áߺ¹ºÒ°¡±×·ì] ÀÎ °æ¿ì if( notOverLap == true ) { /// °°Àº Áߺ¹ºÒ°¡¿¡ ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) { if( pScript->mType == eINFLUENCETYPE_CASH ) return ERROR_ITEM_USE_SKILL_DUPLICATE; else return ERROR_ITEM_USE_SKILL_GROUPORDER; } /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pScript->mType == eINFLUENCETYPE_BUF || pScript->mType == eINFLUENCETYPE_DEBUF ) ) return ERROR_ITEM_USE_SKILL_PCOVER; /// pc¹æ ¹öÇÁ°¡ Áߺ¹ºÒ°¡ ±×·ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pScript->mType == eINFLUENCETYPE_PC ) return ERROR_ITEM_USE_SKILL_PCSCRIPT; } /// º¸À¯Çϰí ÀÖ´Â È¿°ú¿Í ½Å±Ô È¿°úÀÇ È¿·Â±×·ì ºñ±³ if( pScript->mGroupIdx != 0 && pScript->mGroupIdx == pHaveScript->mGroupIdx ) { /// °°Àº ÀÌ¹Ì °É·ÁÀÖ´Â ¹öÇÁ°¡ Äɽà ŸÀÔÀÌ¸é »õ·Î °É¼ö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_CASH ) { if( pScript->mType == eINFLUENCETYPE_CASH ) return ERROR_ITEM_USE_SKILL_DUPLICATE; else return ERROR_ITEM_USE_SKILL_GROUPORDER; } /// ÀϹݹöÇÁ°¡ º¸À¯ÁßÀÎ pc¹æ¹öÇÁ¸¦ ¾ø¿¤¼ö ¾ø´Ù if( pHaveScript->mType == eINFLUENCETYPE_PC && ( pScript->mType == eINFLUENCETYPE_BUF || pScript->mType == eINFLUENCETYPE_DEBUF ) ) return ERROR_ITEM_USE_SKILL_PCOVER; /// pc¹æ ¹öÇÁ°¡ µ¿Àϱ׷ìÀ¸·Î °°ÀÌ ¹­Àϼö ¾ø´Ù. if( pHaveScript->mType == eINFLUENCETYPE_PC && pScript->mType == eINFLUENCETYPE_PC ) return ERROR_ITEM_USE_SKILL_PCSCRIPT; if( pScript->mType == eINFLUENCETYPE_PC || pScript->mType == eINFLUENCETYPE_CASH ) return ERROR_ITEM_USE_INVENTORY_SUCCESS; /// ½Å±Ô °¡ ´õ ³ô°Å³ª °°À¸¸é ½Å±Ô »ý¼º(±âÁ¸»èÁ¦) if( pScript->mGroupOrder < pHaveScript->mGroupOrder ) return ERROR_ITEM_USE_SKILL_GROUPORDER; } } return ERROR_ITEM_USE_INVENTORY_SUCCESS; } bool cSkillManager::ApplyInfluence( cBaseObject* pAttacker, cBaseObject* pTarget, unsigned long infObjectIdx, unsigned long infClassIdx, unsigned long type, long value, bool noProcessApply ) { bool statusCalc = false; if( pAttacker == NULL ) return statusCalc; if( pTarget == NULL ) return statusCalc; if( pAttacker->GetStateDie() == true ) return statusCalc; /// ½ºÅÝ °è»êÀ» ÇÏ´ÂÁö¸¸ üũÇÏ´Â ºÎºÐ if( ( eSTATUSPLUS_STR_PLUS <= type && type <= eSTATUSPLUS_BASE_MAX ) || ( eSTATUSPLUS_STR_PERCENT <= type && type <= eSTATUSPLUS_BASE_PERCENT_MAX ) || eSTATUSPLUS_BASEALL_PLUS == type || ( eSTATUSPLUS_ATK_PLUS <= type && type <= eSTATUSPLUS_BUFF_ETC_MAX ) || eSTATUSPLUS_CHAR_SIZE == type || eSTATUSPLUS_CHANGE_MONSTER == type || ( eSTATUSPLUS_STOPMOVE <= type && type <= eSTATUSPLUS_CONDITIONINDISPOSITION_MAX ) ) { statusCalc = true; } sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pScript == NULL ) return false; /// ÇÁ·Î¼¼½º ½ÃÁ¡¿¡¸¸ hp/mp º¯È­¸¦ Àû¿ëÇÑ´Ù. if( noProcessApply == false ) { switch( type ) { case eSTATUSPLUS_NONSKILL_HPCHANGE_PLUS: { bool die = false; if( value > 0 ) pTarget->HPHeal( value, false, pAttacker->GetObject(), 0, eTAKEDAMAGETYPE_POTION ); else if( value < 0 ) { unsigned long applyDamage = 0; if( DUELMANAGER->DuelLastAttack( pAttacker->GetObject(), pTarget->GetObject(), abs(value), eDAMAGE_NORMAL, &applyDamage ) == false ) pTarget->HPDamage( pAttacker->GetObject(), abs(value), &die, false ); } MSG_SYN_SKILL_NONSKILL_HPCHANGE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_NONSKILL_HPCHANGE_SYN; msg.mInfluenceClassIdx = infClassIdx; msg.mTarget = pTarget->GetObject(); msg.mChangeValue = (short)value; MSG_SYN_SKILL_NONSKILL_HPCHANGE aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = NM_SKILL_NONSKILL_HPCHANGE_AROUND_SYN; aroundMsg.mInfluenceClassIdx = infClassIdx; aroundMsg.mTarget = pTarget->GetObject(); aroundMsg.mChangeValue = (short)value; SendHPMPInf( pTarget, pAttacker->GetObject(), (char*)&msg, sizeof(msg), (char*)&aroundMsg, sizeof(aroundMsg) ); InsertChangeSet( pTarget, pAttacker->GetObject(), eDAMAGE_NORMAL ); //if( pTarget->GetStateDie() == true ) //{ // MSG_SYN_SKILL_APPLY_DIE sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_DIE_SYN; // sync.mAttacker = pTarget->GetSkillLastAttack(); // sync.mDamageKind = pTarget->GetSkillLastKind(); // sync.mTarget = pTarget->GetObject(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} //else //{ // MSG_SYN_SKILL_APPLY_HPMP sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_HPMP_SYN; // sync.mTarget = pTarget->GetObject(); // sync.mHP = pTarget->GetHP(); // sync.mMaxHP = pTarget->GetMaxHP(); // sync.mMP = pTarget->GetMP(); // sync.mMaxMP = pTarget->GetMaxMP(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} } break; case eSTATUSPLUS_NONSKILL_HPCHANGE_PER: { bool die = false; long applyValue = (long)((long)pTarget->GetMaxHP() * value * 0.01f); if( applyValue > 0 ) pTarget->HPHeal( applyValue, false, pAttacker->GetObject(), 0, eTAKEDAMAGETYPE_POTION ); else if( applyValue < 0 ) { unsigned long applyDamage = 0; if( DUELMANAGER->DuelLastAttack( pAttacker->GetObject(), pAttacker->GetObject(), abs(applyValue), eDAMAGE_NORMAL, &applyDamage ) == false ) pTarget->HPDamage( pAttacker->GetObject(), abs(applyValue), &die, false ); } MSG_SYN_SKILL_NONSKILL_HPCHANGE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_NONSKILL_HPCHANGE_SYN; msg.mInfluenceClassIdx = infClassIdx; msg.mTarget = pTarget->GetObject(); msg.mChangeValue = (short)applyValue; MSG_SYN_SKILL_NONSKILL_HPCHANGE aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = NM_SKILL_NONSKILL_HPCHANGE_AROUND_SYN; aroundMsg.mInfluenceClassIdx = infClassIdx; aroundMsg.mTarget = pTarget->GetObject(); aroundMsg.mChangeValue = (short)applyValue; SendHPMPInf( pTarget, pAttacker->GetObject(), (char*)&msg, sizeof(msg), (char*)&aroundMsg, sizeof(aroundMsg) ); InsertChangeSet( pTarget, pAttacker->GetObject(), eDAMAGE_NORMAL ); //if( pTarget->GetStateDie() == true ) //{ // MSG_SYN_SKILL_APPLY_DIE sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_DIE_SYN; // sync.mAttacker = pTarget->GetSkillLastAttack(); // sync.mDamageKind = pTarget->GetSkillLastKind(); // sync.mTarget = pTarget->GetObject(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} //else //{ // MSG_SYN_SKILL_APPLY_HPMP sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_HPMP_SYN; // sync.mTarget = pTarget->GetObject(); // sync.mHP = pTarget->GetHP(); // sync.mMaxHP = pTarget->GetMaxHP(); // sync.mMP = pTarget->GetMP(); // sync.mMaxMP = pTarget->GetMaxMP(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} } break; case eSTATUSPLUS_NONSKILL_MPCHANGE_PLUS: { if( value > 0 ) pTarget->MPHeal( value, false ); else pTarget->MPDamage( abs(value), false ); MSG_SYN_SKILL_NONSKILL_MPCHANGE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_NONSKILL_MPCHANGE_SYN; msg.mInfluenceClassIdx = infClassIdx; msg.mTarget = pTarget->GetObject(); msg.mChangeValue = (short)value; MSG_SYN_SKILL_NONSKILL_MPCHANGE aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = NM_SKILL_NONSKILL_MPCHANGE_AROUND_SYN; aroundMsg.mInfluenceClassIdx = infClassIdx; aroundMsg.mTarget = pTarget->GetObject(); aroundMsg.mChangeValue = (short)value; SendHPMPInf( pTarget, pAttacker->GetObject(), (char*)&msg, sizeof(msg), (char*)&aroundMsg, sizeof(aroundMsg) ); InsertChangeSet( pTarget, pAttacker->GetObject(), eDAMAGE_NORMAL ); //if( pTarget->GetStateDie() == true ) //{ // MSG_SYN_SKILL_APPLY_DIE sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_DIE_SYN; // sync.mAttacker = pTarget->GetSkillLastAttack(); // sync.mDamageKind = pTarget->GetSkillLastKind(); // sync.mTarget = pTarget->GetObject(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} //else //{ // MSG_SYN_SKILL_APPLY_HPMP sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_HPMP_SYN; // sync.mTarget = pTarget->GetObject(); // sync.mHP = pTarget->GetHP(); // sync.mMaxHP = pTarget->GetMaxHP(); // sync.mMP = pTarget->GetMP(); // sync.mMaxMP = pTarget->GetMaxMP(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} } break; case eSTATUSPLUS_NONSKILL_MPCHANGE_PER: { long applyValue = (long)((long)pTarget->GetMaxMP() * value * 0.01f); if( applyValue > 0 ) pTarget->MPHeal( applyValue, false ); else if( applyValue < 0 ) pTarget->MPDamage( abs(applyValue), false ); MSG_SYN_SKILL_NONSKILL_MPCHANGE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_NONSKILL_MPCHANGE_SYN; msg.mInfluenceClassIdx = infClassIdx; msg.mTarget = pTarget->GetObject(); msg.mChangeValue = (short)applyValue; MSG_SYN_SKILL_NONSKILL_MPCHANGE aroundMsg; aroundMsg.Category = NM_SKILL; aroundMsg.Protocol = NM_SKILL_NONSKILL_MPCHANGE_AROUND_SYN; aroundMsg.mInfluenceClassIdx = infClassIdx; aroundMsg.mTarget = pTarget->GetObject(); aroundMsg.mChangeValue = (short)applyValue; SendHPMPInf( pTarget, pAttacker->GetObject(), (char*)&msg, sizeof(msg), (char*)&aroundMsg, sizeof(aroundMsg) ); InsertChangeSet( pTarget, pAttacker->GetObject(), eDAMAGE_NORMAL ); //if( pTarget->GetStateDie() == true ) //{ // MSG_SYN_SKILL_APPLY_DIE sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_DIE_SYN; // sync.mAttacker = pTarget->GetSkillLastAttack(); // sync.mDamageKind = pTarget->GetSkillLastKind(); // sync.mTarget = pTarget->GetObject(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} //else //{ // MSG_SYN_SKILL_APPLY_HPMP sync; // sync.Category = NM_SKILL; // sync.Protocol = NM_SKILL_DAMAGE_APPLY_HPMP_SYN; // sync.mTarget = pTarget->GetObject(); // sync.mHP = pTarget->GetHP(); // sync.mMaxHP = pTarget->GetMaxHP(); // sync.mMP = pTarget->GetMP(); // sync.mMaxMP = pTarget->GetMaxMP(); // NETWORK2->QuickSend( pTarget, (char*)&sync, sizeof(sync) ); //} } break; case eSTATUSPLUS_NONSKILL_DISTRESS_PLUS: { /// Ç÷¹À̾ ¸ó½ºÅÍ¿¡°Ô ¾²´Â °æ¿ì if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { cMonster* pMonster = (cMonster*)pTarget; if( pMonster ) pMonster->AddTakeDamage( pAttacker->GetObject(), 0, value, eTAKEDAMAGETYPE_DAMAGE ); } /// Ç÷¹À̾ Ç÷¹À̾°Ô ¾²´Â °æ¿ì(ÀÚ½ÅÀÌ Àڽſ¡°Ô ¾²´Â°æ¿ìµµ Æ÷ÇÔ) [6/1/2010 Jo_Client] else if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { typedef tHashSet cTargetingMonsterSet; cTargetingMonsterSet targetingMonsterSet; ((cPlayer*)pTarget)->GetTargetingMonster( targetingMonsterSet ); cTargetingMonsterSet::cIterator start = targetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = targetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); cMonster* mon = OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon != NULL ) { mon->AddTakeDamage( pTarget->GetObject(), 0, value, eTAKEDAMAGETYPE_DAMAGE ); } } } } break; case eSTATUSPLUS_NONSKILL_DISTRESS_PER: { /// Ç÷¹À̾ ¸ó½ºÅÍ¿¡°Ô ¾²´Â °æ¿ì¸¸ üũ if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { cMonster* pMonster = (cMonster*)pTarget; if( pMonster ) pMonster->AddDistressPer( pAttacker->GetObject(), value, eTAKEDAMAGETYPE_DAMAGE ); } /// Ç÷¹À̾ Ç÷¹À̾°Ô ¾²´Â °æ¿ì(ÀÚ½ÅÀÌ Àڽſ¡°Ô ¾²´Â°æ¿ìµµ Æ÷ÇÔ) [6/1/2010 Jo_Client] else if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { typedef tHashSet cTargetingMonsterSet; cTargetingMonsterSet targetingMonsterSet; ((cPlayer*)pTarget)->GetTargetingMonster( targetingMonsterSet ); cTargetingMonsterSet::cIterator start = targetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = targetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); cMonster* mon = OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon ) { mon->AddDistressPer( pAttacker->GetObject(), value, eTAKEDAMAGETYPE_DAMAGE ); } } } } break; } } switch( type ) { case eSTATUSPLUS_DISPEL: SKILLMANAGER->DispelInfluence( pTarget->GetObject(), value, pScript->mGroupOrder ); break; case eSTATUSPLUS_RESURRECTION_HP_PLUS: if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) /// Ç÷¹À̾ ºÎȰ { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetStateDie() == true && value > 0 ) { /// ºÎȰ½Ã hpȸº¹·® ¼³Á¤ pPlayer->SkillResurrectionHP( value ); /// Ŭ¶óÀÌ¾ðÆ®¿¡ ºÎȰ ¿äû ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_SKILL_RESURRECTION* sendMsg = (MSG_RES_SKILL_RESURRECTION*)NETWORK2->GetMsgRoot( &handle, pPlayer->GetConnectionIdx( ), NM_SKILL, NM_SKILL_RESURRECTION_RES ); if ( sendMsg != NULL ) { sendMsg->mAttackerIdx = pAttacker->GetObjectID(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_RESURRECTION) ); } } } break; case eSTATUSPLUS_RESURRECTION_HP_PER: if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) /// Ç÷¹À̾îÀÎÁö üũ { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetStateDie() == true && value > 0 && pPlayer->GetMaxHP() > 0) { long resurrectionValue = pPlayer->GetMaxHP() * value / 100; /// ºÎȰ½Ã hpȸº¹·® ¼³Á¤ pPlayer->SkillResurrectionHP( resurrectionValue ); /// Ŭ¶óÀÌ¾ðÆ®¿¡ ºÎȰ ¿äû ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_SKILL_RESURRECTION* sendMsg = (MSG_RES_SKILL_RESURRECTION*)NETWORK2->GetMsgRoot( &handle, pPlayer->GetConnectionIdx( ), NM_SKILL, NM_SKILL_RESURRECTION_RES ); if ( sendMsg != NULL ) { sendMsg->mAttackerIdx = pAttacker->GetObjectID(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_RESURRECTION) ); } } } break; case eSTATUSPLUS_RESURRECTION_MP_PLUS: if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) /// Ç÷¹À̾îÀÎÁö üũ { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetStateDie() == true ) { /// ºÎȰ½Ã mpȸº¹·® ¼³Á¤ /// ¡Ø SkillResurrectionHP °¡ ¼³Á¤µÈ°æ¿ì¸¸ ¼ÂÆÃµÊ pPlayer->SkillResurrectionMP( value ); } } break; case eSTATUSPLUS_RESURRECTION_MP_PER: if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) /// Ç÷¹À̾îÀÎÁö üũ { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetStateDie() == true && value > 0 && pPlayer->GetMaxMP() > 0) { long resurrectionValue = pPlayer->GetMaxMP() * value / 100; /// ºÎȰ½Ã mpȸº¹·® ¼³Á¤ /// ¡Ø SkillResurrectionHP °¡ ¼³Á¤µÈ°æ¿ì¸¸ ¼ÂÆÃµÊ pPlayer->SkillResurrectionMP( resurrectionValue ); } } break; case eSTATUSPLUS_DISPEL_ALL: SKILLMANAGER->DispelInfluenceAll( pTarget->GetObject(), pScript->mGroupOrder ); break; case eSTATUSPLUS_MONSTER_ESCAPE: if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) ((cMonster*)pTarget)->SkillEscape( eSTATUSPLUS_MONSTER_ESCAPE ); break; case eSTATUSPLUS_SWAP_DISTRESS_POINT: { /// Ÿ°Ù°ú ³ªÀÇ ¾î±×·Î Æ÷ÀÎÆ®¸¦ ±³È¯ÇÑ´Ù. if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER && pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { typedef tHashSet cTargetingMonsterSet; cTargetingMonsterSet targetingMonsterSet; ((cPlayer*)pAttacker)->GetTargetingMonster( targetingMonsterSet ); ((cPlayer*)pTarget)->GetTargetingMonster( targetingMonsterSet ); cTargetingMonsterSet::cIterator start = targetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = targetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); cMonster* mon = OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon != NULL ) { mon->SwapDistressPoint( pAttacker->GetObjectID(), pTarget->GetObjectID() ); } } } } break; case eSTATUSPLUS_CHAR_SIZE: break; case eSTATUSPLUS_CHANGE_MONSTER: { if( pTarget->GetObjectType() != eOBJECTTYPE_PLAYER ) return false; cPlayer* pPlayer = (cPlayer*)pTarget; pPlayer->SetChgMonster( infObjectIdx, value ); } break; case eSTATUSPLUS_VEHICLE: { if( pTarget->GetObjectType() != eOBJECTTYPE_PLAYER ) return statusCalc; cPlayer* pPlayer = (cPlayer*)pTarget; pPlayer->SetVehicle( infObjectIdx, value ); } break; case eSTATUSPLUS_ATTACKERTARGETING: { if( pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER && pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) { cMonster* pMonster = (cMonster*)pTarget; pMonster->TargetFixed( pAttacker->GetObjectID(), infObjectIdx ); } } break; } return statusCalc; } void cSkillManager::DispelInfluence( sObject target, unsigned long influenceTypeDetail, unsigned long groupOrder ) { /// Ÿ°Ù Æ÷ÀÎÅÍ È®ÀÎ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) return; /// Ç÷¹À̾îÀÇ º¸À¯ È¿°ú ÇØ½¬¼ÂÀ» Àоî¿È tHashSet* pHashSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pHashSet->Begin(); tHashSet::cIterator end = pHashSet->End(); cInfluenceObject* pHaveObejct = NULL; sInfluenceScript* pHaveScript = NULL; unsigned long uniqueIdx; /// Àüü °Ë»ö while( begin != end ) { uniqueIdx = *begin++; pHaveObejct = SKILLMANAGER->GetInfluence( uniqueIdx ); if( pHaveObejct == NULL ) { assert(NULL); NETWORK2->PostServerEvent("pHaveInfluenceObejct err - unique[%d]", uniqueIdx ); //-/-//InsertDeleteInfluenceObject( pHaveObejct ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } /// º¸À¯ÇÑ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸¸¦ Àоî¿È pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveObejct->GetInfluenceClassIdx() ); if( pHaveScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("DispelInfluence InfluenceClassIdx err - [%d]", pHaveObejct->GetInfluenceClassIdx() ); continue; } /// È¿·Â ±×·ì ºñ±³ if( groupOrder < pHaveScript->mGroupOrder ) continue; /// ÀÔ·ÂÇÑ µð½ºÆç Á¤º¸¿Í º¸À¯ È¿°ú Á¤º¸°¡ °°À¸¸é È¿°ú Á¦°Å if( pHaveScript->mTypeDetail == influenceTypeDetail ) { DeleteInfluence( target, uniqueIdx ); break; } } } void cSkillManager::DispelInfluenceAll( sObject target, unsigned long groupOrder ) { /// Ÿ°Ù Æ÷ÀÎÅÍ È®ÀÎ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) return; /// Ÿ°Ù °´Ã¼ÀÇ º¸À¯ È¿°ú ÇØ½Ã¼ÂÀ» Àоî¿È tHashSet* pHashSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pHashSet->Begin(); tHashSet::cIterator end = pHashSet->End(); cInfluenceObject* pHaveObejct = NULL; sInfluenceScript* pHaveScript = NULL; unsigned long uniqueIdx; /// Àüü °Ë»ö while( begin != end ) { uniqueIdx = *begin++; pHaveObejct = SKILLMANAGER->GetInfluence( uniqueIdx ); if( pHaveObejct == NULL ) { assert(NULL); NETWORK2->PostServerEvent("pHaveInfluenceObejct err - unique[%d]", uniqueIdx ); //-/-//InsertDeleteInfluenceObject( pHaveObejct ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } /// º¸À¯ÇÑ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸¸¦ Àоî¿È pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveObejct->GetInfluenceClassIdx() ); if( pHaveScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("DispelInfluence InfluenceClassIdx err - [%d]", pHaveObejct->GetInfluenceClassIdx() ); continue; } /// È¿·Â ±×·ì ºñ±³ if( groupOrder < pHaveScript->mGroupOrder ) continue; /// µð½ºÆç Àüü´Â µð¹öÇÁ¸¸ Á¦°ÅÇÑ´Ù. if( pHaveScript->mType != eINFLUENCETYPE_DEBUF ) continue; SKILLMANAGER->DeleteInfluenceList( uniqueIdx ); } } // È¿°ú ¸é¿ª void cSkillManager::ClearImmuneKind( sObject target, unsigned long typeDetail ) { /// Ÿ°Ù Æ÷ÀÎÅÍ È®ÀÎ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) return; /// Ÿ°Ù °´Ã¼ÀÇ º¸À¯ È¿°ú ÇØ½Ã¼ÂÀ» Àоî¿È tHashSet* pHashSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pHashSet->Begin(); tHashSet::cIterator end = pHashSet->End(); cInfluenceObject* pHaveObejct = NULL; sInfluenceScript* pHaveScript = NULL; unsigned long uniqueIdx; /// Àüü °Ë»ö while( begin != end ) { uniqueIdx = *begin++; pHaveObejct = SKILLMANAGER->GetInfluence( uniqueIdx ); if( pHaveObejct == NULL ) { assert(NULL); NETWORK2->PostServerEvent("pHaveInfluenceObejct err - unique[%d]", uniqueIdx ); //-/-//InsertDeleteInfluenceObject( pHaveObejct ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } /// º¸À¯ÇÑ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸¸¦ Àоî¿È pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveObejct->GetInfluenceClassIdx() ); if( pHaveScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("DispelInfluence InfluenceClassIdx err - [%d]", pHaveObejct->GetInfluenceClassIdx() ); continue; } /// ºÐ·ùºñ±³ if( typeDetail != pHaveScript->mTypeDetail ) continue; SKILLMANAGER->DeleteInfluenceList( uniqueIdx ); } } // ¹öÇÁ/µð¹öÇÁ ¸é¿ª void cSkillManager::ClearImmuneApplyType( sObject target, unsigned char InfluenceType, unsigned short applyType ) { /// Ÿ°Ù Æ÷ÀÎÅÍ È®ÀÎ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) return; /// Ÿ°Ù °´Ã¼ÀÇ º¸À¯ È¿°ú ÇØ½Ã¼ÂÀ» Àоî¿È tHashSet* pHashSet = pTarget->GetInfluenceSet(); tHashSet::cIterator begin = pHashSet->Begin(); tHashSet::cIterator end = pHashSet->End(); cInfluenceObject* pHaveObejct = NULL; sInfluenceScript* pHaveScript = NULL; unsigned long uniqueIdx; /// Àüü °Ë»ö while( begin != end ) { uniqueIdx = *begin++; pHaveObejct = SKILLMANAGER->GetInfluence( uniqueIdx ); if( pHaveObejct == NULL ) { assert(NULL); NETWORK2->PostServerEvent("pHaveInfluenceObejct err - unique[%d]", uniqueIdx ); //-/-//InsertDeleteInfluenceObject( pHaveObejct ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } /// º¸À¯ÇÑ È¿°úÀÇ ½ºÅ©¸³Æ® Á¤º¸¸¦ Àоî¿È pHaveScript = SKILLSCRIPT->GetInfluenceInfo( pHaveObejct->GetInfluenceClassIdx() ); if( pHaveScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("DispelInfluence InfluenceClassIdx err - [%d]", pHaveObejct->GetInfluenceClassIdx() ); continue; } /// Áö¼Ó È¿°ú ¹øÈ£ °Ë»ç if( applyType != pHaveScript->mStatusPlusIdx1 && applyType != pHaveScript->mStatusPlusIdx2 != applyType != pHaveScript->mStatusPlusIdx3 ) continue; // µ¿ÀÏ Å¸ÀÔÀÇ È¿°ú¸¸ »èÁ¦ if( pHaveScript->mType != InfluenceType ) continue; SKILLMANAGER->DeleteInfluenceList( uniqueIdx ); } } bool cSkillManager::ClientAuraInfluenceOff( unsigned long playerIdx, unsigned long uniqueIdx, unsigned long skillClassIdx ) { cInfluenceObject* pInfluenceObject = (cInfluenceObject*)mInfluenceMap.GetAt( uniqueIdx ); if( pInfluenceObject == NULL ) return false; /// ½ºÅ³ ¹øÈ£°¡ °°ÀºÁö È®ÀÎ if( pInfluenceObject->GetSkillIdx() != skillClassIdx ) { assert(NULL); NETWORK2->PostServerEvent("ClientAuraInfluenceOff skillClassIdx ERROR [%d,%d,%d]", playerIdx, uniqueIdx, skillClassIdx ); return false;; } /// ºÎ¸ð È¿°úÀÎÁö È®ÀÎ if( pInfluenceObject->GetSwitchType() != eSWITCHTYPE_PARENT ) return false; /// È¿°ú ÁÖÀÎ È®ÀÎ if( pInfluenceObject->GetTarget().index != playerIdx || pInfluenceObject->GetTarget().type != eOBJECTTYPE_PLAYER ) { /// Á¶ÀÛµÈ ¸Þ¼¼Áö assert(NULL); NETWORK2->PostServerEvent("ClientAuraInfluenceOff Hack? player[%d,%d,%d]", playerIdx, uniqueIdx, skillClassIdx ); return false; } cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer == NULL ) return false; SKILLMANAGER->DeleteInfluence( pPlayer->GetObject(), uniqueIdx ); return true; } void cSkillManager::AuraInfluenceOff( unsigned long playerIdx, unsigned long skillClassIdx ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer != NULL ) { cHashSet* pInfSet = pPlayer->GetInfluenceSet(); cHashSet::cIterator begin = pInfSet->Begin(); cHashSet::cIterator end = pInfSet->End(); unsigned long influenceIdx; while( begin != end ) { influenceIdx = *begin++; cInfluenceObject* pInf = GetInfluence( influenceIdx ); if( pInf == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AuraInfluenceOff pInf[%d,%d] == NULL", playerIdx, skillClassIdx ); //-/-//InsertDeleteInfluenceObject( pInf ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } if( pInf->GetSkillIdx() != skillClassIdx ) continue; if( pInf->GetSwitchType() != eSWITCHTYPE_PARENT ) continue; if( pInf->GetTarget().index != playerIdx || pInf->GetTarget().type != eOBJECTTYPE_PLAYER ) continue; SKILLMANAGER->DeleteInfluence( pPlayer->GetObject(), influenceIdx ); return; } } } void cSkillManager::SwitchParentAllOff( unsigned long playerIdx ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer != NULL ) { cHashSet* pInfSet = pPlayer->GetInfluenceSet(); cHashSet::cIterator begin = pInfSet->Begin(); cHashSet::cIterator end = pInfSet->End(); unsigned long influenceIdx; while( begin != end ) { influenceIdx = *begin++; cInfluenceObject* pInf = GetInfluence( influenceIdx ); if( pInf == NULL ) { NETWORK2->PostServerEvent("cSkillManager::SwitchInfAllOff pInf[%d] == NULL", playerIdx ); continue; } if( pInf->GetSwitchType() != eSWITCHTYPE_PARENT ) continue; if( pInf->GetSkillIdx() == 0 ) continue; SKILLMANAGER->DeleteInfluence( pPlayer->GetObject(), influenceIdx ); return; } } } void cSkillManager::InfluenceOff( unsigned long playerIdx, unsigned long influenceClassIdx ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer != NULL ) { cHashSet* pInfSet = pPlayer->GetInfluenceSet(); cHashSet::cIterator i = pInfSet->Begin(); cHashSet::cIterator end = pInfSet->End(); for( ; i != end; ++i ) { unsigned long uniqueIndex = (unsigned long)(*i); cInfluenceObject* pInf = GetInfluence( uniqueIndex ); if( pInf == NULL ) { NETWORK2->PostServerEvent("cSkillManager::InfluenceOff pInf[%d, %d, %d] == NULL", playerIdx, uniqueIndex, influenceClassIdx ); continue; } if( pInf->GetInfluenceClassIdx() != influenceClassIdx ) continue; if( pInf->GetTarget().index != playerIdx || pInf->GetTarget().type != eOBJECTTYPE_PLAYER ) continue; SKILLMANAGER->DeleteInfluence( pPlayer->GetObject(), uniqueIndex ); return; } } } void cSkillManager::DeleteInfluence( sObject target, unsigned long uniqueIdx ) { /// ¡Ø ³ÎÂüÁ¶ ÁÖÀÇ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); unsigned long infClassIdx = 0; bool statusCalc = true; cInfluenceObject* pInf = GetInfluence( uniqueIdx ); if( pInf != NULL ) infClassIdx = pInf->GetInfluenceClassIdx(); if( pTarget != NULL ) { /// Å»°ÍÀ̸é Á¡ÇÁÁß¿¡ Áö¿ï¼ö ¾ø´Ù. const int maximum = 3; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pScript != NULL ) { unsigned short idx[maximum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; for( int i = 0 ; i < maximum ; ++i ) { if( idx[i] == eSTATUSPLUS_VEHICLE ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER && pTarget->GetStateDie() == false ) if( ((cPlayer*)pTarget)->GetJumpEndTime() > NETWORK2->GetAccumTime() ) return; } } } /// Ÿ°Ù °´Ã¼ ¸ñ·Ï¿¡ µé¾îÀÖ´Â È¿°ú ¹øÈ£¸¦ Áö¿î´Ù. pTarget->DeleteInfluence( uniqueIdx ); } /// È¿°ú °´Ã¼¸¦ Áö¿î´Ù. if( pInf != NULL ) { /// ÅäÅÛ¿¡ ÀÇÇØ ¸¸µé¾îÁø È¿°ú¸é »èÁ¦½Ã ºÎ¸ðÅäÅÛ¿¡¼­ ¸ñ·Ï¿¡¼­ »­ if( pInf->GetSwitchType() == eSWITCHTYPE_TOTEM ) pInf->TotemSetEraseTarget(); statusCalc = pInf->IsDelStatusCalc(); if( pTarget ) { /// const int maximum = 3; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pScript != NULL ) { unsigned short idx[maximum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; for( int i = 0 ; i < maximum ; ++i ) { switch( idx[i] ) { case eSTATUSPLUS_CHANGE_MONSTER: { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) ((cPlayer*)pTarget)->EndChgMonster(); } break; case eSTATUSPLUS_VEHICLE: { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) ((cPlayer*)pTarget)->ArightVehicle( true, true ); } break; case eSTATUSPLUS_ATTACKERTARGETING: { /// »ý¼º½Ã Ÿ°Ù °´Ã¼°¡ ¸ó½ºÅÍ ÀÎÁö È®ÀÎ ÇßÀ½ if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) ((cMonster*)pTarget)->TargetFixedEnd(); } } } } else NETWORK2->PostServerEvent("cPlayer::EraseSkillInfluence SKILLSCRIPT->GetInfluenceInfo[%d,%d](%d) == NULL", target.type, target.index, pInf->GetInfluenceClassIdx() ); /// if( pInf->IsSendDelMsg() == true ) { MSG_SYN_INFLUENCE_DELETE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_DELETE_SYN; msg.mUniqueIdx = uniqueIdx; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } } /// Á¦°Å SAFE_DELETE( pInf ); } mInfluenceMap.Erase( uniqueIdx ); if( pTarget != NULL && statusCalc == true ) pTarget->StatusCalc(); } void cSkillManager::DeleteInfluenceClassIdx( sObject target, unsigned long classIdx ) { cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) return; cHashSet* pInfSet = pTarget->GetInfluenceSet(); if( pInfSet == NULL ) return; cHashSet::cIterator start = pInfSet->Begin(); cHashSet::cIterator end = pInfSet->End(); unsigned long infIdx = 0; cInfluenceObject* pInfluence = NULL; while( start != end ) { infIdx = *start++; pInfluence = SKILLMANAGER->GetInfluence( infIdx ); if( pInfluence == NULL ) { NETWORK2->PostServerEvent("cSkillManager::DeleteInfluenceClassIdx pInfluence[%d,%d] == NULL", target.type, target.index ); continue; } if( pInfluence->GetInfluenceClassIdx() != classIdx ) continue; SKILLMANAGER->DeleteInfluenceList( infIdx ); } } void cSkillManager::VehicleDeleteInfluence( sObject target, unsigned long uniqueIdx, bool sendSync ) { /// ¡Ø ³ÎÂüÁ¶ ÁÖÀÇ cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); unsigned long infClassIdx = 0; cInfluenceObject* pInf = GetInfluence( uniqueIdx ); if( pInf != NULL ) infClassIdx = pInf->GetInfluenceClassIdx(); if( pTarget != NULL ) { /// Å»°ÍÀ̸é Á¡ÇÁÁß¿¡ Áö¿ï¼ö ¾ø´Ù. const int maximum = 3; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( infClassIdx ); if( pScript != NULL ) { unsigned short idx[maximum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; for( int i = 0 ; i < maximum ; ++i ) { if( idx[i] == eSTATUSPLUS_VEHICLE ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) if( ((cPlayer*)pTarget)->GetJumpEndTime() > NETWORK2->GetAccumTime() ) return; } } } /// Ÿ°Ù °´Ã¼ ¸ñ·Ï¿¡ µé¾îÀÖ´Â È¿°ú ¹øÈ£¸¦ Áö¿î´Ù. pTarget->DeleteInfluence( uniqueIdx ); pTarget->StatusCalc(); } /// È¿°ú °´Ã¼¸¦ Áö¿î´Ù. if( pInf != NULL ) { if( pTarget ) { /// const int maximum = 3; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL ) { unsigned short idx[maximum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; for( int i = 0 ; i < maximum ; ++i ) { switch( idx[i] ) { case eSTATUSPLUS_CHANGE_MONSTER: { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) ((cPlayer*)pTarget)->EndChgMonster(); } break; case eSTATUSPLUS_VEHICLE: { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) ((cPlayer*)pTarget)->ArightVehicle( sendSync, false ); } break; } } } else NETWORK2->PostServerEvent("cPlayer::EraseSkillInfluence SKILLSCRIPT->GetInfluenceInfo[%d,%d](%d) == NULL", target.type, target.index, pInf->GetInfluenceClassIdx() ); /// if( pInf->IsSendDelMsg() == true ) { MSG_SYN_INFLUENCE_DELETE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_DELETE_SYN; msg.mUniqueIdx = uniqueIdx; NETWORK2->QuickSend( pTarget, (char*)&msg, sizeof(msg) ); } } /// Á¦°Å SAFE_DELETE( pInf ); mInfluenceMap.Erase( uniqueIdx ); } } void cSkillManager::DeleteInfluenceList( unsigned long uniqueIdx ) { cInfluenceObject* pInf = GetInfluence( uniqueIdx ); if( pInf != NULL ) pInf->DelReady(); mDeleteInfluenceAry.PushBack( uniqueIdx ); } void cSkillManager::ClientDeleteInfluenceObject( unsigned long playerIdx, unsigned long uniqueIdx ) { cInfluenceObject* pInfluenceObject = (cInfluenceObject*)mInfluenceMap.GetAt( uniqueIdx ); if( pInfluenceObject == NULL ) return; /// ¸Þ¼¼Áö Áö¿¬À¸·Î ³ª¿Ã¼ö ÀÖÀ½ /// Á¶ÀÛµÈ ¸Þ¼¼Áö if( pInfluenceObject->GetTarget().index != playerIdx || pInfluenceObject->GetTarget().type != eOBJECTTYPE_PLAYER ) { assert(NULL); NETWORK2->PostServerEvent("ClientDeleteInfluenceObject Hack"); return; } sInfluenceScript* pInflueneScript = SKILLSCRIPT->GetInfluenceInfo( pInfluenceObject->GetInfluenceClassIdx() ); if( pInflueneScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("ClientDeleteInfluenceObject GetInfluenceInfo[%d]", pInfluenceObject->GetInfluenceClassIdx() ); return; } /// µð¹öÇÁ »èÁ¦ ¿äû ºÒ°¡ if( pInflueneScript->mType == eINFLUENCETYPE_DEBUF ) return; // ȣĪŸÀÔÀº »èÁ¦ ºÒ°¡ if( pInflueneScript->mTypeDetail == eINFLUENCETYPEDETAIL_NAME ) return; cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer == NULL ) return; /// ȣĪ È¿°ú´Â ȣΰü¸®ÀÚ ÂÊ¿¡¼­ È¿°ú¸¦ ²ö´Ù. if( pPlayer->GetTitleInfIdx() == uniqueIdx ) return; DeleteInfluence( pPlayer->GetObject(), uniqueIdx ); return; } void cSkillManager::SendHPMPInf( cBaseObject* pTarget, sObject attacker, char* targetMsg, unsigned short targetLen, char* aroundMsg, unsigned short aroundLen ) { if( pTarget == NULL ) return; if( targetMsg == NULL ) return; if( aroundMsg == NULL ) return; cPlayer* pPlayer = GRIDMANAGER->FindFirstPlayer( pTarget ); while( pPlayer != NULL ) { /// ÁÖÀ§ Ç÷¹À̾ °ø°ÝÀÚ¸é µ¥¹ÌÁö¸¦ º¸¿©ÁØ´Ù. if( pPlayer->GetObjectID() == attacker.index && pPlayer->GetObjectType() == attacker.type ) { NETWORK2->SendToUser( pPlayer->GetConnectionIdx(), targetMsg, targetLen ); pPlayer = GRIDMANAGER->FindNextPlayer(); continue; } else /// ÁÖÀ§ Ç÷¹À̾ °ø°ÝÀÚÀÇ ÆÄƼÀÌ¸é µ¥¹ÌÁö¸¦ º¸¿©ÁØ´Ù. { if( attacker.type == eOBJECTTYPE_PLAYER ) { cPlayer* pAttacker = GRIDMANAGER->GetPlayer( attacker.index ); if( pAttacker != NULL ) { if( pAttacker->GetPartyIndex() == pPlayer->GetPartyIndex() && pPlayer->GetPartyIndex() != 0 ) { NETWORK2->SendToUser( pPlayer->GetConnectionIdx(), targetMsg, targetLen ); pPlayer = GRIDMANAGER->FindNextPlayer(); continue; } } } } /// ÁÖÀ§ Ç÷¹À̾ Ÿ°ÙÀÌ¸é µ¥¹ÌÁö¸¦ º¸¿©ÁØ´Ù. if( pPlayer->GetObjectID() == pTarget->GetObjectID() && pPlayer->GetObjectType() == pTarget->GetObjectType() ) { if( attacker.index == pTarget->GetObjectID() && attacker.type == pTarget->GetObjectType() ) { pPlayer = GRIDMANAGER->FindNextPlayer(); continue; } else { NETWORK2->SendToUser( pPlayer->GetConnectionIdx(), targetMsg, targetLen ); pPlayer = GRIDMANAGER->FindNextPlayer(); continue; } } else /// ÁÖÀ§ Ç÷¹À̾ Ÿ°ÙÀÇ ÆÄƼÀÌ¸é µ¥¹ÌÁö¸¦ º¸¿©ÁØ´Ù. { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( ((cPlayer*)pTarget)->GetPartyIndex() == pPlayer->GetPartyIndex() && pPlayer->GetPartyIndex() != 0 ) { NETWORK2->SendToUser( pPlayer->GetConnectionIdx(), targetMsg, targetLen ); pPlayer = GRIDMANAGER->FindNextPlayer(); continue; } } } NETWORK2->SendToUser( pPlayer->GetConnectionIdx(), aroundMsg, aroundLen ); pPlayer = GRIDMANAGER->FindNextPlayer(); } } void cSkillManager::CheckActInfluence( eACTSTATUS status, cBaseObject* pObject, cBaseObject* pTarget ) { if( pObject == 0 ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CheckActInfluence pPlayer==NULL" ); return; } if( pObject->GetObjectType() != eOBJECTTYPE_PLAYER && pObject->GetObjectType() != eOBJECTTYPE_HERO ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CheckActInfluence - pPlayer object type is not Player or hero" ); return; } cPlayer* pPlayer = (cPlayer*)pObject; if( pPlayer->GetStateDie() ) return; cHashMap* pActMap = pPlayer->GetActInfluenceMap(); unsigned long checkTime = NETWORK2->GetAccumTime(); if( pActMap->IsEmpty() == true ) return; cHashMap::cIterator i = pActMap->Begin(); cHashMap::cIterator end = pActMap->End(); for( ; i != end; ++i ) { unsigned long actIdx = (unsigned long)((*i).mFirst); unsigned long coolTime = (unsigned long)((*i).mSecond); sActInfluenceScript* pInfo = SKILLSCRIPT->GetActInfluenceInfo(actIdx); if( pInfo == 0 ) continue; /// »óȲ üũ if( pInfo->mActivityState != status ) continue; /// ÄðŸÀÓ Ã¼Å© if( coolTime > checkTime ) continue; /// È®·ü üũ unsigned long randValue = (unsigned long)( RANDOMTABLE->Get( ) * 1000000 ) % 1000000 + 1; if( pInfo->mActivityPer < randValue ) continue; bool sendMsg = false; if( pInfo->mDramaturgyFile != "None" ) sendMsg = true; ////////////////////////////////////////////////////////////////////////// /// ¹ßµ¿ È¿°ú ºÎ¿©... if( pInfo->mApplyType == eAPPLYTYPE_SELF ) { if( AddInfluence( pPlayer->GetObject(), pPlayer->GetObject(), pInfo->mInfIdx, 0, true ) == false ) continue; } else if( pInfo->mApplyType == eAPPLYTYPE_ENEMY ) { if( pInfo->mBoundType == eBOUNDTYPE_NONE ) { /// ¼³Á¤ Ÿ°Ù¿¡ ¹öÇÁ ºÎ¿© if( pTarget == 0 ) continue; if( pTarget->GetStateDie() == true ) continue; if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( pPlayer->IsAttack( pTarget->GetObjectID() ) == false ) continue; } else if( pTarget->GetObjectType() != eOBJECTTYPE_MONSTER ) continue; if( AddInfluence( pPlayer->GetObject(), pTarget->GetObject(), pInfo->mInfIdx, 0, true ) == false ) continue; } else { /// Áß½ÉÀ§Ä¡, ¹üÀ§ °è»ê float tempRange; NiPoint3 centerPos; if( pInfo->mBoundType == eBOUNDTYPE_SELF_TARGET ) { tempRange = OBJECTMANAGER->ObjectSizeRange( pPlayer, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pPlayer->GetXPos(), pPlayer->GetYPos(), pPlayer->Height()); } else if( pInfo->mBoundType == eBOUNDTYPE_TARGET) { if( pTarget == 0 ) continue; tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pTarget->GetXPos(), pTarget->GetYPos(), pTarget->Height()); } else continue; /// Àû ¸®½ºÆ® Ž»ö ¹× ¹öÇÁ/µð¹öÇÁ ºÎ¿© cRangeCheck rangeCheck; rangeCheck.SetRadius( tempRange ); //OBJECTMANAGER->MonsterInCenterPoint( pPlayer->GetMapNumber(), centerPos, tempRange, &targetArr, false ); //OBJECTMANAGER->PlayerInCenterPoint( pPlayer->GetMapNumber(), centerPos, tempRange, &targetArr, 0, false ); mTempActTargetAry.Clear(); GRIDMANAGER->FindPlayers( centerPos.x, centerPos.y, pPlayer->GetMapNumber(), tempRange, &mTempActTargetAry ); for( unsigned long i = 0 ; i < mTempActTargetAry.GetSize() ; ++i ) { sObject pMulTar = { eOBJECTTYPE_PLAYER, mTempActTargetAry[i] }; AddInfluence( pPlayer->GetObject(), pMulTar, pInfo->mInfIdx, 0, true ); } mTempActTargetAry.Clear(); GRIDMANAGER->FindMonsters( centerPos.x, centerPos.y, pPlayer->GetMapNumber(), tempRange, &mTempActTargetAry ); for( unsigned long i = 0 ; i < mTempActTargetAry.GetSize() ; ++i ) { sObject pMulTar = { eOBJECTTYPE_MONSTER, mTempActTargetAry[i] }; AddInfluence( pPlayer->GetObject(), pMulTar, pInfo->mInfIdx, 0, true ); } mTempActTargetAry.Clear(); } } else if( pInfo->mApplyType == eAPPLYTYPE_PARTY ) { if( pInfo->mBoundType == eBOUNDTYPE_NONE ) { AddInfluence( pPlayer->GetObject(), pPlayer->GetObject(), pInfo->mInfIdx, 0, true ); } else { /// Áß½ÉÀ§Ä¡, ¹üÀ§ °è»ê float tempRange; NiPoint3 centerPos; if( pInfo->mBoundType == eBOUNDTYPE_SELF_TARGET ) { tempRange = OBJECTMANAGER->ObjectSizeRange( pPlayer, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pPlayer->GetXPos(), pPlayer->GetYPos(), pPlayer->Height()); } else if( pInfo->mBoundType == eBOUNDTYPE_TARGET) { if( pTarget == 0 ) continue; tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pTarget->GetXPos(), pTarget->GetYPos(), pTarget->Height()); } else continue; cRangeCheck rangeCheck; rangeCheck.SetRadius( tempRange ); /// ÆÄƼ Á¤º¸ Ž»ö ¹× ¹öÇÁ ºÎ¿© cParty* pParty = PARTYMAN->GetParty( pPlayer->GetPartyIndex() ); if( pParty != NULL ) { unsigned long* userArr = pParty->GetUserArr(); unsigned int partyCount = pParty->GetCount(); for( unsigned int i = 0 ; i < partyCount ; ++i ) { /// ÆÄƼ¿øÀ» Àоî¿È cPlayer* pChild = OBJECTMANAGER->GetPlayer( userArr[i] ); if( pChild == NULL ) continue; if( pChild->GetStateDie() == true ) continue; if( pChild->GetGameIn() == false ) continue; /// °Å¸®¾È¿¡ µé¾î¿À´Â °æ¿ì NiPoint3 childPos( pChild->GetXPos(), pChild->GetYPos(), pChild->Height() ); if( rangeCheck.IsRange( childPos, centerPos ) ) AddInfluence( pPlayer->GetObject(), pChild->GetObject(), pInfo->mInfIdx, 0, true ); } } else { /// ÆÄƼ¿¬ÇÕÀ¸·ÎºÎÅÍ Á¤º¸ ÀÐÀ½ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( pPlayer->GetPartyUnionIndex() ); if( partyUnion != NULL ) { unsigned long* userArr = partyUnion->GetGroupArr( pPlayer->GetObjectID() ); for( unsigned int i = 0; i < MAX_PARTYUSER; ++i ) { /// ÆÄƼ¿øÀ» Àоî¿È cPlayer* pChild = OBJECTMANAGER->GetPlayer( userArr[i] ); if( pChild == NULL ) continue; if( pChild->GetStateDie() == true ) continue; if( pChild->GetGameIn() == false ) continue; /// °Å¸®¾È¿¡ µé¾î¿À´Â °æ¿ì NiPoint3 childPos( pChild->GetXPos(), pChild->GetYPos(), pChild->Height() ); if( rangeCheck.IsRange( childPos, centerPos ) ) AddInfluence( pPlayer->GetObject(), pChild->GetObject(), pInfo->mInfIdx, 0, true ); } } else { /// ÆÄƼ ¹× ÆÄƼ À¯´Ï¿Â Á¤º¸°¡ ¾ø´Ù¸é ÀڽŸ¸ °Ç´Ù.. if( AddInfluence( pPlayer->GetObject(), pPlayer->GetObject(), pInfo->mInfIdx, 0, true ) == false ) continue; } } } } else { /// ÇöÀç´Â ¾ÆÀÌÅÛ ¹ßµ¿È¿°ú ÂÊ¿¡¼­´Â »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù [4/6/2010 Jo_Client] /* eAPPLYTYPE_BUFF_SELF: eAPPLYTYPE_DEBUFF_SELF: eAPPLYTYPE_BUFF_ENEMY: eAPPLYTYPE_DEBUFF_ENEMY: eAPPLYTYPE_BUFF_PARTY: eAPPLYTYPE_DEBUFF_PARTY: */ continue; } ////////////////////////////////////////////////////////////////////////// /// ÄðŸÀÓ °»½Å (*i).mSecond = pInfo->mCooltime + checkTime; ////////////////////////////////////////////////////////////////////////// /// msg send if( sendMsg == true ) { MSG_SYN_ACTINFLUNCE_ACTION msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_ACTINFLUENCE_ACTION_SYN; msg.mPlayer = pPlayer->GetObject(); msg.mActIdx = actIdx; NETWORK2->QuickSend( pPlayer, (char*)&msg, sizeof(msg) ); } break; } } void cSkillManager::CheckSkillActInfluence( unsigned long actIdx, cBaseObject* pObject, cBaseObject* pTarget ) { if( pObject == 0 ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CheckSkillActInfluence pPlayer==NULL" ); return; } if( pObject->GetObjectType() != eOBJECTTYPE_PLAYER && pObject->GetObjectType() != eOBJECTTYPE_HERO ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::CheckSkillActInfluence - pPlayer object type is not Player or hero" ); return; } cPlayer* pPlayer = (cPlayer*)pObject; if( pPlayer->GetStateDie() ) return; sActInfluenceScript* pInfo = SKILLSCRIPT->GetActInfluenceInfo( actIdx ); if( pInfo == 0 ) return; /// È®·ü üũ unsigned long randValue = (unsigned long)( RANDOMTABLE->Get( ) * 1000000 ) % 1000000 + 1; if( pInfo->mActivityPer < randValue ) return; bool sendMsg = false; if( pInfo->mDramaturgyFile != "None" ) sendMsg = true; ////////////////////////////////////////////////////////////////////////// /// ¹ßµ¿ È¿°ú ºÎ¿©... if( pInfo->mApplyType == eAPPLYTYPE_SELF ) { if( AddInfluence( pPlayer->GetObject(), pPlayer->GetObject(), pInfo->mInfIdx, 0, true ) == false ) return; } else if( pInfo->mApplyType == eAPPLYTYPE_ENEMY ) { if( pInfo->mBoundType == eBOUNDTYPE_NONE ) { /// ¼³Á¤ Ÿ°Ù¿¡ ¹öÇÁ ºÎ¿© if( pTarget == 0 ) return; if( pTarget->GetStateDie() == true ) return; if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { if( pPlayer->IsAttack( pTarget->GetObjectID() ) == false ) return; } else if( pTarget->GetObjectType() != eOBJECTTYPE_MONSTER ) return; if( AddInfluence( pPlayer->GetObject(), pTarget->GetObject(), pInfo->mInfIdx, 0, true ) == false ) return; } else { /// Áß½ÉÀ§Ä¡, ¹üÀ§ °è»ê float tempRange; NiPoint3 centerPos; if( pInfo->mBoundType == eBOUNDTYPE_SELF_TARGET ) { tempRange = OBJECTMANAGER->ObjectSizeRange( pPlayer, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pPlayer->GetXPos(), pPlayer->GetYPos(), pPlayer->Height()); } else if( pInfo->mBoundType == eBOUNDTYPE_TARGET) { if( pTarget == 0 ) return; tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pTarget->GetXPos(), pTarget->GetYPos(), pTarget->Height()); } else return; /// Àû ¸®½ºÆ® Ž»ö ¹× ¹öÇÁ/µð¹öÇÁ ºÎ¿© cRangeCheck rangeCheck; rangeCheck.SetRadius( tempRange ); mTempActTargetAry.Clear(); GRIDMANAGER->FindPlayers( centerPos.x, centerPos.y, pPlayer->GetMapNumber(), tempRange, &mTempActTargetAry ); for( unsigned long i = 0 ; i < mTempActTargetAry.GetSize() ; ++i ) { sObject pMulTar = { eOBJECTTYPE_PLAYER, mTempActTargetAry[i] }; AddInfluence( pPlayer->GetObject(), pMulTar, pInfo->mInfIdx, 0, true ); } mTempActTargetAry.Clear(); GRIDMANAGER->FindMonsters( centerPos.x, centerPos.y, pPlayer->GetMapNumber(), tempRange, &mTempActTargetAry ); for( unsigned long i = 0 ; i < mTempActTargetAry.GetSize() ; ++i ) { sObject pMulTar = { eOBJECTTYPE_MONSTER, mTempActTargetAry[i] }; AddInfluence( pPlayer->GetObject(), pMulTar, pInfo->mInfIdx, 0, true ); } mTempActTargetAry.Clear(); } } else if( pInfo->mApplyType == eAPPLYTYPE_PARTY ) { if( pInfo->mBoundType == eBOUNDTYPE_NONE ) { AddInfluence( pPlayer->GetObject(), pPlayer->GetObject(), pInfo->mInfIdx, 0, true ); } else { /// Áß½ÉÀ§Ä¡, ¹üÀ§ °è»ê float tempRange; NiPoint3 centerPos; if( pInfo->mBoundType == eBOUNDTYPE_SELF_TARGET ) { tempRange = OBJECTMANAGER->ObjectSizeRange( pPlayer, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pPlayer->GetXPos(), pPlayer->GetYPos(), pPlayer->Height()); } else if( pInfo->mBoundType == eBOUNDTYPE_TARGET) { if( pTarget == 0 ) return; tempRange = OBJECTMANAGER->ObjectSizeRange( pTarget, NULL, pInfo->mBoundDist ); centerPos = NiPoint3( pTarget->GetXPos(), pTarget->GetYPos(), pTarget->Height()); } else return; cRangeCheck rangeCheck; rangeCheck.SetRadius( tempRange ); /// ÆÄƼ Á¤º¸ Ž»ö ¹× ¹öÇÁ ºÎ¿© cParty* pParty = PARTYMAN->GetParty( pPlayer->GetPartyIndex() ); if( pParty != NULL ) { unsigned long* userArr = pParty->GetUserArr(); unsigned int partyCount = pParty->GetCount(); for( unsigned int i = 0 ; i < partyCount ; ++i ) { /// ÆÄƼ¿øÀ» Àоî¿È cPlayer* pChild = OBJECTMANAGER->GetPlayer( userArr[i] ); if( pChild == NULL ) continue; if( pChild->GetStateDie() == true ) continue; if( pChild->GetGameIn() == false ) continue; /// °Å¸®¾È¿¡ µé¾î¿À´Â °æ¿ì NiPoint3 childPos( pChild->GetXPos(), pChild->GetYPos(), pChild->Height() ); if( rangeCheck.IsRange( childPos, centerPos ) ) AddInfluence( pPlayer->GetObject(), pChild->GetObject(), pInfo->mInfIdx, 0, true ); } } else { /// ÆÄƼ¿¬ÇÕÀ¸·ÎºÎÅÍ Á¤º¸ ÀÐÀ½ cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( pPlayer->GetPartyUnionIndex() ); if( partyUnion != NULL ) { unsigned long* userArr = partyUnion->GetGroupArr( pPlayer->GetObjectID() ); for( unsigned int i = 0; i < MAX_PARTYUSER; ++i ) { /// ÆÄƼ¿øÀ» Àоî¿È cPlayer* pChild = OBJECTMANAGER->GetPlayer( userArr[i] ); if( pChild == NULL ) continue; if( pChild->GetStateDie() == true ) continue; if( pChild->GetGameIn() == false ) continue; /// °Å¸®¾È¿¡ µé¾î¿À´Â °æ¿ì NiPoint3 childPos( pChild->GetXPos(), pChild->GetYPos(), pChild->Height() ); if( rangeCheck.IsRange( childPos, centerPos ) ) AddInfluence( pPlayer->GetObject(), pChild->GetObject(), pInfo->mInfIdx, 0, true ); } } else { /// ÆÄƼ ¹× ÆÄƼ À¯´Ï¿Â Á¤º¸°¡ ¾ø´Ù¸é ÀڽŸ¸ °Ç´Ù.. if( AddInfluence( pPlayer->GetObject(), pPlayer->GetObject(), pInfo->mInfIdx, 0, true ) == false ) return; } } } } else { /// ÇöÀç´Â ¾ÆÀÌÅÛ ¹ßµ¿È¿°ú ÂÊ¿¡¼­´Â »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù [4/6/2010 Jo_Client] /* eAPPLYTYPE_BUFF_SELF: eAPPLYTYPE_DEBUFF_SELF: eAPPLYTYPE_BUFF_ENEMY: eAPPLYTYPE_DEBUFF_ENEMY: eAPPLYTYPE_BUFF_PARTY: eAPPLYTYPE_DEBUFF_PARTY: */ return; } ////////////////////////////////////////////////////////////////////////// /// msg send if( sendMsg == true ) { MSG_SYN_ACTINFLUNCE_ACTION msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_ACTINFLUENCE_ACTION_SYN; msg.mPlayer = pPlayer->GetObject(); msg.mActIdx = actIdx; NETWORK2->QuickSend( pPlayer, (char*)&msg, sizeof(msg) ); } } void cSkillManager::InsertChangeSet( cBaseObject* pTarget, sObject attacker, unsigned char damageKind ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { mPlayerChangeSet.Insert( pTarget->GetObjectID() ); cPlayer* pPlayer = (cPlayer*)pTarget; pPlayer->SetSkillLastAttack( attacker, damageKind ); } else if( pTarget->GetObjectType() == eOBJECTTYPE_MONSTER ) { mMonsterChangeSet.Insert( pTarget->GetObjectID() ); cMonster* pMonster = (cMonster*)pTarget; pMonster->SetSkillLastAttack( attacker, damageKind ); } } bool cSkillManager::NeedAddPlayerHaveSkill( unsigned long skillIdx, unsigned char skillStep, /*unsigned long* money,*/ unsigned short* sp ) { /// Ç÷¹ÀÌ¾î ½ºÅ³½ºÅ©¸³Æ® ÂüÁ¶ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( !pSkillInfo ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::NeedAddPlayerHaveSkill pSkillInfo==NULL" ); return false; } /// Ç÷¹ÀÌ¾î ½ºÅ³½ºÅÜ ½ºÅ©¸³Æ® ÂüÁ¶ if( skillStep < 0 || pSkillInfo->mStepCount <= skillStep ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::NeedAddPlayerHaveSkill pSkillInfo->mStepCount ERR" ); return false; } sPlayerSkillStepInfo* pSkillStep = &pSkillInfo->mpSetpInfoArray[skillStep]; if( pSkillStep == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::NeedAddPlayerHaveSkill pSkillStep==NULL" ); return false; } //*money = pSkillStep->mUseMoney; *sp = pSkillStep->mRequireSP; return true; } void cSkillManager::UpdateSkillCoolTime( sObject attacker, unsigned long skillIdx, unsigned char skillStep, unsigned long /*accumTime*/, float speedFactor ) { /// Ç÷¹À̾ »ç¿ë ¸ó½ºÅÍ´Â µû·Î °¡Áö°í ÀÖ´Ù switch( attacker.type ) { case eOBJECTTYPE_HERO: case eOBJECTTYPE_PLAYER: { /// Ç÷¹ÀÌ¾î ½ºÅ³½ºÅ©¸³Æ® ÂüÁ¶ sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( !pSkillInfo ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::UpdateSkillCoolTime pSkillInfo[%d]==NULL", skillIdx ); return; } /// Ç÷¹ÀÌ¾î ½ºÅ³½ºÅÜ ½ºÅ©¸³Æ® ÂüÁ¶ if( skillStep < 0 || pSkillInfo->mStepCount <= skillStep ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::UpdateSkillCoolTime pSkillInfo->mStepCount[%d] ERR", pSkillInfo->mStepCount ); return; } sPlayerSkillStepInfo* pSkillStep = &pSkillInfo->mpSetpInfoArray[skillStep]; cHaveSkillObject* pHaveSkill = GetPlayerHaveSkill( attacker.index, skillIdx ); if( pHaveSkill == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::UpdateSkillCoolTime GetPlayerHaveSkill[%d,%d]", attacker.index, skillIdx ); return; } pHaveSkill->UpdateCoolTime( pSkillStep->mCoolTime, speedFactor ); /// ±×·ì ÄðŸÀÓ Ã¼Å© if( pSkillInfo->mGroupCoolTimeIdx != 0 ) { /// Ç÷¹ÀÌ¾î º¸À¯½ºÅ³ Æ÷ÀÎÆ® ȹµæ cPointerHashMap* pHaveSkillMap = (cPointerHashMap*)GetPlayerHaveSkill( attacker.index ); if( !pHaveSkillMap ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::UpdateSkillCoolTime pHaveSkillMap[%d]==NULL", attacker.index ); return; } /// º¸À¯ ½ºÅ³µéÀÇ ÄðŸÀÓ °ü·Ã Ç׸ñ ¾÷µ¥ÀÌÆ® cPointerHashMap::cIterator begin = pHaveSkillMap->Begin(); cPointerHashMap::cIterator end = pHaveSkillMap->End(); for( ; begin != end ; ++begin ) { cHaveSkillObject* pHave = (cHaveSkillObject*)(*begin).mSecond; if( pHave == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::UpdateSkillCoolTime pHave==NULL" ); continue; } sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( pHave->GetSkillIdx() ); if( pInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::UpdateSkillCoolTime pInfo==NULL" ); continue; } if( pInfo->mGroupCoolTimeIdx == 0 ) continue; if( skillIdx == pHave->GetSkillIdx() ) continue; /// °°Àº ±×·ìÀΰæ¿ì »ç¿ë ½ºÅ³ÀÇ ÄðŸÀÓÀ¸·Î °»½Å if( pSkillInfo->mGroupCoolTimeIdx == pInfo->mGroupCoolTimeIdx ) { sPlayerSkillStepInfo* pStep = &pInfo->mpSetpInfoArray[pHave->GetSkillStep()]; if( pSkillStep->mCoolTime > pStep->mCoolTime ) pHave->UpdateCoolTime( pStep->mCoolTime, speedFactor ); else pHave->UpdateCoolTime( pSkillStep->mCoolTime, speedFactor ); } } } }break; } } void cSkillManager::AddSkillReset( unsigned long playerIdx, unsigned long skillIdx, unsigned char skillStep ) { /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { /// »õ·Î¿î ½ºÅ³¸®½ºÆ®¸¦ ¸¸µë pPlayerHaveSkillMap = new cPointerHashMap; /// »õ·Î ¸¸µç ½ºÅ³¸®½ºÆ®¸¦ ±â·Ï if( !( mPlayerHaveSkillMap.Insert( playerIdx, pPlayerHaveSkillMap ) ) ) { NETWORK2->PostServerEvent("AddSkillReset[%d,%d,%d] - mPlayerHaveSkillMap.Insert error", playerIdx, skillIdx, skillStep ); SAFE_DELETE( pPlayerHaveSkillMap ); return; } } /// º¸À¯½ºÅ³¸®½ºÆ® Á¤º¸¸¦ ±â·Ï cHaveSkillObject* pPlayerHaveSkill = new cHaveSkillObject; pPlayerHaveSkill->Init( skillIdx, skillStep, 0 ); if( !(pPlayerHaveSkillMap->Insert( skillIdx, pPlayerHaveSkill ) ) ) { NETWORK2->PostServerEvent("AddSkillReset[%d,%d,%d] - mPlayerHaveSkillMap.Insert error", playerIdx, skillIdx, skillStep ); SAFE_DELETE( pPlayerHaveSkill ); return; } } bool cSkillManager::SaveSkillCoolTime( unsigned long playerIdx, SKILL_COOLTIME* skillCoolTime ) { skillCoolTime->mCharacterIdx = playerIdx; skillCoolTime->mRetvalue = 0; /// Ç÷¹ÀÌ¾î º¸À¯½ºÅ³ Æ÷ÀÎÆ® ȹµæ cPointerHashMap* pHaveSkillMap = (cPointerHashMap*)GetPlayerHaveSkill( playerIdx ); if( pHaveSkillMap == NULL) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SaveSkillCoolTime pHaveSkillMap==NULL" ); return false; } cPointerHashMap::cIterator begin = pHaveSkillMap->Begin(); cPointerHashMap::cIterator end = pHaveSkillMap->End(); /// º¸À¯½ºÅ³ Æ÷ÀÎÅÍ cHaveSkillObject* pHaveSkill = NULL; long restTime = 0; unsigned long row = 0; for( ; begin != end ; ++begin ) { pHaveSkill = (cHaveSkillObject*)((*begin).mSecond); if( pHaveSkill == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SaveSkillCoolTime pHaveSkill==NULL" ); continue; } /// ±âº» °ø°Ý Åë°ú if( pHaveSkill->GetSkillIdx() <= NORMAL_ATTACK_SKILL_MAX ) continue; /// ³²Àº ÄðŸÀÓÀÌ ¾ø´Â °æ¿ì Åë°ú if( pHaveSkill->DbSaveDataCoolTime() <= NETWORK2->GetAccumTime() ) continue; /// Àç»ç¿ë °¡´É½Ã°£ÀÌ DB_SAVE_COOLTIME msÃÊ ÀÌ»óÀÎ °Íµé¸¸ ÀúÀå restTime = pHaveSkill->DbSaveDataCoolTime() - NETWORK2->GetAccumTime(); if( restTime > DB_SAVE_COOLTIME && pHaveSkill->GetSkillIdx() != 0 ) { skillCoolTime->mTable[row].mSkillIdx = pHaveSkill->GetSkillIdx(); skillCoolTime->mTable[row].mSkillStep = pHaveSkill->GetSkillStep(); skillCoolTime->mTable[row].mEndCoolTime = restTime; ++row; } } skillCoolTime->mRowCount = row; return true; } bool cSkillManager::RestorePlayerSkill( SKILL_SELECT* skillSelect ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( skillSelect->mCharacterIdx ); if( pPlayer == NULL ) return false; ///// º¸À¯¸ñ·Ï Àüü Á¦°Å //if( skillSelect->mRowCount >= 1 ) // ReleasePlayerHaveSkill( skillSelect->mCharacterIdx ); /// ±âº»°ø°Ý(idx:0) ³Ö¾î Áà¾ßÇÔ SKILLMANAGER->AddPlayerHaveSkill( skillSelect->mCharacterIdx, NORMAL_ATTACK_SKILL, SKILL_START_STEP, 0 ); long restTime; for ( long i = 0; i < skillSelect->mRowCount; i++ ) { restTime = skillSelect->mTable[i].mEndCoolTime; /// »ç¿ë °¡´É ½Ã°£ÀÌ µÈ°æ¿ì if( restTime < 0 ) { restTime = 0; } /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( skillSelect->mCharacterIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { /// »õ·Î¿î ½ºÅ³¸®½ºÆ®¸¦ ¸¸µë pPlayerHaveSkillMap = new cPointerHashMap; /// »õ·Î ¸¸µç ½ºÅ³¸®½ºÆ®¸¦ ±â·Ï if( !( mPlayerHaveSkillMap.Insert( skillSelect->mCharacterIdx, pPlayerHaveSkillMap ) ) ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::RestorePlayerSkill mPlayerHaveSkillMap.Insert duplicate" ); SAFE_DELETE( pPlayerHaveSkillMap ); return false; } } if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) { cHaveSkillObject* pPlayerHaveSkill = (cHaveSkillObject*)pPlayerHaveSkillMap->GetAt( skillSelect->mTable[i].mSkillIdx ); if( pPlayerHaveSkill != NULL ) continue; } /// º¸À¯½ºÅ³¸®½ºÆ® Á¤º¸¸¦ ±â·Ï cHaveSkillObject* pPlayerHaveSkill = new cHaveSkillObject; pPlayerHaveSkill->RestoreInit( skillSelect->mTable[i].mSkillIdx, skillSelect->mTable[i].mSkillStep, restTime ); if( !(pPlayerHaveSkillMap->Insert( skillSelect->mTable[i].mSkillIdx, pPlayerHaveSkill ) ) ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::RestorePlayerSkill pPlayerHaveSkillMap.Insert duplicate" ); SAFE_DELETE( pPlayerHaveSkill ); return false; } } //if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) // return AddTutorialHaveSkill( pPlayer ); return true; } bool cSkillManager::AddTutorialHaveSkill( cPlayer* pPlayer ) { /// ½ºÅ©¸³Æ® µ¥ÀÌÅÍ ·Îµå cPArray* pScriptAry = TUTORIALSKILLSCRIPT->GetTutorialSkillArr(); if( pScriptAry == NULL ) return false; unsigned long playerIdx = pPlayer->GetObjectID(); for( unsigned long i = 0; i < pScriptAry->GetSize() ; i++ ) { sTutorialSkill* pTutorial = (sTutorialSkill*)(*pScriptAry)[i]; /// playeridx·Î Ç÷¹À̾ º¸À¯ÇÑ ½ºÅ³¸®½ºÆ® Æ÷ÀÎÅ͸¦ ¾ò¾î¿È cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); /// º¸À¯ÇÑ ½ºÅ³¸®½ºÆ®°¡ ¾øÀ¸¸é if ( !pPlayerHaveSkillMap ) { /// »õ·Î¿î ½ºÅ³¸®½ºÆ®¸¦ ¸¸µë pPlayerHaveSkillMap = new cPointerHashMap; /// »õ·Î ¸¸µç ½ºÅ³¸®½ºÆ®¸¦ ±â·Ï if( !( mPlayerHaveSkillMap.Insert( playerIdx, pPlayerHaveSkillMap ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddTutorialHaveSkill mPlayerHaveSkillMap.Insert duplicate" ); SAFE_DELETE( pPlayerHaveSkillMap ); return false; } } if( pPlayerHaveSkillMap->GetAt( pTutorial->skillIndex ) != NULL ) continue; sPlayerSkillBaseInfo* pBase = SKILLSCRIPT->GetPlayerSkillInfo( pTutorial->skillIndex ); if( pBase == NULL ) { NETWORK2->PostServerEvent("cSkillManager::AddTutorialHaveSkill pBase == NULL[%d]", pTutorial->skillIndex); continue; } if( pBase->mStepCount <= pTutorial->skillStep ) { NETWORK2->PostServerEvent("cSkillManager::AddTutorialHaveSkill pBase->mStepCount < pTutorial->skillStep[%d]"); continue; } sPlayerSkillStepInfo* pStep = &pBase->mpSetpInfoArray[pTutorial->skillStep]; /// Á¾Á· ±¸ºÐ Àִ°æ¿ì if( pBase->mRace != 0 ) /// 0 = ALL { /// Á¾Á· üũ switch( pPlayer->GetRace() ) { case eRACE_HUMAN: if( !( pBase->mRace == eSKILLRACE_HUMAN || pBase->mRace == eSKILLRACE_HUMAN_BEAST || pBase->mRace == eSKILLRACE_HUMAN_ELF ) ) continue; break; case eRACE_BEAST: if( !( pBase->mRace == eSKILLRACE_BEAST || pBase->mRace == eSKILLRACE_HUMAN_BEAST || pBase->mRace == eSKILLRACE_BEAST_ELF ) ) continue; break; case eRACE_ELF: if( !( pBase->mRace == eSKILLRACE_ELF || pBase->mRace == eSKILLRACE_HUMAN_ELF || pBase->mRace == eSKILLRACE_BEAST_ELF ) ) continue; break; default: assert(NULL); continue; } } /// Á÷¾÷±¸ºÐ ÀÖ´Â °æ¿ì if( pStep->mJobType != 0 ) { /// Á÷¾÷À» üũ if( !SKILLSCRIPT->IsPlayerSkillJob( pStep->mJobType, (unsigned long)(pPlayer->GetJob()) ) ) continue; } /// º¸À¯½ºÅ³¸®½ºÆ® Á¤º¸¸¦ ±â·Ï cHaveSkillObject* pPlayerHaveSkill = new cHaveSkillObject; pPlayerHaveSkill->RestoreInit( pTutorial->skillIndex, pTutorial->skillStep, 0 ); if( !(pPlayerHaveSkillMap->Insert( pTutorial->skillIndex, pPlayerHaveSkill ) ) ) { NETWORK2->PostServerEvent("cSkillManager::AddTutorialHaveSkill pPlayerHaveSkillMap.Insert duplicate" ); SAFE_DELETE( pPlayerHaveSkill ); return false; } } return true; } void cSkillManager::SendMsgSkillHaveToPlayer( unsigned long connectionIdx, unsigned long characterIdx ) { HANDLE handle = NULL; MSG_RES_SKILL_LIST* sendMsg = (MSG_RES_SKILL_LIST*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_SKILL, NM_SKILL_LIST_RES ); if ( sendMsg != NULL ) { cPointerHashMap* pPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( characterIdx ); if( pPlayerHaveSkillMap ) { cHaveSkillObject* pPlayerHaveSkill; cPointerHashMap::cIterator start = pPlayerHaveSkillMap->Begin(); cPointerHashMap::cIterator end = pPlayerHaveSkillMap->End(); unsigned char& row = (sendMsg->mRowCount = 0); for( ; start != end ; ++start ) { pPlayerHaveSkill = (cHaveSkillObject*)(*start).mSecond; if( pPlayerHaveSkill == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendMsgSkillHaveToPlayer pPlayerHaveSkill==NULL" ); continue; } if( pPlayerHaveSkill->GetSkillIdx() == 0 ) continue; sendMsg->mTable[row].mSkillIdx = pPlayerHaveSkill->GetSkillIdx(); sendMsg->mTable[row].mSkillStep = pPlayerHaveSkill->GetSkillStep(); sendMsg->mTable[row].mRestCoolTime = pPlayerHaveSkill->GetRestTime(); ++row; } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } cPlayer* player = OBJECTMANAGER->GetPlayer( characterIdx ); if( player ) player->SendSkillPoint(); else assert(0); } void cSkillManager::SendMsgInfluenceToPlayer( unsigned long connectionIdx, unsigned long characterIdx ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( characterIdx ); if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendMsgInfluenceToPlayer pPlayer[%d]==NULL", characterIdx); return; } tHashSet* pInfluenceSet = pPlayer->GetInfluenceSet(); if( !pInfluenceSet ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendMsgInfluenceToPlayer pInfluenceSet==NULL" ); return; } tHashSet::cIterator start = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); HANDLE handle1 = NULL; MSG_RES_INFLUENCE_LIST* pInfList = (MSG_RES_INFLUENCE_LIST*)NETWORK2->GetMsgRoot( &handle1, connectionIdx, NM_SKILL, NM_SKILL_INFLUENCE_LIST_RES ); if ( pInfList == NULL ) { assert(NULL); return; } HANDLE handle2 = NULL; MSG_SYN_SKILL_INFLUENCE_GUARDLIST* pGuardList = (MSG_SYN_SKILL_INFLUENCE_GUARDLIST*)NETWORK2->GetMsgRoot( &handle2, connectionIdx, NM_SKILL, NM_SKILL_INFLUENCE_GUARDLIST_RES ); if( pGuardList == NULL ) { assert(NULL); return; } pInfList->mRowCount = 0; pGuardList->mRowCount = 0; for( ; start != end ; ++start ) { cInfluenceObject* pInf = GetInfluence( (*start) ); if( pInf == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendMsgInfluenceToPlayer pInfluenceObject[%d]==NULL", (*start) ); continue; } if( pInf->GetGuardType() == eINFGUARDTYPE_NONE ) { pInfList->mTable[pInfList->mRowCount].mUniqueIdx = pInf->GetUniqueIdx(); pInfList->mTable[pInfList->mRowCount].mInfluenceClassIdx = pInf->GetInfluenceClassIdx(); if( pInf->GetSwitchType() == eSWITCHTYPE_PARENT ) pInfList->mTable[pInfList->mRowCount].mAuraSkillClassIdx = pInf->GetSkillIdx(); else pInfList->mTable[pInfList->mRowCount].mAuraSkillClassIdx = 0; pInfList->mTable[pInfList->mRowCount].mIsRealTime = pInf->IsRealTime(); if( pInf->IsRealTime() == true ) { pInfList->mTable[pInfList->mRowCount].mRestTime = 0; tm tmTime = TIMER->ConvertTStoTM( pInf->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); pInfList->mTable[pInfList->mRowCount].mEndRealTime = tTime; } else pInfList->mTable[pInfList->mRowCount].mRestTime = pInf->GetInfluenceRestTime(); pInfList->mTable[pInfList->mRowCount].mDeleteType = pInf->GetDeleteType(); ++pInfList->mRowCount; } else { pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mUniqueIdx = pInf->GetUniqueIdx(); pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mInfluenceClassIdx = pInf->GetInfluenceClassIdx(); if( pInf->GetSwitchType() == eSWITCHTYPE_PARENT ) pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mAuraSkillClassIdx = pInf->GetSkillIdx(); else pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mAuraSkillClassIdx = 0; pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mIsRealTime = pInf->IsRealTime(); if( pInf->IsRealTime() == true ) { pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mRestTime = 0; tm tmTime = TIMER->ConvertTStoTM( pInf->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mEndRealTime = tTime; } else pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mRestTime = pInf->GetInfluenceRestTime(); pGuardList->mGuardList[pGuardList->mRowCount].mInfInfo.mDeleteType = pInf->GetDeleteType(); pGuardList->mGuardList[pGuardList->mRowCount].mGuardCnt = pInf->GetLeftGuardCnt(); pGuardList->mGuardList[pGuardList->mRowCount].mGuardValue = pInf->GetLeftGuardValue(); ++pGuardList->mRowCount; } } NETWORK2->SendMsgRoot( handle1, pInfList->GetMsgLength( ) ); NETWORK2->SendMsgRoot( handle2, pGuardList->GetMsgLength( ) ); } void cSkillManager::SendAddSynMsgInfluenceToPlayer( unsigned long connectionIdx, unsigned long characterIdx ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( characterIdx ); if( !pPlayer ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendAddSynMsgInfluenceToPlayer pPlayer[%d]==NULL", characterIdx ); return; } tHashSet* pInfluenceSet = pPlayer->GetInfluenceSet(); if( !pInfluenceSet ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendAddSynMsgInfluenceToPlayer pInfluenceSet==NULL" ); return; } cInfluenceObject* pInf = NULL; tHashSet::cIterator start = pInfluenceSet->Begin(); tHashSet::cIterator end = pInfluenceSet->End(); HANDLE handle = NULL; MSG_SYN_INFLUENCE_ADDLIST* sendMsg = (MSG_SYN_INFLUENCE_ADDLIST*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_SKILL, NM_SKILL_INFLUENCE_ADDLIST_SYN ); if ( sendMsg != NULL ) { sendMsg->mObject.type = eOBJECTTYPE_PLAYER; sendMsg->mObject.index = characterIdx; sendMsg->mRowCount = 0; for( ; start != end ; ++start ) { pInf = GetInfluence( (*start) ); if( pInf == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cSkillManager::SendAddSynMsgInfluenceToPlayer pInfluenceObject[%d]==NULL", (*start) ); //-/-//InsertDeleteInfluenceObject( pInfluenceObject ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } if( pInf->IsRealTime() == false && NETWORK2->GetAccumTime() >= pInf->GetInfluenceEndTime() && pInf->GetSwitchType() == eSWITCHTYPE_NORMAL ) continue; if( pInf->IsRealTime() == true && TIMER->DiffRealTime( pInf->GetInfRealEndTime() ) < 0 && pInf->GetSwitchType() == eSWITCHTYPE_NORMAL ) continue; sendMsg->mTable[sendMsg->mRowCount].mUniqueIdx = pInf->GetUniqueIdx(); sendMsg->mTable[sendMsg->mRowCount].mInfluenceClassIdx = pInf->GetInfluenceClassIdx(); sendMsg->mTable[sendMsg->mRowCount].mDeleteType = pInf->GetDeleteType(); sendMsg->mTable[sendMsg->mRowCount].mIsRealTime = pInf->IsRealTime(); sendMsg->mTable[sendMsg->mRowCount].mRestTime = 0; if( pInf->IsRealTime() == true ) { tm tmTime = TIMER->ConvertTStoTM( pInf->GetInfRealEndTime() ); time_t tTime = mktime( &tmTime ); sendMsg->mTable[sendMsg->mRowCount].mEndRealTime = tTime; } else { if( NETWORK2->GetAccumTime() < pInf->GetInfluenceEndTime() ) sendMsg->mTable[sendMsg->mRowCount].mRestTime = pInf->GetInfluenceEndTime() - NETWORK2->GetAccumTime(); } ++sendMsg->mRowCount; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } else { NETWORK2->PostServerEvent( "cSkillManager::SendAddSynMsgInfluenceToPlayer sendMsg(%d,%d) == NULL", connectionIdx, characterIdx ); } } void cSkillManager::ClearPlayerHaveSkillCoolTime( unsigned long playerIdx, unsigned long exceptSkillIdx ) { cPointerHashMap* cPlayerHaveSkillMap = (cPointerHashMap*)mPlayerHaveSkillMap.GetAt( playerIdx ); if ( !cPlayerHaveSkillMap ) { return; } cPointerHashMap::cConstIterator pos = cPlayerHaveSkillMap->Begin(); cPointerHashMap::cConstIterator end = cPlayerHaveSkillMap->End(); for( ; pos != end; ++pos ) { cHaveSkillObject* haveSkill = (cHaveSkillObject*)(*pos).mSecond; if( haveSkill && haveSkill->GetSkillIdx() != exceptSkillIdx ) haveSkill->ClearRestTime(); } }