#include "stdafx.h" #include "Player_Common.h" #include "ObjectManager.h" #include "SkillManager.h" #include "BaseObject.h" #include "DamageCalc.h" #include "Protocol.h" #include "Player.h" #include "Monster.h" #include "gamesrv.h" #include "Drop.h" #include "StatusCalc_Server.h" #include "GridManager.h" #include "StageScript.h" #include "AIManager.h" cPlayerMonSkillObject::cPlayerMonSkillObject() { mMonsterClassIdx = 0; } cPlayerMonSkillObject::~cPlayerMonSkillObject() { } void* cPlayerMonSkillObject::operator new( size_t n ) { if( n != sizeof(cPlayerMonSkillObject) ) { assert(0); return NULL; } return SKILLMANAGER->AllocPlayerMonSkillObject(); } void cPlayerMonSkillObject::operator delete( void* ptr, size_t n ) { /// NULL Æ÷ÀÎÅÍ °Ë»ç if( ptr == 0 ) { assert(0); return; } if( n != sizeof(cPlayerMonSkillObject) ) { assert(0); return; } SKILLMANAGER->FreePlayerMonSkillObject( static_cast(ptr) ); return; } bool cPlayerMonSkillObject::InitPlayerMonAttack( unsigned long playerIdx, unsigned long monsterClassIdx, eMONSTERATTACK_TYPE attackType, sObject target, unsigned long uniqueIdx, bool casting, float speedFactor, unsigned long mapNumber ) { /// °íÀ¯ idx ¼ÂÆÃ mUniqueIdx = uniqueIdx; /// ¸ó½ºÅÍ À妽º mMonsterClassIdx = monsterClassIdx; mDramaKey = monsterClassIdx; /// ½ºÅ³idxÀÇ °ªÀ» ¼ÂÆÃ. mSkillIdx = attackType; mMapNumber = mapNumber; /// °ø°ÝÀÚ ¼ÂÆÃ mAttacker.index = playerIdx; mAttacker.type = eOBJECTTYPE_PLAYER; mSpeedFactor = speedFactor; /// Ÿ°Ù ¼ÂÆÃ mCenterTarget = target; mIsChgMonsSkill = true; /// ½ºÅ³ ¿ÀºêÁ§Æ® »ý¼º ½Ã°£ mCreationTime = NETWORK2->GetAccumTime(); cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer == NULL ) { /// ½ºÅ³ Á¦°Å assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject - pPlayer[%d] == NULL", playerIdx ); return false; } /// ¿¬Ãâ ½ºÅ©¸³Æ® ÆÄÀÏ¿¡¼­ ½Ã°£ °ªÀ» Àоî¿È cDramaturgyInfo* pDramaInfo = DRAMATURGYMAN->GetMonsterDramaturgyInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pDramaInfo == NULL ) { /// ½ºÅ³ Á¦°Å assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d] - pDramaInfo[%d,%d] == NULL", playerIdx, mMonsterClassIdx, mSkillIdx ); return false; } sDramaState* pDramaState = pDramaInfo->GetDramaState(); if( pDramaState == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject, pDramaState == NULL [%d,%d,%d,%d]", playerIdx, (unsigned short)pPlayer->GetWeaponState(), pPlayer->GetRace(), pPlayer->GetGender() ); return false; } mDetailCnt = pDramaState->GetDamageCount(); mpDetailBegin = (sDramaAction*)pDramaState->GetDamageBegin(); mpDetailEnd = (sDramaAction*)pDramaState->GetDamageEnd(); /// ½ºÅ©¸³Æ® °Ë»ç if( mDetailCnt >= 10 ) return false; /// ¹ß»çü À¯¹« mIsProjectile = pDramaInfo->IsBullet(); /// ¹ß»çü ¼Óµµ mProjectileSpeed = pDramaInfo->GetBulletSpeed(); /// ¹ßµ¿ Á¾·á½Ã°£ mActivityTime = pDramaInfo->GetActivityEndTime(); /// °ø°Ý ½ÃÀÛÀ§Ä¡ = ¹ß»ç¹° ½ÃÀÛÀ§Ä¡ mProjectilePos = pPlayer->GetPos(); /// ¹ß»ç¹° Ÿ°ÙÀ§Ä¡¸¦ ½ÃÀüÀÚ ±âÁØ ¹üÀ§·Î ¹ß»ç¹° ó¸®ÇÒ´ë ¸ñÀûÁöÁ¡À» ¹Ù²Û´Ù. mCenterPos.x = pPlayer->GetXPos(); mCenterPos.y = pPlayer->GetYPos(); mCenterPos.z = pPlayer->Height(); sMonsterSkillScript* pMonsterSkill = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pMonsterSkill == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject::InitPlayerMonAttack pMonsterSkill[%d,%d] == NULL", mMonsterClassIdx, mSkillIdx); return false; } if( mDetailCnt > 1 ) { if( pMonsterSkill->mApplyValueType1 == eSTATUSPLUS_AROUND_PUSH ) return false; if( pMonsterSkill->mApplyValueType1 == eSTATUSPLUS_AROUND_PULL ) return false; if( pMonsterSkill->mApplyValueType2 == eSTATUSPLUS_AROUND_PUSH ) return false; if( pMonsterSkill->mApplyValueType2 == eSTATUSPLUS_AROUND_PULL ) return false; if( pMonsterSkill->mApplyValueType2 == eSTATUSPLUS_TARGET_PUSH ) return false; } if( pMonsterSkill->mShotType == eMONSTERSHOTTYPE_SPOT ) mCastingTime = 0; else { mCastingTime = pPlayer->CalcCastingExt( pMonsterSkill->mCastingTime ); } if( casting == true ) mSkillState = eSKILLPROCESS_CASTING; else { mSkillState = eSKILLPROCESS_ACTIVITY; /// ÄðŸÀÓ ¾÷µ¥ÀÌÆ® pPlayer->UpdateChgMonCoolTime( (eMONSTERATTACK_TYPE)mSkillIdx ); } mAttributeType = pMonsterSkill->mAttributeType; /// °ø°ÝÀÚ ±×¸®µå¿¡ ÇØ´çÇÏ´Â Ç÷¹À̾ ¸ðµÎ ÀÐ¾î µ¥¹ÌÁö ¹ß¼ÛÀÚ ¸í´Ü¿¡ ³Ö´Â´Ù. cPlayer* pMsgTarget = GRIDMANAGER->FindFirstPlayer( pPlayer, true ); while( pMsgTarget != NULL ) { mSendAroundSet.Insert( pMsgTarget->GetObjectID() ); pMsgTarget = GRIDMANAGER->FindNextPlayer( true ); } return true; } bool cPlayerMonSkillObject::InitPlayerMonPosition( unsigned long playerIdx, unsigned long monsterClassIdx, eMONSTERATTACK_TYPE attackType, float targetXPos, float targetYPos, unsigned long uniqueIdx, bool casting, unsigned long mapNumber ) { /// °íÀ¯ idx ¼ÂÆÃ mUniqueIdx = uniqueIdx; /// ¸ó½ºÅÍ À妽º mMonsterClassIdx = monsterClassIdx; mDramaKey = monsterClassIdx; /// ½ºÅ³idxÀÇ °ªÀ» ¼ÂÆÃ. mSkillIdx = attackType; mMapNumber = mapNumber; /// °ø°ÝÀÚ ¼ÂÆÃ mAttacker.index = playerIdx; mAttacker.type = eOBJECTTYPE_PLAYER; /// Ÿ°Ù¿ÀºêÁ§Æ®´Â ¾ø´Ù. mCenterTarget.index = 0; mCenterTarget.type = eOBJECTTYPE_NONE; mIsChgMonsSkill = true; /// ½ºÅ³ ¿ÀºêÁ§Æ® »ý¼º ½Ã°£ mCreationTime = NETWORK2->GetAccumTime(); cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( playerIdx ); if( pPlayer == NULL ) { assert(NULL); NETWORK2->PostServerEvent("InitPlayerSkillPosition - playerIdx[%d]", playerIdx ); return false; } /// ¿¬Ãâ ½ºÅ©¸³Æ® ÆÄÀÏ¿¡¼­ ½Ã°£ °ªÀ» Àоî¿È cDramaturgyInfo* pDramaInfo = DRAMATURGYMAN->GetMonsterDramaturgyInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pDramaInfo == NULL ) { /// ½ºÅ³ Á¦°Å assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d] - pDramaInfo[%d,%d] == NULL", playerIdx, mMonsterClassIdx, mSkillIdx ); return false; } sDramaState* pDramaState = pDramaInfo->GetDramaState(); if( pDramaState == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject, pDramaState == NULL [%d,%d,%d,%d]", playerIdx, (unsigned short)pPlayer->GetWeaponState(), pPlayer->GetRace(), pPlayer->GetGender() ); return false; } mDetailCnt = pDramaState->GetDamageCount(); mpDetailBegin = (sDramaAction*)pDramaState->GetDamageBegin(); mpDetailEnd = (sDramaAction*)pDramaState->GetDamageEnd(); /// ½ºÅ©¸³Æ® °Ë»ç if( mDetailCnt >= 10 ) return false; /// ¹ß»çü À¯¹« mIsProjectile = pDramaInfo->IsBullet(); /// ¹ß»çü ¼Óµµ mProjectileSpeed = pDramaInfo->GetBulletSpeed(); /// ¹ßµ¿ Á¾·á½Ã°£ mActivityTime = pDramaInfo->GetActivityEndTime(); /// °ø°Ý ½ÃÀÛÀ§Ä¡ = ¹ß»ç¹° ½ÃÀÛÀ§Ä¡ mProjectilePos = pPlayer->GetPos(); /// ±âÁØÁÂÇ¥ ¼ÂÆÃ mCenterPos.x = targetXPos; mCenterPos.y = targetYPos; AIMANAGER->CalcHeight( pPlayer->GetMapNumber(), &mCenterPos.z, mCenterPos.x, mCenterPos.y ); sMonsterSkillScript* pMonsterSkill = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pMonsterSkill == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject::InitPlayerMonAttack pMonsterSkill[%d,%d] == NULL", mMonsterClassIdx, mSkillIdx); return false; } if( mDetailCnt > 1 ) { if( pMonsterSkill->mApplyValueType1 == eSTATUSPLUS_AROUND_PUSH ) return false; if( pMonsterSkill->mApplyValueType1 == eSTATUSPLUS_AROUND_PULL ) return false; if( pMonsterSkill->mApplyValueType2 == eSTATUSPLUS_AROUND_PUSH ) return false; if( pMonsterSkill->mApplyValueType2 == eSTATUSPLUS_AROUND_PULL ) return false; if( pMonsterSkill->mApplyValueType2 == eSTATUSPLUS_TARGET_PUSH ) return false; } if( pMonsterSkill->mShotType == eMONSTERSHOTTYPE_SPOT ) mCastingTime = 0; else { mCastingTime = pPlayer->CalcCastingExt( pMonsterSkill->mCastingTime ); } if( casting == true ) mSkillState = eSKILLPROCESS_CASTING; else { mSkillState = eSKILLPROCESS_ACTIVITY; /// ÄðŸÀÓ ¾÷µ¥ÀÌÆ® pPlayer->UpdateChgMonCoolTime( (eMONSTERATTACK_TYPE)mSkillIdx ); } return true; } bool cPlayerMonSkillObject::CastingObjectCheck( cBaseObject* pAttacker ) { unsigned char errorCode = FAIL_SKILL_CASTING_DONT_TARGET; /// »ýÁ¸ ¿©ºÎ È®ÀÎ if( pAttacker->GetStateDie() == false ) { sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pSkillInfo != NULL ) { if( ((cPlayer*)pAttacker)->IsCantSkill( pSkillInfo->mAttributeType ) == false ) { /// ¹üÀ§ ¹æ½Ä¿¡ µû¸¥ Ÿ°Ù °´Ã¼ È®ÀÎ ¿©ºÎ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_SELF_NOTARGET: case eBOUNDTYPE_FIELD: case eBOUNDTYPE_AUTOFIELD: return true; case eBOUNDTYPE_NONE: /// ¹üÀ§ ¾øÀ½ case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ case eBOUNDTYPE_SELF_TARGET: /// ½ÃÀüÀÚ(ÀÚ½Å) ±âÁعüÀ§ - ¹ßµ¿½Ã Ÿ°Ù Á¸Àç { /// ÀÚ½ÅÀÌ Àû¿ë ´ë»óÀÌ¸é ¸®ÅÏ if( pSkillInfo->mApplyType == eAPPLYTYPE_SELF ) return true; } } /// Ÿ°Ù °´Ã¼ üũ cBaseObject* pTarget = OBJECTMANAGER->GetObject( mCenterTarget.type, mCenterTarget.index ); if( pTarget != NULL && pTarget->GetStateDie() == false ) return true; } else errorCode = FAIL_SKILL_CASTING_DONT_OBSTACLE; } else { NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d]::CastingObjectCheck pSkillInfo[%d,%d] == NULL", pAttacker->GetObjectID(), mMonsterClassIdx, mSkillIdx); errorCode = FAIL_SKILL_CASTING_DONT_SCRIPT; } } else errorCode = FAIL_SKILL_CASTING_DONT_ATTACKER; /// ij½ºÆÃ ¹ßµ¿ ½ÇÆÐ ¸Þ¼¼Áö Àü¼Û MSG_SYN_SKILL_CAST_ACTIVITY_FAIL failMsg; failMsg.Category = NM_SKILL; failMsg.Protocol = NM_SKILL_CAST_ACTIVITY_FAIL_SYN; failMsg.mAttacker = mAttacker; failMsg.mSkillIndex = mUniqueIdx; failMsg.mFailCode = errorCode; NETWORK2->QuickSend( pAttacker, (char*)&failMsg, sizeof(failMsg) ); /// Á¶°ÇÀÌ ¸¸Á·ÇÏ´Â °æ¿ì »ó´Ü¿¡ return true·Î ºüÁ®³ª°¨ ¿©±â±îÁö ¿Â°æ¿ì Á¶°ÇÀ» ¸¸Á· ¸øÇÏ´Â °æ¿ìÀÓ return false; } /// ÁÖÀÇ : ij½ºÆÃ ÇÏ´Â °æ¿ì¸¸ ÀÌÇÔ¼ö·Î µé¾î¿È bool cPlayerMonSkillObject::RequireValue( cBaseObject* pAttacker ) { sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pSkillInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d]::RequireValue pSkillInfo[%d,%d] == NULL", pAttacker->GetObjectID(), mMonsterClassIdx, mSkillIdx); SKILLMANAGER->InsertDeleteSkillObject( mAttacker, mUniqueIdx ); return false; } /// ¼Ò¸ð üũ unsigned long useMp = pSkillInfo->mUseMP; if( pAttacker && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { useMp = ((cPlayer*)pAttacker)->CalcUseMPExt( pSkillInfo->mUseMP ); } if( pAttacker->GetMP() < useMp ) { /// ij½ºÆÃ ¹ßµ¿ ½ÇÆÐ ¸Þ¼¼Áö Àü¼Û MSG_SYN_SKILL_CAST_ACTIVITY_FAIL failMsg; failMsg.Category = NM_SKILL; failMsg.Protocol = NM_SKILL_CAST_ACTIVITY_FAIL_SYN; failMsg.mSkillIndex = mUniqueIdx; failMsg.mAttacker = mAttacker; failMsg.mFailCode = FAIL_SKILL_CASTING_MP_EMPTY; NETWORK2->QuickSend( pAttacker, (char*)&failMsg, sizeof(failMsg) ); return false; } /// MP¸¦ ¼Ò¸ð ÇÏ´Â ½ºÅ³ if( useMp != 0 ) pAttacker->MPUse( useMp, false ); /// ij½ºÆÃ ½ºÅ³ ¹ßµ¿À» ¾Ë¸®´Â ½ÌÅ© Àü¼Û MSG_SYN_SKILL_CAST_ACTIVE msgEtc; msgEtc.Category = NM_SKILL; msgEtc.Protocol = NM_SKILL_CAST_ACTIVE_SYN; msgEtc.mSkillIndex = mUniqueIdx; msgEtc.mAttacker = mAttacker; msgEtc.mAttackerPosX = pAttacker->GetXPos(); msgEtc.mAttackerPosY = pAttacker->GetYPos(); msgEtc.mObjectMP = pAttacker->GetMP(); msgEtc.mObjectMaxMp = pAttacker->GetMaxMP(); NETWORK2->QuickSend( pAttacker, (char*)&msgEtc, sizeof(msgEtc) ); /// ÄðŸÀÓ ¾÷µ¥ÀÌÆ® ((cPlayer*)pAttacker)->UpdateChgMonCoolTime( (eMONSTERATTACK_TYPE)mSkillIdx ); ///¹ßµ¿ üũ cBaseObject* pTarget = OBJECTMANAGER->GetObject( mCenterTarget.type, mCenterTarget.index ); if( pTarget ) { switch( pSkillInfo->mType ) { case eMONSTERSKILLTYPE_DAMAGE: case eMONSTERSKILLTYPE_MPDAMAGE: SKILLMANAGER->CheckActInfluence( eACTSTATUS_ACTIVESKILL, pAttacker, pTarget ); break; case eMONSTERSKILLTYPE_HEAL: SKILLMANAGER->CheckActInfluence( eACTSTATUS_HEALSKILL, pAttacker, pTarget ); break; } /// ½ºÅ³ ¹ßµ¿ È¿°ú if( pSkillInfo->mActiveIdx != 0 ) SKILLMANAGER->CheckSkillActInfluence( pSkillInfo->mActiveIdx, pAttacker, pTarget ); } return true; } bool cPlayerMonSkillObject::SetCenterPos() { sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pSkillInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject::RequireValue pSkillInfo[%d,%d] == NULL", mMonsterClassIdx, mSkillIdx ); SKILLMANAGER->InsertDeleteSkillObject( mAttacker, mUniqueIdx ); return false; } /// µ¥¹ÌÁö Àû¿ë½Ã ±âÁØÀÌ µÉ À§Ä¡ÁÂÇ¥ »êÃâ switch( pSkillInfo->mBoundType ) { case eBOUNDTYPE_NONE: /// ¹üÀ§ °ø°ÝÀÌ ¾Æ´Ô case eBOUNDTYPE_TARGET: /// Ÿ°Ù ±âÁعüÀ§ { /// »ç°Å¸® üũ ´ë»óÀÌ ½ÃÀüÀÚÀΰæ¿ì ÇÊ¿ä ¾øÀ½ if( pSkillInfo->mApplyType != eAPPLYTYPE_SELF ) { cBaseObject* pObject = OBJECTMANAGER->GetObject( mCenterTarget.type, mCenterTarget.index ); /// ¹ßµ¿ Àü¿¡ Ÿ°ÙÀÌ »ç¶óÁø°æ¿ì µ¥¹ÌÁö ¹Ì½º if( pObject == NULL || pObject->GetMapNumber() != mMapNumber ) return false; mCenterPos.x = pObject->GetXPos(); mCenterPos.y = pObject->GetYPos(); mCenterPos.z = pObject->Height(); } }break; } return true; } void cPlayerMonSkillObject::TargetSelect( cBaseObject* pAttacker ) { sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pSkillInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d]::TargetSelect pSkillInfo[%d,%d] == NULL", pAttacker->GetObjectID(), mMonsterClassIdx, mSkillIdx ); SKILLMANAGER->InsertDeleteSkillObject( mAttacker, mUniqueIdx ); return; } bool applyHP = pSkillInfo->mType == eMONSTERSKILLTYPE_MPDAMAGE ? false : true; /// ¹ß»çüÁß Å¸°ÙÀ» ÇâÇØ ³¯¾Æ °¡´Ù Ÿ°ÙÀÌ »ç¶óÁø°æ¿ì µ¥¹ÌÁö ¹Ì½ºÃ³¸® ¿©ºÎ if( mNoTargetNoDamage == true ) return; 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; } } } } } /// Ÿ°Ù ¼±Á¤ if( pSkillInfo->mBoundType != eBOUNDTYPE_NONE ) { switch( pSkillInfo->mApplyType ) { case eAPPLYTYPE_SELF: { //sMultiTarget multiTarget; //multiTarget.mTarget.type = eOBJECTTYPE_PLAYER; //multiTarget.mTarget.index = pAttacker->GetObjectID(); ////multiTarget.mApplyHP = applyHP; //mTargetAry.PushBack( multiTarget ); sObject object = { eOBJECTTYPE_PLAYER, pAttacker->GetObjectID() }; SKILLTARGETPOOL->AddSkillTarget( &mTargetRoot, object ); } break; case eAPPLYTYPE_BUDDY: { //mTargetAry.Clear(); unsigned char targetCnt = 0; SelectPlayerTarget( pAttacker, mCenterPos, pSkillInfo->mBoundDist1, pSkillInfo->mBoundDist2, &targetCnt, targetMaxCnt, applyHP, false, pSkillInfo->mBoundType ); //mTargetAry.Clear(); //float tempRange = OBJECTMANAGER->ObjectSizeRange( pAttacker, NULL, pSkillInfo->mBoundDist1 ); //OBJECTMANAGER->PlayerInCenterPoint( pAttacker->GetMapNumber(), mCenterPos, tempRange, &mTargetAry, applyHP, targetMaxCnt ); }break; case eAPPLYTYPE_ENEMY: { //mTargetAry.Clear(); unsigned char targetCnt = 0; if( mCreateType == eSKILLCREATETYPE_DELTARGET ) { float tempRange = OBJECTMANAGER->ObjectSizeRange( pAttacker, NULL, pSkillInfo->mBoundDist1 ); mTempDelTargetAry.Clear(); ((cPlayer*)pAttacker)->MonsterInTargeting( &mTempDelTargetAry, tempRange ); for( unsigned long jj = 0 ; jj < mTempDelTargetAry.GetSize() ; ++jj ) { sObject pObject = mTempDelTargetAry[jj]; SKILLTARGETPOOL->AddSkillTarget( &mTargetRoot, pObject ); } mTempDelTargetAry.Clear(); } else { SelectPlayerTarget( pAttacker, mCenterPos, pSkillInfo->mBoundDist1, pSkillInfo->mBoundDist2, &targetCnt, targetMaxCnt, applyHP, true, pSkillInfo->mBoundType ); SelectMonsterTarget( pAttacker, mCenterPos, pSkillInfo->mBoundDist1, pSkillInfo->mBoundDist2, &targetCnt, targetMaxCnt, applyHP, pSkillInfo->mBoundType ); } //mTargetAry.Clear(); //float tempRange = OBJECTMANAGER->ObjectSizeRange( pAttacker, NULL, pSkillInfo->mBoundDist1 ); //if( mCreateType == eSKILLCREATETYPE_DELTARGET ) // ((cPlayer*)pAttacker)->MonsterInTargeting( &mTargetAry, tempRange ); //else // OBJECTMANAGER->MonsterInCenterPoint( pAttacker->GetMapNumber(), mCenterPos, tempRange, &mTargetAry, applyHP ); //OBJECTMANAGER->PlayerInCenterPoint( pAttacker->GetMapNumber(), mCenterPos, tempRange, &mTargetAry, // pAttacker->GetObjectID(), applyHP, targetMaxCnt ); }break; } } else { //sMultiTarget multiTarget; //multiTarget.mTarget = mCenterTarget; ////multiTarget.mApplyHP = applyHP; //mTargetAry.PushBack( multiTarget ); SKILLTARGETPOOL->AddSkillTarget( &mTargetRoot, mCenterTarget ); // ¿ÀÅä´õ¹Ì °ø°Ý if( mCenterTarget.type == eOBJECTTYPE_MONSTER ) { cMonster* mon = OBJECTMANAGER->GetMonster( mCenterTarget.index ); if( mon != NULL ) { mon->AttackDummy( pAttacker->GetObject() ); } else NETWORK2->PostServerEvent("cMonsterSkillObject[%d]::TargetSelect Monster null", pAttacker->GetObjectID(), mCenterTarget.index ); } } } void cPlayerMonSkillObject::ApplyDamage( cBaseObject* pAttacker ) { /// ÀÚµ¿»ç³É ½Å°í °ü·Ã if ( pAttacker != NULL && pAttacker->GetObjectType() == eOBJECTTYPE_PLAYER ) { cPlayer* pHero = (cPlayer*)pAttacker; if ( pHero ) { pHero->SetLastAttackTime( NETWORK2->GetAccumTime() ); } else { NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d]::ApplyDamage [LastAttackTime] pHero == NULL", pAttacker->GetObjectID() ); } } sMonsterSkillScript* pSkillInfo = SKILLSCRIPT->GetMonsterSkillInfo( mMonsterClassIdx, (eMONSTERATTACK_TYPE)mSkillIdx ); if( pSkillInfo == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayerMonSkillObject[%d]::ApplyDamage pSkillInfo[%d,%d] == NULL", pAttacker->GetObjectID(), mMonsterClassIdx, mSkillIdx ); SKILLMANAGER->InsertDeleteSkillObject( mAttacker, mUniqueIdx ); return; } /// ŸÀÔº° µ¥¹ÌÁö ó¸® switch( pSkillInfo->mType ) { case eMONSTERSKILLTYPE_DAMAGE: { SendDamage( pAttacker, pSkillInfo->mShotType, pSkillInfo->mAttributeType, pSkillInfo->mRangeType, pSkillInfo->mApplyValueType1, pSkillInfo->mApplyValueType2, pSkillInfo->mApplyValue1, pSkillInfo->mApplyValue2, pSkillInfo->mInfulenceIdx, pSkillInfo->mAccuracyValue, pSkillInfo->mCriticalValue, true ); } break; case eMONSTERSKILLTYPE_HEAL: { SendHeal( pAttacker, pSkillInfo->mShotType, pSkillInfo->mApplyValueType1, pSkillInfo->mApplyValueType2, pSkillInfo->mApplyValue1, pSkillInfo->mApplyValue2, pSkillInfo->mInfulenceIdx ); } break; case eMONSTERSKILLTYPE_NONACTIVE: { if( eSKILLCREATETYPE_DELTARGET == mCreateType ) { SendDelTarget( pAttacker, pSkillInfo->mAccuracyValue ); } else if( eSKILLCREATETYPE_BLINK == mCreateType ) { ApplyBlink( pAttacker ); } else { SendApply( pAttacker, pSkillInfo->mShotType, pSkillInfo->mAttributeType, pSkillInfo->mAccuracyValue, pSkillInfo->mApplyValueType1, pSkillInfo->mApplyValueType2, pSkillInfo->mApplyValue1, pSkillInfo->mApplyValue2, pSkillInfo->mInfulenceIdx ); } } break; case eMONSTERSKILLTYPE_MPDAMAGE: { SendDamage( pAttacker, pSkillInfo->mShotType, pSkillInfo->mAttributeType, pSkillInfo->mRangeType, pSkillInfo->mApplyValueType1, pSkillInfo->mApplyValueType2, pSkillInfo->mApplyValue1, pSkillInfo->mApplyValue2, pSkillInfo->mInfulenceIdx, pSkillInfo->mAccuracyValue, pSkillInfo->mCriticalValue, false ); } break; case eMONSTERSKILLTYPE_TOTEM: { 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; } } } } } AddTotem( pAttacker, ((cPlayer*)pAttacker)->GetPartyIndex(), ((cPlayer*)pAttacker)->GetPartyUnionIndex(), pSkillInfo->mApplyType, pSkillInfo->mAttributeType, pSkillInfo->mInfulenceIdx, targetMaxCnt ); } break; case eMONSTERSKILLTYPE_PORTAL: { AddPortal( pAttacker, pSkillInfo->mInfulenceIdx ); } break; } }