#include "StdAfx.h" #include "DnActor.h" #include "DnWorld.h" #include "DnWorldGrid.h" #include "MAActorRenderBase.h" #include "MAMovementBase.h" #include "DnWeapon.h" #include "EtActionSignal.h" #include "VelocityFunc.h" #include "DnWorldBrokenProp.h" #include "DnWorldSector.h" #include "DnProjectile.h" #include "DnMonsterActor.h" #include "TaskManager.h" #include "DnPlayerActor.h" #include "PerfCheck.h" #include "DnStateBlow.h" #include "DnBlow.h" #include "DnGameTask.h" #include "DnItemTask.h" #include "DNUserData.h" #include "DNUserSession.h" #include "DnWorldTrapProp.h" #include "DnChangeActionStrProcessor.h" //#include "DNUserConnection.h" // Siva Shaodw Test Àӽà #ifdef _SHADOW_TEST #include "DNProtocol.h" #include "GameSendPacket.h" bool g_bEnableShadow[MAX_SESSION_COUNT] = { 0, }; #endif #include "EtComputeDist.h" #include "DNAggroSystem.h" #include "DnParryBlow.h" #include "DnCooltimeParryBlow.h" #include "DnChargerBlow.h" #include "DnBuffProp.h" #include "DnWorldBrokenBuffProp.h" #include "DnReverseTeamBlow.h" #include "DnHighLanderBlow.h" #include "DnCannonMonsterActor.h" #include "DnPlayerSpeedHackChecker.h" #include "DnFrostbiteBlow.h" #include "DnChangeActionSetBlow.h" #include "DnInvincibleAtBlow.h" #include "DnBreakSuperArmorBlow.h" #include "DnBurnCriticalBlow.h" #include "DnDisableActionBlow.h" #ifdef PRE_ADD_EXPORT_DPS_INFORMATION #include "DnDPSReporter.h" #endif #include "DnManaShieldBlow.h" #include "DnCurseBlow.h" #include "DNGameDataManager.h" #include "DnStateBlowSignalProcessor.h" #include "DnInvincibleTypeBlow.h" #include "DnImmuneByTypeBlow.h" #include "DnComboDamageLimitBlow.h" #include "DnTransmitDamageBlow.h" #include "DnChangeStandActionBlow.h" #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) #include "DnTotalLevelSkillBlows.h" #endif // PRE_ADD_TOTAL_LEVEL_SKILL #if defined(PRE_FIX_68898) #include "DnPartialPlayProcessor.h" #endif // PRE_FIX_68898 #include "SmartPtrDef.h" #include "DnBubbleSystem.h" #include "DnObserverEventMessage.h" DECL_DN_SMART_PTR_STATIC( CDnActor, MAX_SESSION_COUNT, 100 ) STATIC_DECL_INIT( CDnActor, CEtOctree *, s_pOctree ) = { NULL, }; STATIC_DECL_INIT( CDnActor, DWORD, s_dwUniqueCount ) = { 0, }; STATIC_DECL_INIT( CDnActor, CDnActor::mapActorSearch, s_dwMapActorSearch ); float CDnActor::s_fDieDelta = 20.f; float CEtOctreeNode::s_fMinRadius = 1000.0f; #define DOWN_DELAY_RANDOM_RANGE 0.2f // 20ÇÁ·Î ±æ°Å³ª ¤E°Å³ª~ #ifdef PRE_FIX_GAMESERVER_OPTIMIZE STATIC_DECL_INIT( CDnActor, CFrameSkip, s_MonsterProcess ); STATIC_DECL_INIT( CDnActor, float, s_fMonsterProcessDelta ); STATIC_DECL_INIT( CDnActor, CFrameSkip, s_NpcProcess ); STATIC_DECL_INIT( CDnActor, float, s_fNpcProcessDelta ); #endif CDnActor::CDnActor( CMultiRoom *pRoom, int nClassID ) : CDnUnknownRenderObject( pRoom, true ) , m_vStaticPosition( 0.f, 0.f, 0.f ) , m_vPrevPosition( 0.f, 0.f, 0.f ) { CDnActorState::Initialize( this ); m_nClassID = nClassID; m_fAddHeight = 0.f; m_bShow = true; m_fDownDelta = 0.f; m_fDieDelta = 0.f; m_fMaxDieDelta = CDnActor::s_fDieDelta; m_fStiffDelta = 0.f; m_fLastDownRatio = 1.f; m_LastHitSignalTime = 0; m_nLastHitSignalIndex = -1; m_nLastDamageHitterActionIndex = 0; m_nTeam = 0; m_dwUniqueID = -1; m_pAggroSystem = NULL; m_bModifyPlaySpeed = false; m_PlaySpeedStartTime = 0; m_dwPlaySpeedTime = 0; m_bEnableNormalSuperAmmor = false; m_nNormalSuperAmmorTime = 0; m_fBreakNormalSuperAmmorDurability = 0.f; m_HitCheckType = HitCheckTypeEnum::BoundingBox; memset( m_bSelfDeleteWeapon, 0, sizeof( m_bSelfDeleteWeapon ) ); m_pStateBlow = new CDnStateBlow( GetMySmartPtr() ); memset( m_nSkillSuperAmmorValue, 0, sizeof(m_nSkillSuperAmmorValue) ); memset( m_nLastUpdateSkillSuperAmmorValue, 0, sizeof(m_nLastUpdateSkillSuperAmmorValue) ); m_nSkillSuperAmmorTime = 0; m_fSkillSuperAmmorDamageDecreaseProb = 0.f; m_bIngnoreNormalSuperArmor = false; InsertOctreeNode(); m_bUseSignalSkillCheck = false; ZeroMemory( m_abSignalSkillCheck, sizeof(m_abSignalSkillCheck) ); m_iCantMoveReferenceCount = 0; m_iCantActionReferenceCount = 0; m_iCantUseSkillReferenceCount = 0; m_iCantAttackReferenceCount = 0; m_iCantXZMoveSE = 0; #ifdef _SHADOW_TEST m_bIsShadowActor = false; m_bEnableShadowActor = true; #endif m_iLastDamage = 0; m_bOnSignalFromChargerSE = false; m_bAllowCalcCombo = true; m_bOctreeUpdate = true; m_bToggleIngnoreHit = false; m_dwGenTick = timeGetTime(); m_iFrameStopRefCount = 0; m_fPlaySpeed = 0.0f; m_iLastProcessPressCount = 0; m_bCompleteKill_AfterProcessStateBlow = false; m_pStateBlowSignalProcessor = new CDnStateBlowSignalProcessor(); m_bChangeWeaponLocked = false; m_bSkipChangeWeaponAction = false; m_bSkipOnAttatchDetachWeapon = false; #if defined(PRE_ADD_50907) m_ChangeWeaponRefCount = 0; m_bOrigWeaponWhenChangeWeaponSelfDelete = false; #endif // PRE_ADD_50907 #if defined(PRE_ADD_50907) m_DisarmamentRefCount = 0; m_bOrigWeaponWhenDisarmamentSelfDelete = false; #endif // PRE_ADD_50907 #if defined(PRE_FIX_50482) m_nChangeTeamRefCount = 0; #endif // PRE_FIX_50482 #if defined(PRE_FIX_59347) m_bApplyPartsDamage = false; #endif // PRE_FIX_59347 #ifdef PRE_ADD_GRAVITY_PROPERTY m_fGravityEnd = 0.0f; #endif // PRE_ADD_GRAVITY_PROPERTY // Rotate. m_dwRotateStartTime = 0; m_dwRotateTime = 0; m_bRotate = false;; m_bRotLeft = false; // ȸÀü¹æÇâ. m_fSpeedRot = 0.0f; // ȸÀü¼Óµµ. m_fStartSpeed = 0.0f; // ½ÃÀÛ¼Óµµ. m_fEndSpeed = 0.0f; // Á¾·á¼Óµµ. m_vRotAxis.x = m_vRotAxis.y = m_vRotAxis.z = 0.0f; // ȸÀüÃàÁÂÇ¥. } CDnActor::~CDnActor() { RemoveUniqueSearchMap( GetRoom(), this ); FreeAction(); for( int i=0; i<2; i++ ) SAFE_RELEASE_SPTR( m_hWeapon[i] ); RemoveOctreeNode(); SAFE_DELETE_VEC( m_VecPreActionState ); SAFE_DELETE_VEC( m_VecPreActionCustomState ); SAFE_DELETE(m_pStateBlow); SAFE_DELETE( m_pAggroSystem ); SAFE_DELETE(m_pStateBlowSignalProcessor); } void CDnActor::InsertOctreeNode() { if( STATIC_INSTANCE(s_pOctree) ) { SSphere Sphere; GetBoundingSphere( Sphere ); m_pCurrentNode = STATIC_INSTANCE(s_pOctree)->Insert( GetMySmartPtr(), Sphere ); } } void CDnActor::RemoveOctreeNode() { if( STATIC_INSTANCE(s_pOctree) ) { if( !STATIC_INSTANCE(s_pOctree)->Remove( GetMySmartPtr(), m_pCurrentNode ) ) { STATIC_INSTANCE(s_pOctree)->Remove( GetMySmartPtr(), NULL ); } m_pCurrentNode = NULL; } } void CDnActor::SetUniqueID( DWORD dwUniqueID ) { RemoveUniqueSearchMap( GetRoom(), this ); m_dwUniqueID = dwUniqueID; InsertUniqueSearchMap( GetRoom(), this ); } void CDnActor::InsertUniqueSearchMap( CMultiRoom *pRoom, CDnActor *pActor ) { if( pActor->GetUniqueID() == -1 ) return; STATIC_INSTANCE_(s_dwMapActorSearch).insert( make_pair( pActor->GetUniqueID(), pActor->GetMySmartPtr() ) ); } void CDnActor::RemoveUniqueSearchMap( CMultiRoom *pRoom, CDnActor *pActor ) { if( pActor->GetUniqueID() == -1 ) return; std::map::iterator it; it = STATIC_INSTANCE_(s_dwMapActorSearch).find( pActor->GetUniqueID() ); if( it != STATIC_INSTANCE_(s_dwMapActorSearch).end() ) { STATIC_INSTANCE_(s_dwMapActorSearch).erase( it ); } } // Static Func void CDnActor::InitializeNextStage( CMultiRoom* pRoom ) { CDNGameRoom* pGameRoom = static_cast(pRoom); for( DWORD i=0; iIsPlayerActor() ) { //g_Log.Log( LogType::_INVALIDACTOR, "[%d] MapIdx:%d ClassID:%d LocalTime=%I64d\r\n", g_Config.nManagedID, pGameRoom->m_iMapIdx, STATIC_INSTANCE_(s_pVecProcessList)[i]->GetClassID(), pGameTask ? pGameTask->m_pFrameSync->GetMSTime() : 0 ); STATIC_INSTANCE_(s_pVecProcessList)[i]->Release(); i--; } } } bool CDnActor::InitializeClass( CMultiRoom *pRoom ) { if( !CDnWorld::IsActive(pRoom) ) return false; DNVector(DnActorHandle) VecList; GetActorList( pRoom, VecList ); int iNumActor = (int)VecList.size(); for( int i = 0; i < iNumActor; ++i ) { DnActorHandle hActor = VecList.at( i ); CDnActor::ActorTypeEnum ActorType = hActor->GetActorType(); if( ActorType > -1 && ActorType <= ActorTypeEnum::Reserved6 ) hActor->OnInitializeNextStage(); } float fCenter, fSize; CDnWorld::GetInstance(pRoom).CalcWorldSize( fCenter, fSize ); SAFE_DELETE( STATIC_INSTANCE_(s_pOctree) ); STATIC_INSTANCE_(s_pOctree) = new CEtOctree( false ); STATIC_INSTANCE_(s_pOctree)->Initialize( EtVector3( 0.f, fCenter, 0.f ), fSize ); STATIC_INSTANCE_(CDnActor::s_dwUniqueCount) = 0; #ifdef PRE_FIX_GAMESERVER_OPTIMIZE STATIC_INSTANCE_(s_MonsterProcess).SetFramePerSec( 10.f ); STATIC_INSTANCE_(s_fMonsterProcessDelta) = 0.f; STATIC_INSTANCE_(s_NpcProcess).SetFramePerSec( 1.f ); STATIC_INSTANCE_(s_fNpcProcessDelta) = 0.f; #endif return true; } void CDnActor::ProcessClass( CMultiRoom *pRoom, LOCAL_TIME LocalTime, float fDelta ) { #ifdef PRE_FIX_GAMESERVER_OPTIMIZE float fResultDelta[2] = { fDelta, fDelta }; bool bProcessSkip[2] = { false, false }; if( STATIC_INSTANCE_(s_MonsterProcess).Update( fDelta ) ) { STATIC_INSTANCE_(s_fMonsterProcessDelta) += fDelta; fResultDelta[0] = STATIC_INSTANCE_(s_fMonsterProcessDelta); bProcessSkip[0] = false; STATIC_INSTANCE_(s_fMonsterProcessDelta) = 0.f; } else { bProcessSkip[0] = true; STATIC_INSTANCE_(s_fMonsterProcessDelta) += fDelta; } if( STATIC_INSTANCE_(s_NpcProcess).Update( fDelta ) ) { STATIC_INSTANCE_(s_fNpcProcessDelta) += fDelta; fResultDelta[1] = STATIC_INSTANCE_(s_fNpcProcessDelta); bProcessSkip[1] = false; STATIC_INSTANCE_(s_fNpcProcessDelta) = 0.f; } else { bProcessSkip[1] = true; STATIC_INSTANCE_(s_fNpcProcessDelta) += fDelta; } float fTempDelta; for( DWORD i=0; iSyncClassTime( LocalTime ); fTempDelta = fDelta; if( !pActor->IsPlayerActor() ) { if( pActor->IsMonsterActor() ) { #ifndef PRE_FIX_MOMSTER_PROCESS_DELTA // ¸ó½ºÅÍ¿Í Ç÷¹À̾îÀÇ ÇÁ·¹ÀÓÀ²ÀÌ ´Þ¶ó¼­ ¹Î°¨ÇÑ ºÎºÐ¿¡¼­ Ŭ¶ó¿Í ¼­¹öÀÇ ½ÌÅ©°¡ ´Þ¶óÁö°ÔµË´Ï´Ù // ƯÁ¤ Delta°ªÀ» ÀÌ¿ëÇÑ º¸°£ °è»êÀ̳ª Delta °ªÀ» »ç¿ëÇÏ´Â ºÎºÐ¿¡¼­ ¹Ì¹¦ÇÏ°Ô ½ÌÅ©°¡ Ʋ¾îÁ®¼­ ¸ó½ºÅÍ´Â ÇÁ·¹ÀÓ ½ÌÅ© °ÉÁö¾Êµµ·Ï ¼³Á¤ÇÕ´Ï´Ù. fTempDelta = fResultDelta[0]; if( bProcessSkip[0] ) continue; #endif } if( pActor->IsNpcActor() ) { fTempDelta = fResultDelta[1]; if( bProcessSkip[1] ) continue; } } /* if( bProcessSkip == true && !STATIC_INSTANCE_(s_pVecProcessList)[i]->IsPlayerActor() ) { continue; } if( !STATIC_INSTANCE_(s_pVecProcessList)[i]->IsPlayerActor() ) { fTempDelta = fResultDelta; } else fTempDelta = fDelta; */ STATIC_INSTANCE_(s_pVecProcessList)[i]->Process( LocalTime, fTempDelta ); SSphere Sphere; STATIC_INSTANCE_(s_pVecProcessList)[i]->GetBoundingSphere( Sphere ); if( STATIC_INSTANCE_(s_pVecProcessList)[i]->m_bOctreeUpdate ) STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode = STATIC_INSTANCE_(s_pOctree)->Update( STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr(), Sphere, STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode ); if( STATIC_INSTANCE_(s_pVecProcessList)[i]->IsDestroy() ) { STATIC_INSTANCE_(s_pVecProcessList)[i]->Release(); i--; } } #else for( DWORD i=0; iSyncClassTime( LocalTime ); STATIC_INSTANCE_(s_pVecProcessList)[i]->Process( LocalTime, fDelta ); SSphere Sphere; STATIC_INSTANCE_(s_pVecProcessList)[i]->GetBoundingSphere( Sphere ); if( STATIC_INSTANCE_(s_pVecProcessList)[i]->m_bOctreeUpdate ) STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode = STATIC_INSTANCE_(s_pOctree)->Update( STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr(), Sphere, STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode ); if( STATIC_INSTANCE_(s_pVecProcessList)[i]->IsDestroy() ) { STATIC_INSTANCE_(s_pVecProcessList)[i]->Release(); i--; } } #endif } void CDnActor::ProcessAIClass( CMultiRoom *pRoom, LOCAL_TIME LocalTime, float fDelta ) { for( DWORD i=0; iProcessAI( LocalTime, fDelta ); } } void CDnActor::ReleaseClass( CMultiRoom *pRoom ) { SAFE_DELETE( STATIC_INSTANCE_(s_pOctree) ); SAFE_DELETE_MAP( STATIC_INSTANCE_(s_dwMapActorSearch) ); DeleteAllObject( pRoom ); STATIC_INSTANCE_(s_pVecProcessList).clear(); } int CDnActor::ScanActor( CMultiRoom *pRoom, EtVector3 &vPos, float fRadius, DNVector(DnActorHandle) &VecList, bool bInside ) { SSphere Sphere; Sphere.Center = vPos; Sphere.fRadius = fRadius; STATIC_INSTANCE_(s_pOctree)->Pick( Sphere, VecList, bInside ); return (int)VecList.size(); } int CDnActor::ScanActorByActorSize( CMultiRoom *pRoom, EtVector3 &vPos, float fRadius, DNVector(DnActorHandle) &VecList, bool bInside, bool bActorSize ) { SSphere Sphere; Sphere.Center = vPos; Sphere.fRadius = fRadius; STATIC_INSTANCE_(s_pOctree)->Pick( Sphere, VecList, bInside, bActorSize ); return (int)VecList.size(); } void CDnActor::GetActorList(CMultiRoom *pRoom, DNVector(DnActorHandle) &VecList) { for( DWORD i=0; iGetMySmartPtr(); VecList.push_back(hActor); } } void CDnActor::GetOpponentActorList(CMultiRoom *pRoom, int nTeam, DNVector(DnActorHandle) &VecList, EtVector3* pPos/*=NULL*/, float fMaxRange/*=0.f*/ ) { for( DWORD i=0; iGetMySmartPtr(); if( hActor->GetTeam() != nTeam ) { bool bPush = true; if( pPos && fMaxRange > 0.f ) { if( EtVec3LengthSq( &(*pPos-*hActor->GetPosition()) ) > fMaxRange*fMaxRange ) bPush = false; } if( bPush ) VecList.push_back(hActor); } } } DnActorHandle CDnActor::FindActorFromUniqueID( CMultiRoom *pRoom, DWORD dwUniqueID ) { std::map::iterator it = STATIC_INSTANCE_(s_dwMapActorSearch).find( dwUniqueID ); if( it != STATIC_INSTANCE_(s_dwMapActorSearch).end() ) return it->second; return CDnActor::Identity(); } DnActorHandle CDnActor::FindActorFromName( CMultiRoom *pRoom, TCHAR *szName ) { for( DWORD i=0; iGetName(), szName ) ) return STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr(); } return CDnActor::Identity(); } void CDnActor::ProcessReservedRemoveBlows( void ) { if( false == m_vlReservedRemoveBlows.empty() ) { for( int i = 0; i < (int)m_vlReservedRemoveBlows.size(); ++i ) { DnBlowHandle hBlow = m_vlReservedRemoveBlows.at( i ); if( hBlow ) this->CmdRemoveStateEffectFromID( hBlow->GetBlowID() ); } m_vlReservedRemoveBlows.clear(); } } void CDnActor::Process( LOCAL_TIME LocalTime, float fDelta ) { UpdateStealMagicBuff(); int nState = GetState(); m_bEnableNormalSuperAmmor = false; CDnActionBase::ProcessAction( LocalTime, fDelta ); if( 0 < GetCantMoveSEReferenceCount() ) m_vAniDistance.x = m_vAniDistance.z = 0.0f; if( !IsNpcActor() ) { PROFILE_TIME_TEST( OnSkillProcess( LocalTime, fDelta ) ); } ProcessDown( LocalTime, fDelta ); ProcessDie( LocalTime, fDelta ); ProcessStiff( LocalTime, fDelta ); ProcessPlaySpeed( LocalTime, fDelta ); ProcessRotate( LocalTime, fDelta ); // Rotate; PROFILE_TIME_TEST( ProcessState( LocalTime, fDelta ) ); PROFILE_TIME_TEST( ProcessPress() ); if (m_pStateBlowSignalProcessor && !IsDie() ) m_pStateBlowSignalProcessor->Process(LocalTime, fDelta); //»óÅÂÈ¿°ú 229¹ø¿¡¼­ µî·ÏµÈ »óÅÂÈ¿°ú Àû¿ë¿ë ÇÔ¼ö.. ApplySkillStateEffect(); for( int i=0; i<2; i++ ) { if( m_hWeapon[i] ) m_hWeapon[i]->Process( LocalTime, fDelta ); } #ifdef PRE_ADD_GRAVITY_PROPERTY if( m_fGravityEnd > 0.0f ) { m_fGravityEnd -= fDelta; if( m_fGravityEnd <= 0.0f ) { SetVelocityY( 0.01f ); SetResistanceY( -30.0f ); SetAppliedYDistance( false ); m_fGravityEnd = 0.0f; } } #endif // PRE_ADD_GRAVITY_PROPERTY #ifdef _SHADOW_TEST if( g_bEnableShadow[GetRoom()->GetRoomID()] && m_bEnableShadowActor && GetGameRoom() ) { char pBuf[256]; CPacketCompressStream Stream( pBuf, 256 ); int nIndex = GetElementIndex( m_szAction.c_str() ); float fFrame = GetCurFrame(); EtVector3 vMoveX = *GetMoveVectorX(); EtVector3 vMoveZ = *GetMoveVectorZ(); Stream.Write( &nIndex, sizeof(int) ); Stream.Write( &fFrame, sizeof(float) ); Stream.Write( &m_Cross.m_vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( &m_Cross.m_vXAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Stream.Write( &m_Cross.m_vZAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Stream.Write( &vMoveX, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Stream.Write( &vMoveZ, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); bool bMoveTarget = ( GetMoveTarget() ) ? true : false; bool bLookTarget = ( GetLookTarget() ) ? true : false; Stream.Write( &bMoveTarget, sizeof(bool) ); if( bMoveTarget ) { DnActorHandle hMoveTarget = GetMoveTarget(); Stream.Write( hMoveTarget->GetPosition(), sizeof(EtVector3) ); } Stream.Write( &bLookTarget, sizeof(bool) ); if( bLookTarget ) { DnActorHandle hLookTarget = GetLookTarget(); Stream.Write( hLookTarget->GetPosition(), sizeof(EtVector3) ); } for( DWORD i=0; iGetUserCount(); i++ ) { SendActorShadowMsg( GetGameRoom()->GetUserData(i), GetUniqueID(), eActor::SC_SHADOW, (BYTE*)Stream.GetBuffer(), Stream.Tell() ); } } #endif // ¸¶Áö¸·À¸·Î ¹Þ¾Ò´ø µ¥¹ÌÁö ÃʱâÈ­. (È­¿° »óÅÂÈ¿°ú¿¡¼­ ¾²ÀÓ) m_iLastDamage = 0; } void CDnActor::GetBoundingSphere( SSphere &Sphere, bool bActorSize/* = false*/ ) { MAActorRenderBase *pRenderBase = static_cast(this); if( pRenderBase ) { if( pRenderBase->GetBoundingSphere( Sphere ) == false ) { Sphere.Center = m_Cross.m_vPosition; Sphere.fRadius = (float)GetUnitSize(); } } else { Sphere.Center = m_Cross.m_vPosition; Sphere.fRadius = (float)GetUnitSize(); } if (bActorSize == true) { Sphere.Center = FindAutoTargetPos(); Sphere.fRadius = (float)GetUnitSize(); } } void CDnActor::GetBoundingBox( SAABox &Box ) { MAActorRenderBase *pRenderBase = static_cast(this); if( pRenderBase ) { pRenderBase->GetBoundingBox( Box ); } else { Box.Min = m_Cross.m_vPosition + EtVector3( -50.f, -50.f, -50.f ); Box.Max = m_Cross.m_vPosition + EtVector3( 50.f, 50.f, 50.f ); } } void CDnActor::AddStateEffectQueue( const CDnSkill::SkillInfo& ParentSkillInfo, const CDnSkill::StateEffectStruct& StateEffectInfo ) { m_dqApplySelfStateBlowQ.push_back( S_NO_PACKET_SELF_STATEBLOW(ParentSkillInfo, StateEffectInfo) ); } void CDnActor::ClearSelfStateSignalBlowQueue( bool bItemSkill/* = false*/ ) { deque::iterator iter = m_dqApplySelfStateBlowQ.begin(); for( iter; iter != m_dqApplySelfStateBlowQ.end(); ) { if( bItemSkill == iter->ParentSkillInfo.bIsItemSkill ) { iter = m_dqApplySelfStateBlowQ.erase( iter ); } else { iter++; } } } void CDnActor::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex ) { switch( Type ) { case STE_Hit: { if( IsDie() ) break; if (ProcessIgnoreHitSignal() == true) break; HitStruct *pStruct = (HitStruct *)pPtr; DNVector(DnActorHandle) hVecList; DNVector(DnActorHandle) hVecActorToApplyStateEffect; int nWeaponLength = 0; bool bOnDamageCalled = false; if( pStruct->bIncludeWeaponLength && GetWeapon() ) nWeaponLength = GetWeapon()->GetWeaponLength(); MatrixEx CrossTemp = m_Cross; if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; // ½ºÄÉÀÏµÈ ¸ó½ºÅÍÀÇ °æ¿ì È÷Æ® ½Ã±×³ÎÀÇ Áß½ÉÃàÀÌ Ç×»ó ¾×ÅÍÀÇ ¿øÁ¡ À§Ä¡°¡ ¸Â´Â °ÍÀº ¾Æ´Ï±â ¶§¹®¿¡ // ¿ÀÇÁ¼Â¿¡µµ Á¤È®ÇÏ°Ô ½ºÄÉÀÏ °ªÀ» Àû¿ë½ÃÄÑ Áà¾ß ÇÑ´Ù.(#18971) EtVector3 vOffset = *pStruct->vOffset * GetScale()->y; CrossTemp.MoveLocalZAxis( vOffset.z ); CrossTemp.MoveLocalXAxis( vOffset.x ); CrossTemp.MoveLocalYAxis( vOffset.y ); // ƯÁ¤ º»°ú ¸µÅ©µÈ »óŶó¸é.. if( pStruct->szLinkBoneName && strlen(pStruct->szLinkBoneName) > 0 ) { int nBoneIndex = GetBoneIndex( pStruct->szLinkBoneName ); if( -1 != nBoneIndex ) { EtMatrix matBoneWorld = GetBoneMatrix( pStruct->szLinkBoneName ); EtMatrixMultiply( (EtMatrix*)&CrossTemp, (EtMatrix*)&CrossTemp, &matBoneWorld ); } } // ¸ó½ºÅÍ´Â ½ºÄÉÀÏ¿¡µû¶ó º¸Á¤ÇØÁà¾ßÇÑ´Ù. float fDistanceMax = pStruct->fDistanceMax * GetScale()->y; float fDistanceMin = pStruct->fDistanceMin * GetScale()->y; float fHeightMax = pStruct->fHeightMax * GetScale()->y; EtVector3 vPos = CrossTemp.m_vPosition; float fDistance = max( fDistanceMax, fHeightMax - pStruct->fHeightMin ) + nWeaponLength; float fXZDistanceSQ = fDistanceMax + nWeaponLength; float fXZDistanceMinSQ = fDistanceMin; // Min Àº Weapon ±æÀÌ ¿µÇâ¾È¹Þ½À´Ï´Ù. fXZDistanceSQ *= fXZDistanceSQ; fXZDistanceMinSQ *= fXZDistanceMinSQ; ScanActor( GetRoom(), vPos, fDistance, hVecList ); //#53454 ²ÀµÎ°¢½Ã ¼Òȯ¾×ÅÍÀÎ °æ¿ì, ²ÀµÎ°¢½Ã ÁÖÀÎ?Àº HitList¿¡¼­ Á¦¿Ü ½ÃŲ´Ù. #if defined(PRE_FIX_61382) ExceptionHitList2(hVecList, m_Cross, GetMySmartPtr(), pStruct, hVecActorToApplyStateEffect, 0, fDistance, m_vPrevPosition); #else ExceptionHitList(hVecList, m_Cross, GetMySmartPtr(), pStruct); #endif // PRE_FIX_61382 EtVector3 vDir; EtVector3 vZVec = m_Cross.m_vZAxis; if( pStruct->fCenterAngle != 0.f ) { EtMatrix matRotate; EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) ); EtVec3TransformNormal( &vZVec, &vZVec, &matRotate ); #if defined(PRE_FIX_63356) //#63356 ¼­Å¬º½¹öÀÇ °æ¿ì È÷Æ® ¿µ¿ªÀÌ 180µµ ȸÀüÀÌ µÈ °æ¿ì.. //vPos´Â ÇöÀç ij¸¯ÅÍÀÇ ¹æÇâ¿¡¼­ ¿É¼Â °ª¸¸Å­ À̵¿ÀÌ µÇ°í, È÷Æ® ¿µ¿ªÀº 180µµ ȸÀüÀÌ µÇ´Â °æ¿ì À̹ǷΠ//Çã¿ë °¢µµ °è»ê¿¡¼­ ÀÌ È¸Àü °ªÀ» Àû¿ë ½ÃÄÑ¾ß ÇÑ´Ù. CrossTemp.m_vZAxis = vZVec; #endif // PRE_FIX_63356 } SAABox Box; float fDot = 0.0f; SHitParam HitParam; bool bHit = false; bool bFirstHit = true; if( m_LastHitSignalTime > LocalTime ) bFirstHit = false; if( m_nLastHitSignalIndex != nSignalIndex ) { bFirstHit = true; m_nLastHitSignalIndex = nSignalIndex; } HitParam.szActionName = pStruct->szTargetHitAction; HitParam.fDamage = pStruct->fDamageProb * 0.01f; HitParam.fDurability = pStruct->fDurabilityDamageProb * 0.01f; HitParam.vVelocity = *pStruct->vVelocity; HitParam.vResistance = *pStruct->vResistance; HitParam.hHitter = GetMySmartPtr(); HitParam.hWeapon = GetActiveWeapon(0); HitParam.vPosition = vPos; HitParam.fStiffProb = pStruct->fStiffProb * 0.01f; HitParam.RemainTime = SignalEndTime; HitParam.nDamageType = pStruct->nDamageType; HitParam.nSkillSuperAmmorIndex = pStruct->nApplySuperAmmorIndex - 1; HitParam.nSkillSuperAmmorDamage = pStruct->nApplySuperAmmorDamage; HitParam.cAttackType = (char)pStruct->nAttackType; HitParam.DistanceType = (pStruct->nDistanceType == 0) ? CDnDamageBase::DistanceTypeEnum::Melee : CDnDamageBase::DistanceTypeEnum::Range; HitParam.HasElement = CalcHitElementType( ( pStruct->bUseSkillApplyWeaponElement == TRUE ) ? true : false ); HitParam.bIgnoreCanHit = ( pStruct->bIgnoreCanHit == TRUE ); HitParam.bIgnoreParring = ( pStruct->bIgnoreParring == TRUE ); HitParam.bReleaseCatchActor = ( pStruct->bReleaseCatchedActor == TRUE ); HitParam.nWeightValueLimit = pStruct->nWeightValueLimit; bool isFirstHitter = true; HitParam.nHitLimitCount = pStruct->nHitLimitCount; bool isHitLimited = false; HitLimitCountInfo* pHitLimitCountInfo = NULL; if (HitParam.nHitLimitCount != 0) { //HitLimitCountÁ¤º¸°¡ µî·ÏµÇ¾î ÀÖ´Â°Ô ÀÖ´ÂÁö È®ÀÎ.. HIT_LIMIT_COUNT_INFO_LIST::iterator findIter = m_HitLimitCountInfoList.find(nSignalIndex); if (findIter != m_HitLimitCountInfoList.end()) pHitLimitCountInfo = &findIter->second; else { //»õ·Î¿î Á¤º¸ Ãß°¡ Çϰí, ÇØ´ç ¸®½ºÆ®ÀÇ Á¤º¸ÀÇ Æ÷ÀÎÅÍ ¾ò´Â´Ù.. HitLimitCountInfo newHitLimitCountInfo(HitParam.nHitLimitCount, HitParam.nHitLimitCount); m_HitLimitCountInfoList.insert(HIT_LIMIT_COUNT_INFO_LIST::value_type(nSignalIndex, newHitLimitCountInfo)); HIT_LIMIT_COUNT_INFO_LIST::iterator findIter = m_HitLimitCountInfoList.find(nSignalIndex); if (findIter != m_HitLimitCountInfoList.end()) pHitLimitCountInfo = &findIter->second; } } // Note: ¿©±â¼­ Clear Çϸé ÀÌÀü¿¡ ¶§·È´ø ¾ÖµéÀÇ È÷Æ®½Ã±×³Î Á¾·á ½Ã°£ÀÌ º¹±¸µÇÁö ¾ÊÀº »óÅ·Π³Ñ¾î°¡¹ö¸± ¼ö ÀÖ½À´Ï´Ù. // ½´ÆÛ¾Æ¸Ó ÀÖ´Â ¾Ö°¡ ¸Â¾ÒÀ» ¶§ FPS°¡ 1.8ÀÌ µÇ¾î EndTime ÀÌ µÚ·Î ¹Ð¸° ä·Î ProcessPlaySpeed ¿¡¼­ Á¦´ë·Î º¹±¸ ½ÃÄÑÁÖ·Á¸é // ¸¶Áö¸·À¸·Î ¸ÂÀº ¾ÖµéÀ» ¸®½ºÆ®·Î º¹±¸½Ã۱â Àü¿¡ ³¯¸®¸é ¾ÈµË´Ï´Ù. m_hVecLastHitList.clear(); // Actor üũ for( DWORD i=0; inHitLimitCount != 0 && pHitLimitCountInfo->nHitCount <= 0)); if (isHitLimited) break; // Â÷Á® »óÅÂÈ¿°ú¶ó¸é ÇØ´ç »óÅÂÈ¿°úÀÇ ID ¸¦ À¯´ÏÅ© ¾ÆÀ̵𸦠»ç¿ëÇÑ´Ù. // ¼îÅ© ¿Àºê ·¼¸¯Ã³·³ °°Àº ¾×¼ÇÀ¸·Î Â÷Á® »óÅÂÈ¿°úÀÇ ÀνºÅϽº °¹¼ö´ë·Î µ¿½Ã¿¡ ¿©·¯ È÷Æ® ½Ã±×³ÎÀ» ¹ßµ¿½Ã۱â À§Çؼ­. if( m_hChargerBlowCalledOnSignal ) { if( !hVecList[i]->IsHittable( GetMySmartPtr(), LocalTime, pStruct, m_hChargerBlowCalledOnSignal->GetBlowID() ) ) continue; // ¿©±â¼­ hitparam ÀÇ À¯´ÏÅ© id ¸¦ ¼ÂÆÃÇØÁà¾ß ÃßÈÄ¿¡ ondamage ¿¡¼­ ÀÌ id º°·Î Á¤¸®µÇ¾î ÃßÈÄ ishittable È£Ãâ½Ã »ç¿ëÇÏ°Ô µÈ´Ù. HitParam.iUniqueID = m_hChargerBlowCalledOnSignal->GetBlowID(); } else { if( !hVecList[i]->IsHittable( GetMySmartPtr(), LocalTime, pStruct ) ) continue; } switch( hVecList[i]->GetHitCheckType() ) { case HitCheckTypeEnum::BoundingBox: { HitParam.vPosition = vPos; vDir = *hVecList[i]->GetPosition() - vPos; vDir.y = 0.f; hVecList[i]->GetBoundingBox( Box ); if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue; if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue; EtVec3Normalize( &vDir, &vDir ); fDot = EtVec3Dot( &vZVec, &vDir ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue; if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) continue; if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) continue; HitParam.vViewVec = -vDir; } break; case HitCheckTypeEnum::Collision: { SCollisionCapsule Capsule; SCollisionResponse CollisionResult; DNVector(SCollisionResponse) vCollisionResult; Capsule.Segment.vOrigin = vPos; float fHeight = fHeightMax - pStruct->fHeightMin; Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) ); Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f ); Capsule.fRadius = ( fDistanceMax + nWeaponLength ); EtVector3 vDestPos; if( hVecList[i]->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false ) continue; if( CollisionResult.pCollisionPrimitive ) { for( UINT k=0 ; kGetBoundingBox( Box ); if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } DNVector(EtVector3) vPointList; vPointList.push_back( Box.GetCenter() ); #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX || vCollisionResult[k].pCollisionPrimitive->Type == CT_CAPSULE ) { #else if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ) { #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL Box.GetVertices( vPointList ); } bool bCheck = false; for( DWORD m=0; mCheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == true ) { #else if( hVecList[i]->CheckCollisionHitCondition(vPos, m_Cross, vPointList[m], pStruct->fAngle) == true ) { #endif // PRE_FIX_63356 bCheck = true; break; } } if( bCheck == false ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } HitParam.vBoneIndex.push_back( hVecList[i]->GetObjectHandle()->GetParentBoneIndex( vCollisionResult[k].pCollisionPrimitive ) ); } } if( vCollisionResult.empty() ) continue; GetCenterPos( *CollisionResult.pCollisionPrimitive, vDestPos ); HitParam.vPosition = vDestPos; } else { ASSERT( 0 ); } if( pStruct->fDistanceMin > 100.f ) { vCollisionResult.clear(); Capsule.fRadius = pStruct->fDistanceMin; if( hVecList[i]->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == true ) { if( CollisionResult.pCollisionPrimitive ) { for( UINT k=0 ; kGetBoundingBox( Box ); if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } DNVector(EtVector3) vPointList; vPointList.push_back( Box.GetCenter() ); #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX || vCollisionResult[k].pCollisionPrimitive->Type == CT_CAPSULE ) { #else if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ) { #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL Box.GetVertices( vPointList ); } bool bCheck = false; for( DWORD m=0; mCheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == false ) { #else if( hVecList[i]->CheckCollisionHitCondition(vPos, m_Cross, vPointList[m], pStruct->fAngle) == false ) { #endif // PRE_FIX_63356 #else #if defined(PRE_FIX_63356) if( hVecList[i]->CheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == true ) { #else if( hVecList[i]->CheckCollisionHitCondition(vPos, m_Cross, vPointList[m], pStruct->fAngle) == true ) { #endif // PRE_FIX_63356 #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL bCheck = true; break; } } #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL if( bCheck == true ) { #else if( bCheck == false ) { #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } int nBoneIndex = hVecList[i]->GetObjectHandle()->GetParentBoneIndex( vCollisionResult[k].pCollisionPrimitive ); std::vector::iterator it = std::find( HitParam.vBoneIndex.begin(), HitParam.vBoneIndex.end(), nBoneIndex ); if( it != HitParam.vBoneIndex.end() ) { HitParam.vBoneIndex.erase( it ); } } } } } if( HitParam.vBoneIndex.empty() ) continue; } HitParam.vViewVec = vPos - vDestPos; EtVec3Normalize( &HitParam.vViewVec, &HitParam.vViewVec ); } break; } HitParam.bFirstHit = bFirstHit; bFirstHit = false; bHit = true; if( !HitParam.szActionName.empty() ) { m_hVecLastHitList.push_back( hVecList[i] ); // ÇÁ·¹ÀÓÀÌ »¡¶óÁ³À» °æ¿ì¿¡ Áߺ¹À¸·Î ¾×ÅͰ¡ µé¾î¿Ã ¼ö ÀÖ´Ù. if( m_hVecLastHitListByRemainTime.end() == find( m_hVecLastHitListByRemainTime.begin(), m_hVecLastHitListByRemainTime.end(), hVecList[i] ) ) { m_hVecLastHitListByRemainTime.push_back( hVecList[i] ); } #if defined(PRE_ADD_PREFIX_SYSTE_RENEW) // HitSignal¿¡¼­ ½ºÅ³ ¿©ºÎ »ó°ü¾øÀÌ Á¢µÎ»ç ½ºÅ³ ¹ßµ¿ // Á¢µÎ¾î »óÅÂÈ¿°ú ¹«½ÃÇÏ´Â »óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é Àû¿ë ¾ÈµÊ // #40186 Á¢¹Ì»ç? ¹ßµ¿ Á¶°Ç º¯°æ (µ¥¹ÌÁö ºñÀ²ÀÌ 0ÀÎ °æ¿ì ¹ßµ¿ µÇÁö ¾Êµµ·ÏÇÔ.) if (HitParam.bFirstHit && pStruct->fDamageProb != 0.0f && !IsAppliedThisStateBlow(STATE_BLOW::BLOW_183) && isFirstHitter) { ProcessPrefixOffenceSkill_New(); isFirstHitter = false; } #else ////////////////////////////////////////////////////////////////////////// // Á¢µÎ¾î °ø°Ý¿ë ½ºÅ³ ¹ßµ¿ Áغñ ÀÛ¾÷.. // ÆòŸÀ϶§¸¸ Á¢µÎ¾î ½Ã½ºÅÛ °ø°Ý½ºÅ³ ¹ßµ¿ // ÆòŸÀ̰í, HitÇÁ·¹ÀÓ¿¡ óÀ½ µé¾î ¿Ô°í, ù¹øÂ° ¸Â´Â ³à¼®À϶§ bool isCanUsePrefixSkill = CanUsePrefixSkill(); if (isCanUsePrefixSkill && HitParam.bFirstHit && isFirstHitter) { OutputDebug("CDnActor::OnSignal -> STE_Hit start %d current %d end %d\n", (int)SignalStartTime, (int)LocalTime, (int)SignalEndTime); //¿©±â¼­´Â Àڽſ¡°Ô Àû¿ë ÇÏ´Â »óÅ ȿ°ú¸¸ Àû¿ë½Ã۰í, //¸Â´Â ³à¼®¿¡°Ô Àû¿ëÇØ¾ßÇÒ »óÅ ȿ°ú´Â Target->OnDamage¿¡¼­ ó¸® µÇµµ·ÏÇÑ´Ù.?? ProcessPrefixOffenceSkill( 1.0f ); isFirstHitter = false; } #endif // PRE_ADD_PREFIX_SYSTE_RENEW #ifdef PRE_ADD_MONSTER_CATCH if( HitParam.bReleaseCatchActor ) { if( IsMonsterActor() ) { static_cast(this)->ReleaseThisActor( hVecList[ i ] ); } } #endif // #ifdef PRE_ADD_MONSTER_CATCH hVecList[i]->OnDamage( GetMySmartPtr(), HitParam, pStruct ); if( 0 != pStruct->StateEffectFilter ) { OnHitSignalStateEffectFilterException( hVecList[ i ]->GetUniqueID(), pStruct->StateEffectFilter ); } bOnDamageCalled = true; //Hit¼ö Áõ°¡ if (pHitLimitCountInfo) pHitLimitCountInfo->nHitCount--; } hVecActorToApplyStateEffect.push_back( hVecList[i] ); #ifdef PRE_ADD_TRIGGER_BY_HIT_CONDITION if( pStruct->szTriggerEventParameter != NULL && IsPlayerActor() == false && hVecList[i]->IsMonsterActor() ) { CDnMonsterActor* pTrigerTargetMonsterActor = static_cast( hVecList[i].GetPointer()); if( pTrigerTargetMonsterActor ) { std::string strParam = pStruct->szTriggerEventParameter; std::vector tokens; TokenizeA(strParam, tokens, ";"); if (tokens.size() == 2) { if( pTrigerTargetMonsterActor->GetMonsterClassID() == atoi(tokens[0].c_str()) ) { CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventArea", pTrigerTargetMonsterActor->GetBirthAreaHandle() ); CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "ActorHandle", pTrigerTargetMonsterActor->GetUniqueID() ); CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventID", atoi(tokens[1].c_str()) ); CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnActor::TriggerEvent", CDnActionBase::m_LocalTime, 0.f ); } } } } #endif } bool bIsFarm = false; CDnGameTask *pGameTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); if( pGameTask && pGameTask->GetGameTaskType() == GameTaskType::Farm ) bIsFarm = true; if( false == bIsFarm && IsProcessSkill() ) { int iNumActorApplyStateEffect = (int)hVecActorToApplyStateEffect.size(); m_hProcessSkill->CheckTargetCount( iNumActorApplyStateEffect ); for( int i = 0; i < iNumActorApplyStateEffect; ++i ) { // ´ë»óÀÌ ¾óÀ½°¨¿Á »óÅÂÀ϶§´Â »óÅÂÈ¿°ú Àû¿ë ¹«½Ã if (hVecActorToApplyStateEffect[ i ]->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149)) continue; // ½ºÅ³ ´ë»ó ¼³Á¤ÀÌ ¾Æ±ºÀΰ¡ Ÿ°ÙÀΰ¡¿¡ µû¶ó »óÅÂÈ¿°ú Àû¿ëÀ» ±¸ºÐÇÑ´Ù. switch( m_hProcessSkill->GetTargetType() ) { case CDnSkill::Enemy: case CDnSkill::Self: if( GetTeam() == hVecActorToApplyStateEffect[ i ]->GetTeam() ) continue; break; case CDnSkill::Friend: case CDnSkill::Party: if( GetTeam() != hVecActorToApplyStateEffect[ i ]->GetTeam() ) continue; break; // ½ºÅ³ Àû¿ë ´ë»óÀÌ ¾Æ±º/Àû±º ÀüºÎ ´Ù ¶ó¸é »óÅÂÈ¿°ú Àû¿ë ÂÊ¿¡¼­ Àû¿ë ¿©ºÎ¸¦ ±¸ºÐÇØ¾ß ÇÑ´Ù. case CDnSkill::All: break; } // »óÅÂÀÌ»ó Add ½Ã¿¡ Áö¼Ó ±¸ºÐ À妽º ó¸® ÇÊ¿ä. // ÇØ´ç ActorÀÇ Áö¼ÓÈ¿°ú ±¸ºÐ À妽º¸¦ ±¸ºÐÇÏ¿© ¼º°øÇÑ °æ¿ì¿¡ »óÅÂÀÌ»ó Ãß°¡ ½ÃÅ´. map mapDuplicateResult; CDnSkill::CanApply eResult = CDnSkill::CanApplySkillStateEffect( hVecActorToApplyStateEffect[i], m_hProcessSkill, mapDuplicateResult, true ); if( CDnSkill::CanApply::Fail != eResult ) { for( DWORD k = 0; k < m_hProcessSkill->GetStateEffectCount(); k++ ) { CDnSkill::StateEffectStruct *pLocalStruct = m_hProcessSkill->GetStateEffectFromIndex(k); if (pStruct->szSkipStateBlows && CDnSkill::IsSkipStateBlow(pStruct->szSkipStateBlows, (STATE_BLOW::emBLOW_INDEX)pLocalStruct->nID)) continue; // ¾Æ±º±îÁö Èú ½ÃÄÑÁÖ´Â ½ºÅ³ÀÇ °æ¿ì¿£ Self Èú°ú Target Èú µÎ °³ÀÇ »óÅÂÈ¿°ú°¡ ¼±¾ðµÇ¾îÀÖµû. // Self »óÅÂÈ¿°ú´Â Àڽſ¡°Ô ÀÌ¹Ì Àû¿ëµÇ¾ú°í ¿©±ä Hit ½Ã±×³Î ÆÇÁ¤µÇ´Â °÷ÀÌ±â ‹š¹®¿¡ Target ¸¸ Àû¿ëµÈ´Ù. switch( pLocalStruct->ApplyType ) { case CDnSkill::ApplySelf: continue; break; case CDnSkill::ApplyTarget: break; case CDnSkill::ApplyEnemy: if( GetTeam() == hVecActorToApplyStateEffect[ i ]->GetTeam() ) continue; break; case CDnSkill::ApplyFriend: if( GetTeam() != hVecActorToApplyStateEffect[ i ]->GetTeam() ) continue; break; } // °°Àº ½ºÅ³ ÁßøÀÏ °æ¿ì¿£ ½ºÅ³ È¿°ú Áß¿¡ È®·ü üũÇÏ´Â °ÍµéÀº ÀÌ¹Ì CanApplySkillStateEffect ¿¡¼­ È®·üüũµÇ°í // Åë°úµÈ »óÅÂÀÌ´Ù. µû¶ó¼­ ¿©±â¼± È®·ü üũ µÈ°ÇÁö È®ÀÎÇÏ°í µÈ°Å¶ó¸é ´Ù½Ã È®·ü üũ ¾ÈÇϵµ·Ï ÇÔ¼ö È£Ãâ ÇØÁØ´Ù. bool bAllowAddThisSE = true; bool bCheckCanBegin = true; if( CDnSkill::ApplyDuplicateSameSkill == eResult ) { map::iterator iter = mapDuplicateResult.find( pLocalStruct->nID ); // ¸Ê¿¡ ¾ø´Â °æ¿ì ÇöÀç ¾×ÅͰ¡ »óÅÂÈ¿°ú¿¡ °É·ÁÀÖÁö ¾ÊÀ¸¹Ç·Î ±×³É Á¤»óÀûÀ¸·Î »óÅÂÈ¿°ú Ãß°¡ ·çƾ ½ÇÇà. if( mapDuplicateResult.end() != iter ) { // °°Àº ½ºÅ³ÀÇ È®·üÀÖ´Â »óÅÂÈ¿°ú°¡ ÇöÀç °É·ÁÀ־ CanAdd ¸¦ È£ÃâÇØº¸¾ÒÀ¸³ª ½ÇÆÐÇßÀ½. // ÀÌ·± °æ¿ì¿£ »óÅÂÈ¿°ú Ãß°¡ÇÏÁö ¾Ê´Â´Ù. if( false == (iter->second) ) bAllowAddThisSE = false; else // ÀÌ¹Ì CanAdd ¸¦ Åë°úÇÑ »óÅÂÀ̹ǷΠCmdAddStateEffect È£Ã⠽à µû·Î üũÇÏÁö ¾Êµµ·Ï ÇØÁØ´Ù. bCheckCanBegin = false; } } if( bAllowAddThisSE ) { // #72931 ½ºÅ©¸®¸Ó ÀúÁÖ ÄðŸÀÓ °øÀ¯ ó¸® -> ³ªÁß¿¡ ÀÌ·±½ÄÀ¸·Î ¾²´Â°Å ¸¹¾ÆÁö¸é ÀϹÝÈ­ÇØ¾ßÇÔ bool bShareCurseCoolTime = false; if( pLocalStruct->nID == STATE_BLOW::BLOW_244 ) { DNVector(DnBlowHandle) vlhBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_244, vlhBlows ); if( static_cast( vlhBlows.size() ) > 0 ) { CDnCurseBlow* pDnCurseBlow = static_cast( vlhBlows[0].GetPointer() ); if( pDnCurseBlow ) { pLocalStruct->szValue += ";"; pLocalStruct->szValue += FormatA( "%f", pDnCurseBlow->GetCoolTime() ); bShareCurseCoolTime = true; } } } // ¿©±â¼­ µî·ÏµÇ¾î ÀÖ´Â Á¦°Å µÇ¾î¾ßÇÒ »óÅÂÈ¿°úµé ¾ø¾Ø´Ù. [2010/12/08 semozz] hVecActorToApplyStateEffect[i]->RemoveResetStateBlow(); hVecActorToApplyStateEffect[i]->CmdAddStateEffect( m_hProcessSkill->GetInfo(), (STATE_BLOW::emBLOW_INDEX)pLocalStruct->nID, pLocalStruct->nDurationTime, pLocalStruct->szValue.c_str(), false, bCheckCanBegin ); if( bShareCurseCoolTime ) // #72931 ÄðŸÀÓ ºÙ¿´´ø°Å ´Ù½Ã Á¦°Å { std::string::size_type delimiterindex = pLocalStruct->szValue.rfind( ";" ); if( delimiterindex != std::string::npos ) { pLocalStruct->szValue.erase( delimiterindex, pLocalStruct->szValue.length() - delimiterindex ); } } // ¿ø·¡´Â OnDamage() È£ÃâµÇ¸é ¾ÈÂÊ¿¡¼­ DamageRemainTime À» ¼ÂÆÃÇØÁØ´Ù. ÇÏÁö¸¸ // Èúó·³ µ¥¹ÌÁö ¾øÀÌ »óÅÂÈ¿°ú¸¸ Ãß°¡½Ã۱â À§ÇÑ hit ½Ã±×³Îµµ ÀÖÀ¸¹Ç·Î OnDamage() È£ÃâµÇÁö ¾Ê¾Ò´õ¶óµµ // ¿©±â¼­ LastDamageTime ÀÌ ¼ÂÆÃ ¾ÈµÇ¾îÀÖ´Â ³à¼®Àº ¼ÂÆÃÇØÁÖµµ·Ï ÇÑ´Ù. // ÀÌ·¸°Ô ÇØ¾ß hit ½Ã±×³Î¿¡ Çѹ游 ¸Â´Â´Ù. if( !bOnDamageCalled ) { hVecActorToApplyStateEffect[ i ]->SetDamageRemainTime( GetUniqueID(), HitParam.RemainTime ); hVecActorToApplyStateEffect[ i ]->SetLastDamageHitUniqueID( GetUniqueID(), HitParam.iUniqueID ); } } } } // ½ºÅ³ »ç¿ë ³¡³µÀ¸¸é ¸®¼Â¸®½ºÆ® ÃʱâÈ­ [2010/12/09 semozz] hVecActorToApplyStateEffect[i]->InitStateBlowIDToRemove(); } } if( bHit ) { m_LastHitSignalTime = SignalEndTime; OnHitFinish( LocalTime, pStruct ); } else m_LastHitSignalTime = -1; // ÇÁ¶ø üũ // Note: ÇÁ¶øÃ¼Å©´Â »óÅÂÈ¿°ú¸¸ ÀÖ´Â Heal °°Àº °ÍÀº üũÇÏÁö ¾Êµµ·Ï ÇÕ´Ï´Ù. HitAction ÀÌ ¾ø´Â °ÍÀ¸·Î ±¸ºÐ. if( false == HitParam.szActionName.empty() //ÇÊÅͰ¡ Àû¿ëµÇ¾î ÀÖÁö ¾ÊÀ»¶§¸¸ ÇÁ¶ø¿¡ µ¥¹ÌÁö¸¦ ÁÙ ¼ö ÀÖ´Ù. && pStruct->StateEffectFilter == 0 ) { DNVector(CEtWorldProp*) pVecProp; CDnWorld* pWorld = CDnWorld::GetInstancePtr(GetRoom()); pWorld->ScanProp( vPos, fDistance, pVecProp ); for( DWORD i=0; iIsBrokenType() ) continue; if( !((CDnWorldBrokenProp*)pVecProp[i])->IsHittable( GetMySmartPtr(), LocalTime ) ) continue; pVecProp[i]->GetBoundingBox( Box ); if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue; if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue; vDir = ((CDnWorldProp*)pVecProp[i])->GetMatEx()->m_vPosition - vPos; EtVec3Normalize( &vDir, &vDir ); fDot = EtVec3Dot( &vZVec, &vDir ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue; if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < m_Cross.m_vPosition.y + pStruct->fHeightMin ) continue; if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > m_Cross.m_vPosition.y + fHeightMax ) continue; HitParam.vViewVec = -vDir; ((CDnWorldProp*)pVecProp[i])->OnDamage( GetMySmartPtr(), HitParam ); } } ////////////////////////////////////////////////////////////////////////// // Á¢µÎ¾î °ø°Ý¿ë ½ºÅ³ ³¡.. InitPrefixOffenceSkills(); ////////////////////////////////////////////////////////////////////////// // PROFILE_TICK_TEST_BLOCK_END(); } break; case STE_VelocityAccel: { VelocityAccelStruct *pStruct = (VelocityAccelStruct *)pPtr; MAMovementBase *pMovement = GetMovement(); // #24949 VelocityAccel ½Ã±×³Î »ç¿ëÇÏ´Â ºÎºÐµµ ¸·µµ·Ï ó¸®. EtVector3 vVelocity = *pStruct->vVelocity; EtVector3 vResistance = *pStruct->vResistance; if( 0 < GetCantXZMoveSEReferenceCount() ) { vVelocity.x = vVelocity.z = 0.0f; vResistance.x = vResistance.z = 0.0f; } if( pMovement ) { pMovement->SetVelocity( vVelocity ); pMovement->SetResistance( vResistance ); } } break; case STE_State: { if( IsCustomProcessSignal() ) break; StateStruct *pStruct = (StateStruct *)pPtr; int nState = CDnActorState::s_nActorStateIndex[pStruct->nStateOne] | CDnActorState::s_nActorStateIndex[pStruct->nStateTwo] | CDnActorState::s_nActorStateIndex[pStruct->nStateThree]; SetState( (ActorStateEnum)nState ); } break; case STE_CustomState: { if( IsCustomProcessSignal() ) break; CustomStateStruct *pStruct = (CustomStateStruct *)pPtr; int nState = CDnActorState::s_nActorCustomStateIndex[pStruct->nStateOne] | CDnActorState::s_nActorCustomStateIndex[pStruct->nStateTwo] | CDnActorState::s_nActorCustomStateIndex[pStruct->nStateThree]; SetCustomState( (ActorCustomStateEnum)nState ); } break; case STE_CanHit: { // °áºù »óŰ¡ µÇ¾úÀ»¶§ ÇöÀç ÁøÇàÁßÀÎ ¾×¼Ç¿¡¼­ ÇÁ·¹ÀÓÀÌ ½ºÅ¾µÇ´Â °æ¿ì°¡Àִµ¥ // ƯÁ¤ ¾×¼ÇÀÇ STE_CanHit °¡ False ÀÎ »óÅÂÀ϶§´Â °áºù»óÅ¿¡¼­µµ Hit °¡ µé¾î°¡Áö ¾Ê´ø ¹®Á¦°¡ À־ °áºù »óÅ¿¡¼­´Â ¹«Á¶°Ç // ¸Âµµ·Ï ÇØÁØ´Ù. if(GetStateBlow()->IsApplied( STATE_BLOW::BLOW_041)) { SetHittable(true); break; } CanHitStruct *pStruct = (CanHitStruct *)pPtr; SetHittable( ( pStruct->bHittable == TRUE ) ? true : false ); } break; case STE_CanMove: { if( CDnActorState::Cant_Move != (m_StateEffect & CDnActorState::Cant_Move) ) { CanMoveStruct *pStruct = (CanMoveStruct *)pPtr; SetMovable( ( pStruct->bCanMove == TRUE ) ? true : false ); } } break; case STE_SendAction_Weapon: { SendAction_WeaponStruct *pStruct = (SendAction_WeaponStruct *)pPtr; if( 2 <= pStruct->nWeaponIndex ) // º¸Á¶¹«±â¿ë À妽ºÀÌ´Ù. break; if( !GetActiveWeapon( pStruct->nWeaponIndex ) ) break; if( pStruct->szActionName ) { // Ç÷¹ÀÌ¾î ¾×ÅÍÀÎ °æ¿ìÇöÀç ¾×¼Ç¿¡¼­ ½ò ¼ö ÀÖ´Â ¹ß»çü °¹¼ö¿¡ ¹«±âÀÇ ¹ß»çü °¹¼ö¸¦ ´õÇØÁØ´Ù. if( GetActiveWeapon( pStruct->nWeaponIndex )->IsExistAction( pStruct->szActionName ) ) { GetActiveWeapon( pStruct->nWeaponIndex )->SetActionQueue( pStruct->szActionName ); } } } break; case STE_MotionSpeed: { if( IsModifyPlaySpeed() ) break; MotionSpeedStruct *pStruct = (MotionSpeedStruct *)pPtr; float fIncreadSpeed = 1.f / pStruct->fFrame * 60.f; DWORD dwTime = (DWORD)( ( SignalEndTime - SignalStartTime ) * fIncreadSpeed ); float fSpeed = 1.f / 60.f * pStruct->fFrame; SetPlaySpeed( dwTime, fSpeed ); } break; case STE_NormalSuperAmmor: { NormalSuperAmmorStruct *pStruct = (NormalSuperAmmorStruct *)pPtr; m_bEnableNormalSuperAmmor = ( pStruct->bEnable == TRUE ) ? true : false; m_nNormalSuperAmmorTime = pStruct->nTime; m_fBreakNormalSuperAmmorDurability = pStruct->fBreakDurability; if ( m_bIngnoreNormalSuperArmor ) { m_bEnableNormalSuperAmmor = false; } } break; case STE_ResetVelocity: { ResetVelocityStruct *pStruct = (ResetVelocityStruct *)pPtr; if( pStruct->bXAxis ) { SetVelocityX( 0.f ); SetResistanceX( 0.f ); } if( pStruct->bYAxis ) { SetVelocityY( 0.f ); SetResistanceY( 0.f ); } if( pStruct->bZAxis ) { SetVelocityZ( 0.f ); SetResistanceZ( 0.f ); } } break; case STE_Projectile: { ProjectileStruct *pStruct = (ProjectileStruct *)pPtr; OutputDebug("%s m_bOnSignalFromChargerSE: %d m_ActorType: %d", __FUNCTION__, m_bOnSignalFromChargerSE, m_ActorType); // Note: Ç÷¹À̾îÀÎ °æ¿ì¿£ ¸ðµç ÇÁ·ÎÁ§Å¸ÀÏ ÆÐŶÀ» Ŭ¶ó·ÎºÎÅÍ ¹Þ¾Æ¼­ »ý¼ºÇÕ´Ï´Ù. // Direction ŸÀÔÀÌ¶óµµ °¢ ·ÎÄÈ Ä«¸Þ¶ó ¹æÇâ¿¡ µû¸¥ ¼³Á¤µµ Àֱ⠶§¹®¿¡.. if( false == m_bOnSignalFromChargerSE ) if( m_ActorType <= CDnActorState::Reserved6 ) break; MatrixEx LocalCross = *GetMatEx(); CDnProjectile *pProjectile = CDnProjectile::CreateProjectile( GetRoom(), GetMySmartPtr(), LocalCross, pStruct ); if( pProjectile == NULL ) break; pProjectile->SetShooterType( GetMySmartPtr(), m_nActionIndex, nSignalIndex ); //bool bActorAttachWeapon = false; //if( pStruct->nWeaponTableID == 0 && GetWeapon(1) ) bActorAttachWeapon = true; if( m_bOnSignalFromChargerSE && m_hChargetDestActor ) { DNVector(DnBlowHandle) vlhChargerBlows; m_hChargetDestActor->GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_062, vlhChargerBlows ); // 1°³ ÀÌ»ó Áߺ¹µÇÁö ¾Ê´Â °Ô ÁÁÀºµ¥ ±âȹ¿¡¼­ ¾îÂî ÇÒÁö. for( int i = 0; i < (int)vlhChargerBlows.size(); ++i ) { if( vlhChargerBlows[i] ) static_cast( vlhChargerBlows.at( i ).GetPointer() )->OnProjectileSignal( pProjectile ); } } if( false == m_bOnSignalFromChargerSE ) { OnProjectile( pProjectile, pStruct, LocalCross, nSignalIndex ); OnSkillProjectile( pProjectile ); } } break; case STE_SkillSuperAmmor: { SkillSuperAmmorStruct *pStruct = (SkillSuperAmmorStruct *)pPtr; m_nSkillSuperAmmorValue[0] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorOneProb ); m_nSkillSuperAmmorValue[1] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorTwoProb ); m_nSkillSuperAmmorValue[2] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorThreeProb ); m_nSkillSuperAmmorValue[3] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorFourProb ); memcpy( m_nLastUpdateSkillSuperAmmorValue, m_nSkillSuperAmmorValue, sizeof(m_nSkillSuperAmmorValue) ); m_nSkillSuperAmmorTime = pStruct->nTime; m_fSkillSuperAmmorDamageDecreaseProb = pStruct->fDamageDecreaseProb; } break; case STE_SummonMonster: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonMonsterStruct* pStruct = (SummonMonsterStruct *)pPtr; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); if( pGameTask ) { // ³»ºÎÀûÀ¸·Î °ªÀ» ¹Ù²ã¼­ »ç¿ëÇϱ⠶§¹®¿¡ ¹Ýµå½Ã º¹»çÇØ¼­ »ç¿ëÇÑ´Ù. #ifdef PRE_FIX_MEMOPT_SIGNALH SummonMonsterStruct Struct; CopyShallow_SummonMonsterStruct(Struct, pStruct); #else SummonMonsterStruct Struct = *pStruct; #endif // 167¹ø ¼Òȯ ¸ó½ºÅÍ ½ºÅ³·¹º§ °­Á¦ ¼ÂÆÃ »óÅÂÈ¿°ú ó¸®. /////////////////// if( IsPlayerActor() ) { if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_167 ) ) { DNVector(DnBlowHandle) vlBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_167, vlBlows ); if( false == vlBlows.empty() ) { Struct.nForceSkillLevel = (int)vlBlows.front()->GetFloatValue(); } } } ////////////////////////////////////////////////////////////////////////// if(Struct.PositionCheck == TRUE ) { MatrixEx Cross = *GetMatEx(); Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; if( INSTANCE(CDnWorld).IsOnNavigationMesh( Cross.GetPosition() ) == false ) break; } pGameTask->RequestSummonMonster( GetActorHandle(), &Struct ); } } break; //case STE_SummonProp: // { // SummonPropStruct *pStruct = (SummonPropStruct *)pPtr; // MatrixEx Cross = m_Cross; // Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; // Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; // Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; // float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); // EtVector3 vRotate; // vRotate = *pStruct->vRotate; // vRotate.y += EtToDegree( acos(fDot) ); // CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); // DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, Cross.m_vPosition, vRotate, *pStruct->vScale ); // } // break; // **************************************************************************************************************** // ÇÁ¶ø ¼Òȯ ½Ã±×³Î¿¡¼­ ¼ÒȯµÇ´Â ÇÁ¶ø Ŭ·¡½ºµéÀº ¹Ýµå½Ã void ReleasePostCustomParam() ¸¦ ±¸ÇöÇØ¾ß ÇÔ!! // ŸÀÔ¿¡ ¸ÂÃç¼­ ÇÁ¶ø struct ¸¦ »èÁ¦ÇÏÁö ¾ÊÀ¸¸é boost::pool ¿¡¼­ ¸Þ¸ð¸® courrupt // **************************************************************************************************************** case STE_SummonChestProp: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonChestPropStruct *pStruct = (SummonChestPropStruct *)pPtr; MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); EtVector3 vRotate; vRotate = *pStruct->vRotate; vRotate.y += EtToDegree( acos(fDot) ); ChestStruct* pChestPropInfo = new ChestStruct; pChestPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID; pChestPropInfo->nNeedKeyID = pStruct->nNeedKeyID; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_Chest, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pChestPropInfo ); if( -1 < pStruct->nLifeTime ) hProp->SetLifeTime( pStruct->nLifeTime ); hProp->SetMasterActor(GetMySmartPtr()); } break; case STE_SummonBrokenProp: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonBrokenPropStruct *pStruct = (SummonBrokenPropStruct *)pPtr; MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); EtVector3 vRotate; vRotate = *pStruct->vRotate; vRotate.y += EtToDegree( acos(fDot) ); BrokenStruct* pBrokenPropInfo = new BrokenStruct; pBrokenPropInfo->nDurability = pStruct->nDurability; pBrokenPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_Broken, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBrokenPropInfo ); if( -1 < pStruct->nLifeTime ) hProp->SetLifeTime( pStruct->nLifeTime ); hProp->SetMasterActor(GetMySmartPtr()); } break; case STE_SummonBrokenDamageProp: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonBrokenDamagePropStruct *pStruct = (SummonBrokenDamagePropStruct *)pPtr; MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); EtVector3 vRotate; vRotate = *pStruct->vRotate; vRotate.y += EtToDegree( acos(fDot) ); BrokenDamageStruct* pBrokenDamagePropInfo = new BrokenDamageStruct; pBrokenDamagePropInfo->nMonsterTableID = 102; // goblin pBrokenDamagePropInfo->nDurability = pStruct->nDurability; pBrokenDamagePropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID; pBrokenDamagePropInfo->nSkillTableID = pStruct->nSkillTableID; pBrokenDamagePropInfo->nSkillLevel = pStruct->nSkillLevel; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_BrokenDamage, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBrokenDamagePropInfo ); if( !hProp ) break; MAActorProp* pActorProp = dynamic_cast(hProp.GetPointer()); _ASSERT( pActorProp ); if( pActorProp ) pActorProp->CopyActorStateFromThis( GetMySmartPtr() ); if( -1 < pStruct->nLifeTime ) hProp->SetLifeTime( pStruct->nLifeTime ); hProp->SetMasterActor(GetMySmartPtr()); } break; case STE_SummonHitMoveDamageBrokenProp: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonHitMoveDamageBrokenPropStruct *pStruct = (SummonHitMoveDamageBrokenPropStruct *)pPtr; MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); EtVector3 vRotate; vRotate = *pStruct->vRotate; vRotate.y += EtToDegree( acos(fDot) ); HitMoveDamageBrokenStruct* pHitMoveDamageBrokenPropInfo = new HitMoveDamageBrokenStruct; pHitMoveDamageBrokenPropInfo->nMonsterTableID = 102; // goblin pHitMoveDamageBrokenPropInfo->nDurability = pStruct->nDurability; pHitMoveDamageBrokenPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID; pHitMoveDamageBrokenPropInfo->MovingAxis = pStruct->MovingAxis; pHitMoveDamageBrokenPropInfo->fDefaultAxisMovingSpeed = pStruct->fDefaultAxisMovingSpeed; pHitMoveDamageBrokenPropInfo->fMaxAxisMoveDistance = pStruct->fMaxAxisMoveDistance; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_HitMoveDamageBroken, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pHitMoveDamageBrokenPropInfo ); if( !hProp ) break; MAActorProp* pActorProp = dynamic_cast(hProp.GetPointer()); _ASSERT( pActorProp ); if( pActorProp ) pActorProp->CopyActorStateFromThis( GetMySmartPtr() ); if( -1 < pStruct->nLifeTime ) hProp->SetLifeTime( pStruct->nLifeTime ); hProp->SetMasterActor(GetMySmartPtr()); } break; case STE_SummonBuffProp: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonBuffPropStruct *pStruct = (SummonBuffPropStruct *)pPtr; MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); EtVector3 vRotate; vRotate = *pStruct->vRotate; vRotate.y += EtToDegree( acos(fDot) ); BuffStruct* pBuffPropInfo = new BuffStruct; pBuffPropInfo->nMonsterTableID = 102; // goblin pBuffPropInfo->nSkillTableID = pStruct->nSkillTableID; pBuffPropInfo->nSkillLevel = pStruct->nSkillLevel; pBuffPropInfo->nTeam = pStruct->nTeam; pBuffPropInfo->fCheckRange = pStruct->fCheckRange; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_Buff, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBuffPropInfo ); if( !hProp ) break; MAActorProp* pActorProp = dynamic_cast(hProp.GetPointer()); _ASSERT( pActorProp ); if( pActorProp ) pActorProp->CopyActorStateFromThis( GetMySmartPtr() ); if( -1 < pStruct->nLifeTime ) hProp->SetLifeTime( pStruct->nLifeTime ); static_cast(hProp.GetPointer())->SetSummoner( GetMySmartPtr() ); hProp->SetMasterActor(GetMySmartPtr()); } break; case STE_SummonBuffBrokenProp: { // #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ.. if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break; SummonBuffBrokenPropStruct *pStruct = (SummonBuffBrokenPropStruct *)pPtr; MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z; float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis ); EtVector3 vRotate; vRotate = *pStruct->vRotate; vRotate.y += EtToDegree( acos(fDot) ); BuffBrokenStruct* pBuffBrokenPropInfo = new BuffBrokenStruct; pBuffBrokenPropInfo->nMonsterTableID = 102; // goblin pBuffBrokenPropInfo->nDurability = pStruct->nDurability; pBuffBrokenPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID; pBuffBrokenPropInfo->nSkillTableID = pStruct->nSkillTableID; pBuffBrokenPropInfo->nSkillLevel = pStruct->nSkillLevel; pBuffBrokenPropInfo->nTeam = pStruct->nTeam; pBuffBrokenPropInfo->fCheckRange = pStruct->fCheckRange; CDnGameTask* pGameTask = static_cast(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" )); DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_BuffBroken, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBuffBrokenPropInfo ); if( !hProp ) break; MAActorProp* pActorProp = dynamic_cast(hProp.GetPointer()); _ASSERT( pActorProp ); if( pActorProp ) pActorProp->CopyActorStateFromThis( GetMySmartPtr() ); if( -1 < pStruct->nLifeTime ) hProp->SetLifeTime( pStruct->nLifeTime ); static_cast(hProp.GetPointer())->SetSummoner( GetMySmartPtr() ); hProp->SetMasterActor(GetMySmartPtr()); } break; // **************************************************************************************************************** // ÇÁ¶ø ¼Òȯ ½Ã±×³Î¿¡¼­ ¼ÒȯµÇ´Â ÇÁ¶ø Ŭ·¡½ºµéÀº ¹Ýµå½Ã void ReleasePostCustomParam() ¸¦ ±¸ÇöÇØ¾ß ÇÔ!! // **************************************************************************************************************** case STE_DropItem: { DropItemStruct *pStruct = (DropItemStruct*)pPtr; DNVector(CDnItem::DropItemStruct) VecList; CDnDropItem::CalcDropItemList( GetRoom(), pStruct->nDropItemTableID, VecList ); MatrixEx Cross = m_Cross; Cross.m_vPosition += Cross.m_vXAxis * pStruct->vOffset->x; Cross.m_vPosition += Cross.m_vYAxis * pStruct->vOffset->y; Cross.m_vPosition += Cross.m_vZAxis * pStruct->vOffset->z; CDnItemTask *pTask = (CDnItemTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "ItemTask" ); int nSeed = 0; for( DWORD i=0; ibFixPosition?true:false) == true) nSeed = 0; else nSeed = VecList[i].nSeed; #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD) pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, nSeed, VecList[i].nCount, 0, -1, VecList[i].nEnchantID ); #else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD) pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, nSeed, VecList[i].nCount, 0 ); #endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD) #else #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD) pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, VecList[i].nSeed, VecList[i].nCount, 0, -1, VecList[i].nEnchantID ); #else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD) pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, VecList[i].nSeed, VecList[i].nCount, 0 ); #endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD) #endif // PRE_FIX_46730 } } break; // Çѱâ 2009.7.27 // Àڽſ¡°Ô »ç¿ëÇÏ´Â È¿°ú Àû¿ë ½Ã°£ °ü·Ã (#1911) case STE_ApplyStateEffect: { // ½ºÅ³À» »ç¿ëÇÑ ¼ø°£ »óÅÂÈ¿°ú Àû¿ëµÇ±â Àü¿¡ ¾×ÅͰ¡ Á×À¸¸é »óÅÂÈ¿°ú´Â Ãß°¡µÇÁö ¾ÊÀ¸¹Ç·Î // ¾Æ·¡·Î »óÅÂÈ¿°ú ·çƾÀ» ÁøÇà½ÃŰÁö ¾Ê´Â´Ù. if( GetHP() <= 0 ) { if( m_hAuraSkill && m_hAuraSkill->IsAuraOn() ) { OnSkillAura( m_hAuraSkill, false ); } ClearSelfStateSignalBlowQueue(); break; } if( false == m_dqApplySelfStateBlowQ.empty() ) { ApplyStateEffectStruct* pStruct = (ApplyStateEffectStruct*)pPtr; if( pStruct->StateEffectIndex < (int)m_dqApplySelfStateBlowQ.size() ) { const S_NO_PACKET_SELF_STATEBLOW& StateBlowInfo = m_dqApplySelfStateBlowQ.at( pStruct->StateEffectIndex ); ApplyStateEffectSignalProcess(StateBlowInfo, pStruct); } else { OutputDebug( "[Error!!]CDnActor::OnSignal, case STE_ApplyStateEffect: ½ºÅ³¿¡ µé¾îÀÖ´Â »óÅÂÈ¿°ú °¹¼ö(%d)¸¦ ¹þ¾î³­ Àû¿ë »óÅÂÈ¿°ú À妽º(%d)ÀÓ.\n", (int)m_dqApplySelfStateBlowQ.size(), pStruct->StateEffectIndex ); _ASSERT( !"case STE_ApplyStateEffect: ½ºÅ³¿¡ µé¾îÀÖ´Â »óÅÂÈ¿°ú °¹¼ö¸¦ ¹þ¾î³­ Àû¿ë »óÅÂÈ¿°ú À妽ºÀÓ" ); } } } break; case STE_Parring: { ParringStruct* pStruct = (ParringStruct*)pPtr; DNVector(DnBlowHandle) vlhParryBlows; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_031, vlhParryBlows ); int iNumParryBlow = (int)vlhParryBlows.size(); for( int i = 0; i < iNumParryBlow; ++i ) { DnBlowHandle hParryBlow = vlhParryBlows.at( i ); if( !hParryBlow ) continue; const CDnSkill::SkillInfo* pParentSkillInfo = hParryBlow->GetParentSkillInfo(); if( pParentSkillInfo && pStruct->nSkillID == pParentSkillInfo->iSkillID ) { CDnParryBlow* pParryBlow = static_cast(hParryBlow.GetPointer()); if( false == pParryBlow->IsEnabled() ) { pParryBlow->EnableParrying( pStruct->fProb ); pParryBlow->SetParringActionName( pStruct->szParringActionName ); } } } } break; case STE_CooltimeParring: { CooltimeParringStruct* pStruct = (CooltimeParringStruct*)pPtr; DNVector(DnBlowHandle) vlhParryBlows; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_153, vlhParryBlows ); int iNumParryBlow = (int)vlhParryBlows.size(); for( int i = 0; i < iNumParryBlow; ++i ) { DnBlowHandle hParryBlow = vlhParryBlows.at( i ); if( !hParryBlow ) continue; const CDnSkill::SkillInfo* pParentSkillInfo = hParryBlow->GetParentSkillInfo(); if( pParentSkillInfo && pStruct->nSkillID == pParentSkillInfo->iSkillID ) { CDnCooltimeParryBlow* pParryBlow = static_cast(hParryBlow.GetPointer()); if( false == pParryBlow->IsEnabled() ) { pParryBlow->EnableParrying( pStruct->fProb ); pParryBlow->SetParringActionName( pStruct->szParringActionName ); } } } } break; case STE_Gravity: { GravityStruct *pStruct = (GravityStruct *)pPtr; MatrixEx CrossOffset = m_Cross; CrossOffset.MoveLocalXAxis( pStruct->vOffset->x ); CrossOffset.MoveLocalYAxis( pStruct->vOffset->y ); CrossOffset.MoveLocalZAxis( pStruct->vOffset->z ); DNVector(DnActorHandle) hVecList; CDnActor::ScanActor( GetRoom(), CrossOffset.m_vPosition, pStruct->fDistanceMax, hVecList ); #ifdef PRE_ADD_GRAVITY_PROPERTY EtVector3 vPos = CrossOffset.m_vPosition; float fXZDistanceMaxSQ = pStruct->fDistanceMax; float fXZDistanceMinSQ = pStruct->fDistanceMin; fXZDistanceMaxSQ *= fXZDistanceMaxSQ; fXZDistanceMinSQ *= fXZDistanceMinSQ; SAABox Box; float fDot = 0.0f; EtVector3 vZVec = m_Cross.m_vZAxis; if( pStruct->fCenterAngle != 0.f ) { EtMatrix matRotate; EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) ); EtVec3TransformNormal( &vZVec, &vZVec, &matRotate ); } #endif // PRE_ADD_GRAVITY_PROPERTY for( DWORD i=0; iIsDie() ) continue; if( hVecList[i]->GetWeight() == 0.f ) continue; if( hVecList[i]->IsNpcActor() ) continue; if( hVecList[i]->ProcessIgnoreGravitySignal() ) continue; bool bHittable = false; switch( pStruct->nTargetType ) { case 0: // Enemy if( hVecList[i]->GetTeam() == GetTeam() ) break; bHittable = true; break; case 1: // Friend if( hVecList[i]->GetTeam() != GetTeam() ) break; bHittable = true; break; case 2: // All bHittable = true; break; } if( !bHittable ) continue; bHittable = true; switch( pStruct->nApplyTargetState ) { case 0: // Normal if( hVecList[i]->GetState() == CDnActorState::Down ) break; bHittable = true; break; case 1: // Down if( !( hVecList[i]->GetState() & CDnActorState::Down ) ) break; bHittable = true; break; case 2: // Normal + Down bHittable = true; break; } if( !bHittable ) continue; #ifdef PRE_ADD_GRAVITY_PROPERTY bool bCheckArea = true; DnActorHandle hActor = hVecList[i]; EtVector3 vDirActorToPos; vDirActorToPos = *hActor->GetPosition() - vPos; vDirActorToPos.y = 0.f; hActor->GetBoundingBox( Box ); float fSQDistance = SquaredDistance( vPos, Box ); if( fSQDistance > fXZDistanceMaxSQ ) bCheckArea = false; if( fSQDistance <= fXZDistanceMinSQ ) bCheckArea = false; if( pStruct->fAngle != 0.0f ) { EtVec3Normalize( &vDirActorToPos, &vDirActorToPos ); fDot = EtVec3Dot( &vZVec, &vDirActorToPos ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) bCheckArea = false; } if( pStruct->fHeightMax == 0.0f ) pStruct->fHeightMax = 3000.0f; if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) bCheckArea = false; if( Box.Min.y > vPos.y + pStruct->fHeightMax && Box.Max.y > vPos.y + pStruct->fHeightMax ) bCheckArea = false; if( !bCheckArea ) { hActor->SetVelocityZ( 0.0f ); hActor->SetResistanceZ( 0.0f ); hActor->ResetLook(); continue; } #endif // PRE_ADD_GRAVITY_PROPERTY MAMovementBase *pMovement = hVecList[i]->GetMovement(); if( !pMovement ) continue; EtVector3 vDir = *hVecList[i]->GetPosition() - CrossOffset.m_vPosition; float fDistance = EtVec3Length( &vDir ); float fDistance2 = EtVec3Length( &EtVector3( vDir.x, 0.f, vDir.z ) ); EtVec3Normalize( &vDir, &vDir ); #ifdef PRE_ADD_GRAVITY_PROPERTY float fDistanceMaxToMin = pStruct->fDistanceMax - pStruct->fDistanceMin; float fTemp = 0.0f; if( fDistanceMaxToMin > 0.0f ) fTemp = pStruct->fMinVelocity + ( ( (pStruct->fMaxVelocity - pStruct->fMinVelocity) / fDistanceMaxToMin ) * ( fDistanceMaxToMin - fDistance ) ); float fHeight = CrossOffset.m_vPosition.y - hVecList[i]->GetPosition()->y; float fHeightMaxToMin = pStruct->fHeightMax - pStruct->fHeightMin; float fTempVertical = 0.0f; if( fHeightMaxToMin > 0.0f ) fTempVertical = pStruct->fMinVelocity_Vertical + ( ( (pStruct->fMaxVelocity_Vertical - pStruct->fMinVelocity_Vertical) / fHeightMaxToMin ) * ( fHeightMaxToMin - fHeight ) ); #else // PRE_ADD_GRAVITY_PROPERTY float fTemp = pStruct->fMinVelocity + ( ( (pStruct->fMaxVelocity - pStruct->fMinVelocity) / pStruct->fDistanceMax ) * ( pStruct->fDistanceMax - fDistance ) ); #endif // PRE_ADD_GRAVITY_PROPERTY EtVector3 vVel; if( pMovement ) { EtVector3 vCurLook = *pMovement->GetLookDir(); pMovement->Look( EtVec3toVec2(vDir), true ); pMovement->SetVelocityZ( -fTemp ); pMovement->SetResistanceZ( fTemp * 2.f ); #ifdef PRE_ADD_GRAVITY_PROPERTY if( fTempVertical > 0.0f ) { pMovement->SetVelocityY( fTempVertical ); pMovement->SetResistanceY( fTempVertical * 2.f ); pMovement->SetAppliedYDistance( true ); hVecList[i]->SetGravityEnd( 0.2f + ( float(SignalEndTime - SignalStartTime) / 1000.0f ) ); } #endif // PRE_ADD_GRAVITY_PROPERTY pMovement->Look( EtVec3toVec2(vCurLook), true ); } } } break; case STE_MoveY: { if( m_pMovement ) { MoveYStruct* pStruct = (MoveYStruct*)pPtr; float fYDelta = pStruct->fVelocityY * ((float(SignalEndTime - SignalStartTime) / 1000.0f)); float fWholeMoveYDistance = (0.0f < fYDelta) ? fYDelta : -fYDelta; m_pMovement->SetMoveYDistancePerSec( pStruct->fVelocityY, fWholeMoveYDistance, (pStruct->bMaintainYPos == TRUE) ? true : false ); } } break; // Signal Rotate. case STE_Rotate: { RotateStruct * pStruct = static_cast< RotateStruct * >( pPtr ); float fLength = (float)( SignalEndTime - SignalStartTime ) * (CDnActionBase::m_fFPS / 60.0f); DWORD dwTime = (DWORD)( fLength - 16.6666f ); SetRotate( dwTime, pStruct->fStartSpeed, pStruct->fEndSpeed, *(pStruct->vAxis), pStruct->bLeft == TRUE ? true : false ); } break; } } LOCAL_TIME CDnActor::CheckRemainFrameTime() { float fCurFrame = GetCurFrame(); int nCurActionIndex = GetCurrentActionIndex(); ActionElementStruct *pStruct = GetElement(nCurActionIndex); LOCAL_TIME remainTime = 0; if (pStruct) remainTime = pStruct->dwLength - (LOCAL_TIME)fCurFrame; return remainTime; } bool CDnActor::SetActionQueue( const char *szActionName, int nLoopCount, float fBlendFrame, float fStartFrame, bool bCheck, bool bCheckStateEffect ) { if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_224 ) ) { DNVector(DnBlowHandle) vlhDisableActionSetBlow; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_224, vlhDisableActionSetBlow ); // ¾×¼Ç ¼Â º¯°æ »óÅÂÈ¿°ú´Â ¿©·¯°³ ÀÖÀ» ¼ö ÀÖ´Ù. int iNumBlow = (int)vlhDisableActionSetBlow.size(); for( int i = 0; i < iNumBlow; ++i ) { CDnDisableActionBlow* pDisableActionSetBlow = static_cast( vlhDisableActionSetBlow.at( i ).GetPointer() ); if(pDisableActionSetBlow->IsMatchedAction(szActionName)) return false; } } const char *szName = szActionName; if( bCheck ) { if( m_szActionQueue.empty() ) { if( strcmp( szName, m_szAction.c_str() ) == NULL ) { LOCAL_TIME remainTime = CheckRemainFrameTime(); //ÇöÀç µ¿ÀÛÀÌ °ÅÀÇ ³¡±îÁö °¬´Ù¸é µ¿ÀÛ ³¡³µ´Ù°í º¸°í ´ÙÀ½ µ¿ÀÛ ¿¹¾àÇÑ´Ù.. if (remainTime >= 20) return false; } } else { if( strcmp( szName, m_szActionQueue.c_str() ) == NULL ) { LOCAL_TIME remainTime = CheckRemainFrameTime(); //ÇöÀç µ¿ÀÛÀÌ °ÅÀÇ ³¡±îÁö °¬´Ù¸é µ¿ÀÛ ³¡³µ´Ù°í º¸°í ´ÙÀ½ µ¿ÀÛ ¿¹¾àÇÑ´Ù.. if (remainTime >= 20) return false; } } } int nCurrentActionIndex = GetElementIndex( szName ); if( bCheckStateEffect && nCurrentActionIndex > -1 ) { int nActionState = GetState( nCurrentActionIndex ); // State¿¡ µû¶ó ¼¼ºÎÀûÀ¸·Î ³ª´¶´Ù~ // °ø°ÝºÒ°¡ÀÏ ¶© °ø°Ý state ÀÎ ¾×¼ÇÀº »ç¿ë ¸øÇÔ. if( (nActionState & ActorStateEnum::Attack) && !( nActionState & ActorStateEnum::IgnoreCantAction) ) { if( (GetStateEffect() & CDnActorState::Cant_AttackAction) == CDnActorState::Cant_AttackAction ) { if( !IsDie() || IsGMTrace() ) return false; } } } CDnActionBase::SetActionQueue( szName, nLoopCount, fBlendFrame, fStartFrame ); if( nCurrentActionIndex != -1 ) { for( int i=(int)m_VecPreActionState[nCurrentActionIndex].size()-1; i>=0; i-- ) { if( (int)fStartFrame >= m_VecPreActionState[nCurrentActionIndex][i].nOffset ) { SetState( (CDnActorState::ActorStateEnum)m_VecPreActionState[nCurrentActionIndex][i].nState ); break; } } for( int i=(int)m_VecPreActionCustomState[nCurrentActionIndex].size()-1; i>=0; i-- ) { if( (int)fStartFrame >= m_VecPreActionCustomState[nCurrentActionIndex][i].nOffset ) { SetCustomState( (CDnActorState::ActorCustomStateEnum)m_VecPreActionCustomState[nCurrentActionIndex][i].nState ); break; } } for( int i=(int)m_VecPreCanMoveState[nCurrentActionIndex].size()-1; i>=0; i-- ) { if( (int)fStartFrame >= m_VecPreCanMoveState[nCurrentActionIndex][i].nOffset ) { SetMovable( ( m_VecPreCanMoveState[nCurrentActionIndex][i].nState == TRUE ) ? true : false ); break; } } } return true; } void CDnActor::SetCustomAction( const char *szActionName, float fFrame ) { if( m_hToggleSkill && m_hToggleSkill->IsToggleOn() ) { CDnChangeActionStrProcessor* pChangeAction = static_cast( m_hToggleSkill->GetProcessor( IDnSkillProcessor::CHANGE_ACTIONSTR ) ); if( pChangeAction ) { pChangeAction->GetChangeActionName( szActionName ); } } CDnActionBase::SetCustomAction( szActionName, fFrame ); } void CDnActor::ProcessDown( LOCAL_TIME LocalTime, float fDelta ) { if( IsDie() ) return; if( GetState() == CDnActorState::Down && m_fDownDelta > 0.f ) { m_fDownDelta -= ( fDelta * ( ( 1.f / 60.f ) * CDnActionBase::GetFPS() ) ); if( m_fDownDelta <= 0.f ) { m_fDownDelta = 0.f; m_fLastDownRatio = 1.f; SetActionQueue( "Down_StandUp", 0, 0.f, 0.f, true, false ); } } } void CDnActor::ProcessStiff( LOCAL_TIME LocalTime, float fDelta ) { if( IsDie() ) return; if( IsStiff() ) { if( m_fStiffDelta == 0.f ) return; m_fStiffDelta -= ( fDelta * ( ( 1.f / 60.f ) * CDnActionBase::GetFPS() ) ); if( m_fStiffDelta <= 0.f ) { m_fStiffDelta = 0.f; ActionElementStruct *pStruct = GetElement( m_szAction.c_str() ); if( pStruct ) SetActionQueue( pStruct->szNextActionName.c_str(), 0, 3.f ); else SetActionQueue( "Stand", 0, 3.f ); } } else m_fStiffDelta = 0.f; } void CDnActor::ProcessDie( LOCAL_TIME LocalTime, float fDelta ) { if( !IsDie() ) return; m_fDieDelta -= fDelta; if( m_fDieDelta <= 0.f ) { SetDestroy(); return; } } void CDnActor::RequestKillAfterProcessStateBlow(DnActorHandle hHitter) { m_bCompleteKill_AfterProcessStateBlow = true; m_hCompleteKillActor = hHitter; } void CDnActor::ExecuteKillAfterProcessStateBlow() { if(m_bCompleteKill_AfterProcessStateBlow) { SetHP( 0 ); RequestHPMPDelta( CDnState::ElementEnum_Amount, -( GetMaxHP() *2 ), GetUniqueID() ); m_bCompleteKill_AfterProcessStateBlow = false; //ÃÖÁ¾ DieÈ£Ãâ Die(m_hCompleteKillActor); m_hCompleteKillActor.Identity(); } } void CDnActor::CmdRefreshHPSP( INT64 nHP, int nSP ) { SetHP( min( nHP, GetMaxHP() ) ); SetSP( min( nSP, GetMaxSP() ) ); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &m_nHP, sizeof(INT64) ); Stream.Write( &m_nSP, sizeof(int) ); //printf("[RLKT_DEBUG][%s] CurHP: %lld FuncRecvCurHP: %lld SP: %d\n", __FUNCTION__, m_nHP, nHP , m_nSP); Send( eActor::SC_REFRESHHPSP, &Stream ); } void CDnActor::CmdAction( const char *szActionName, int nLoopCount, float fBlendFrame, bool bCheckOverlapAction, bool bFromStateBlow/* = false*/, bool bSkillChain/* = false*/ ) { SetActionQueue( szActionName, nLoopCount, fBlendFrame, 0.f, bCheckOverlapAction ); // Note: ¶óÀÌ¡ ½½·¡½Ã ó·³ ÀԷ¿¡ µû¶ó ¿©·¯ ¾×¼ÇÀÌ ³ª´µ¾î ³ª°¡´Â °æ¿ì ½ºÅ³ÀÇ // »óÅÂÈ¿°ú°¡ Áö¼ÓµÇ¾î¾ß ÇϹǷΠ½ºÅ³ ÂÊ¿¡ ¾Ë·ÁÁÖµµ·Ï ÇÑ´Ù. // ¼­¹ö·Î´Â CmdActon ÀÌ È£ÃâµÉ ¶§ ÆÐŶ¿¡ °°ÀÌ ³¯¾Æ°¨. if( bSkillChain ) { if( m_hProcessSkill ) m_hProcessSkill->OnChainInput( szActionName ); } } int CDnActor::CmdAddStateEffect( const CDnSkill::SkillInfo* pParentSkillInfo, STATE_BLOW::emBLOW_INDEX emBlowIndex, int nDurationTime, const char *szParam, bool bOnPlayerInit/* = false*/, bool bCheckCanBegin/* = true*/ , bool bEternity /*= false*/ ) { if( emBlowIndex < STATE_BLOW::BLOW_NONE || emBlowIndex >= STATE_BLOW::BLOW_MAX ) { if( pParentSkillInfo ) g_Log.Log(LogType::_ERROR, L"[CDnActor::CmdAddStateEffect] SkillID:%d, STATE_BLOW:%d\r\n", pParentSkillInfo->iSkillID, emBlowIndex ); else g_Log.Log(LogType::_ERROR, L"[CDnActor::CmdAddStateEffect] STATE_BLOW:%d\r\n", emBlowIndex); return -1; } // [2011/03/18 semozz] // »óÅÂÈ¿°ú °­Á¦ BeginÀ» À§ÇØ ÄÚµå ¼öÁ¤ int nBlowID = AddStateBlow( emBlowIndex, pParentSkillInfo, nDurationTime, szParam, bOnPlayerInit, bCheckCanBegin , bEternity ); DnBlowHandle hBlow = GetStateBlowFromID(nBlowID); if (pParentSkillInfo && pParentSkillInfo->bItemPrefixSkill) ForceBeginStateBlow(hBlow); return nBlowID; } void CDnActor::CmdModifyStateEffect( int iBlowID, STATE_BLOW& StateBlowInfo ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlowFromID( iBlowID ); if( hBlow ) { char acBuffer[ 32 ]; CPacketCompressStream Stream( acBuffer, sizeof(acBuffer) ); Stream.Write( &iBlowID, sizeof(int) ); Stream.Write( &StateBlowInfo.fDurationTime, sizeof(float) ); Send( eActor::SC_CMDMODIFYSTATEEFFECT, &Stream ); } } DnBlowHandle CDnActor::GetStateBlowFromID( int nStateBlowID ) { return m_pStateBlow->GetStateBlowFromID( nStateBlowID ); } void CDnActor::CmdRemoveStateEffect( STATE_BLOW::emBLOW_INDEX emBlowIndex, bool bRemoveFromServerToo/* = true*/ ) { DelStateBlow( emBlowIndex ); } void CDnActor::CmdRemoveStateEffectImmediately( STATE_BLOW::emBLOW_INDEX emBlowIndex ) { if( !m_pStateBlow ) return; m_pStateBlow->RemoveImediatlyStateEffectByBlowIndex( emBlowIndex ); } void CDnActor::CmdRemoveStateEffectFromID( int nID ) { #ifdef PRE_FIX_REMOVE_STATE_EFFECT_PACKET // ¿©±â´Ù ³Ö°ÔµÇ¸é ÆÛÆ÷¸Õ½º ºÎÇϰ¡ ÀÖÀ»°Í °°±â¶§¹®¿¡ ÀÏ´ÜÀº ³ÖÁö¾Ê½À´Ï´Ù. // ¿Ø¸¸ÇѰæ¿ì¿¡¼­´Â ºí·Î¿ì ¾ÆÀ̵𸦠ãÀºÀÌÈÄ¿¡ ³Ö¾îÁֱ⶧¹®¿¡ ±»ÀÌ °Ë»çÇÒ ÇÊ¿ä´Â ¾ø¾îº¸ÀÔ´Ï´Ù. // if( m_pStateBlow->IsExistStateBlowFromBlowID( nID ) == false ) // return; #endif m_pStateBlow->RemoveStateBlowFromID( nID ); SendRemoveStateEffectFromID(nID); } void CDnActor::ClearTriggerBuff() { for( int itr = 0; itr < (int)m_vTriggerBuff.size(); ++itr ) CmdRemoveStateEffectFromID( m_vTriggerBuff[itr] ); m_vTriggerBuff.clear(); } void CDnActor::CmdWarp() { CmdWarp( *GetPosition(), EtVec3toVec2( *GetLookDir() ) ); } void CDnActor::CmdWarp( EtVector3 &vPos, EtVector2 &vLook, CDNUserSession* pGameSession/*=NULL*/, bool bCheckPlayerFollowSummonedMonster/*=false*/ ) { SetPosition( vPos ); SetPrevPosition( vPos ); Look( vLook, true ); if( abs( CDnWorld::GetInstance(GetRoom()).GetHeight( vPos ) - vPos.y ) > 5.f ) { SetVelocityY( -3.0f ); SetResistanceY( -18.0f ); } BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); // pGameSession ÀÌ ÀÖ´Â °æ¿ì´Â ÇØ´ç ¼¼¼Ç¿¡°Ô¸¸ ÆÐŶ º¸³½´Ù. if( pGameSession ) Send( pGameSession, eActor::SC_CMDWARP, GetUniqueID(), &Stream ); else Send( eActor::SC_CMDWARP, &Stream ); } bool CDnActor::CheckDamageAction( DnActorHandle hActor ) { MAMovementBase *pMovement = GetMovement(); // ¸ð¾ç¼¼ ¼ÂÆÃ if( ( IsAir() ) || ( IsHit() && IsDown() && !IsStun() ) || GetState() == ActorStateEnum::Down ) { if( IsStandHit( m_HitParam.szActionName.c_str() ) ) { m_HitParam.szActionName = "Hit_AirBounce"; m_HitParam.vVelocity.y = pMovement->GetLastVelocity()->y * 0.8f; m_HitParam.vResistance.y = pMovement->GetResistance()->y; if( m_HitParam.vVelocity.y > 0.f && m_HitParam.vResistance.y >= 0.f ) { m_HitParam.vResistance.y = -18.f; } } } return true; } void CDnActor::CheckDamageVelocity( DnActorHandle hActor ) { MAMovementBase *pMovement = GetMovement(); // ¹Ù¶óº¸±â ¼ÂÆÃ EtVector2 vViewVec = EtVec3toVec2( m_HitParam.vViewVec ); EtVec2Normalize( &vViewVec, &vViewVec ); if( EtVec2LengthSq( &vViewVec ) > 0.f ) { pMovement->Look( vViewVec ); } // ¸¸¾à¿¡ ÀüÇô ¶ì¿öÁ®ÀÖ´Â »óŰ¡ ¾Æ´Ô¿¡µÎ Air ÀÎ Hit ¸ð¼ÇÀÌ µé¾î¿ÔÀ» °æ¿ì¸¦ ´ëºñÇØ¼­ ¿©±â¼­ ÀÓÀÇÀÇ ¼öÄ¡·Î ¶ç¾îÁÖ±â·Î ÇÏÀÚ // (ex. Àü»çÀÇ ´©¿öÀִ³𠶧¸®±âÀÇ °æ¿ì ½ºÅÏÀ¸·Î ¸ÂÀ»°æ¿ì ¶°¾ßÇϴµ¥ y°ªÀ¸·Î °¡¼Óµµ¸¦ ÁÖÁö ¾Ê±â ¶§¹®¿¡ ¶°Àִ»óÅ·Π¿¡´Ï°¡ À¯ÁöµÇ´Â °æ¿ì°¡ ÀÖ´Ù. ) ActorStateEnum HitState = (ActorStateEnum)GetState( m_HitParam.szActionName.c_str() ); if( ( HitState & ActorStateEnum::Air ) && m_HitParam.vVelocity.y == 0.f ) { m_HitParam.vVelocity.y = 3.f; m_HitParam.vResistance.y = -18.f; } if( m_HitParam.vVelocity.y == 0.f && pMovement->GetVelocity() && pMovement->GetVelocity()->y != 0.f && ( GetAddHeight() != 0.f ) || ( m_HitParam.szActionName.empty() && ( GetState() & ActorStateEnum::Air ) ) ) { m_HitParam.vVelocity.y = pMovement->GetVelocity()->y; m_HitParam.vResistance.y = pMovement->GetResistance()->y; } // Weight °¡ 0ÀÌ¸é ¾È¶ß´Â³ðÀÌ´Ù. ±×·¯³ª ½Ã±×³ÎÁß¿¡ Air »óÅ·ΠµÇÀְԵǸé À§ÀÇ ¿¹¿Ü󸮷çƾÀ» ¹«½ÃÇϰԵDZⶫ¿¡ // ¹Ù´Ú¿¡¼­ Air ·Î À¯ÁöµÇ´Â ³ðµéÀÌ »ý±æ¼ö°¡ ÀÖÀ¸´Ï 0ÀγðÀº »óŰ¡ Àý´ë Air ·Î µÇ¸é ¾ÈµÈ´Ù. if( GetWeight() == 0.f ) { // ¿Üµý¼¶(301) µ¢Äð Æ®·¦Ã³·³ ¹«°Ô°ª 0.0 À¸·Î ¹Ù²Ù´Â °æ¿ì ´ëÆ÷°°Àº °Å ¸Â¾Æ¼­ // °øÁß¿¡ ¶ß´Â ³Ë¹é ¾×¼ÇÀÌ ³ª¿Ã °æ¿ì ¶¥¿¡ ÂøÁöÇÏÁö ¸øÇÏ´Â ¹ö±×°¡ »ý±æ ¼ö ÀÖÀ¸¹Ç·Î ¼öÁ¤. (#12253) if( IsAir( m_HitParam.szActionName.c_str() ) ) m_HitParam.szActionName.assign( GetCurrentAction() ); m_HitParam.vVelocity = EtVector3( 0.f, 0.f, 0.f ); m_HitParam.vResistance = EtVector3( 0.f, 0.f, 0.f ); } pMovement->SetVelocity( m_HitParam.vVelocity ); pMovement->SetResistance( m_HitParam.vResistance ); } int GetGaussianRandom( int nMin, int nMax, CMultiRoom *pRoom ) { float f1 = ( _rand(pRoom) % 10001 ) / 10000.f; float f2 = ( _rand(pRoom) % 10001 ) / 10000.f; int nResult = (int)( ((nMin+nMax)/2.f) + ( ( sqrt(-2.f*log(f1)) * cos(2.f*3.1415926f*f2) ) * ((nMax-nMin)/6.f) ) ); if( nResult < nMin || nResult > nMax ) nResult = (nMin + nMax) / 2; return nResult; }; float GetGaussianRandom( float fMin, float fMax, CMultiRoom *pRoom, float fPrecision = 0.01f ) { float f1 = ( _rand(pRoom) % 10001 ) / 10000.f; float f2 = ( _rand(pRoom) % 10001 ) / 10000.f; float fResult = ((fMin+fMax)/2.f) + ( ( sqrt(-2.f*log(f1)) * cos(2.f*3.1415926f*f2) ) * ((fMax-fMin)/6.f) ); if( fResult < fMin || fResult > fMax ) fResult = (fMin + fMax) / 2; return fResult; }; CDnState::ElementEnum CDnActor::CalcHitElementType( bool bUseSkillApplyWeaponElement, CDnState::ElementEnum eSkillElement, bool bUsingSkill ) { // #33312 ƯÁ¤ »óȲ¿¡¼­ °­Á¦·Î ¼ÂÆÃÇÑ ¼Ó¼ºÀÌ ÀÖ´Ù¸é ÇØ´ç ¼Ó¼ºÀ¸·Î ó¸®. if( false == m_vlForceSettedHitElement.empty() ) return static_cast(m_vlForceSettedHitElement.back()); bool bProcessSkill = (m_hProcessSkill ? true : false); ElementEnum eProcessSkillElement = CDnState::ElementEnum_Amount; if( m_hProcessSkill ) eProcessSkillElement = m_hProcessSkill->GetElement(); // ¿ÜºÎ¿¡¼­ ½ºÅ³ »ç¿ë Á¤º¸¸¦ °®°í È£ÃâÇØÁÙ ¶§(½ºÅ³·Î ³ª°£ ÇÁ·ÎÁ§Å¸ÀÏ) if( bUsingSkill ) { bProcessSkill = bUsingSkill; eProcessSkillElement = eSkillElement; } ElementEnum Type = CDnState::ElementEnum_Amount; if( bProcessSkill ) { if( eProcessSkillElement == CDnState::ElementEnum_Amount ) { if( bUseSkillApplyWeaponElement ) { if( IsPlayerActor() ) { Type = ( CDnActor::GetWeapon() ) ? CDnActor::GetWeapon()->GetElementType() : CDnState::ElementEnum_Amount; } else if( IsMonsterActor() ) { Type = static_cast(this)->GetElementType(); } } } else { Type = eProcessSkillElement; } } else { if( m_ActorType <= ActorTypeEnum::Reserved6 ) Type = ( CDnActor::GetWeapon() ) ? CDnActor::GetWeapon()->GetElementType() : CDnState::ElementEnum_Amount; else Type = static_cast(this)->GetElementType(); } return Type; } // »óÅÂÈ¿°ú¿¡ °ü·ÃµÈ ºÎºÐÀº #pragma region À¸·Î Á¢Èû °¡´ÉÇÏ°Ô ¼³Á¤ÇÕ´Ï´Ù // Visual Studio ¿É¼Ç¿¡¼­ ÆùÆ®¿É¼Ç¿¡ "Ãà¼Ò °¡´É ÅýºÆ®" ºÎºÐ¿¡ »öÁöÁ¤À» ÇØµÎ½Ã¸é °¡µ¶¼ºÀÌ ³ô¾ÆÁý´Ï´Ù. float CDnActor::PreCalcDamage( CDnDamageBase *pHitter, SHitParam &HitParam, const float fDefenseRate/*=1.f*/, float fStateEffectAttackM /*= -1.0f */ ) { float fResult = 0.f; float fHitPer = HitParam.fDamage; float fAttackPower = 0.0f; int nDefense = 0; float fDefenseWeight = 0.0f; float fElementWeight = 1.f; float fGausianResultProb = 1.f; DnActorHandle hHitter = pHitter->GetActorHandle(); CDnState *pState = NULL; CDnStateBlow *pHitterStateBlow = hHitter->GetStateBlow(); bool bCalcDamageFromStateEffect = ( fStateEffectAttackM != -1.0f ); if( bCalcDamageFromStateEffect == true ) { if( hHitter ) pState = static_cast(hHitter.GetPointer()); fAttackPower = fStateEffectAttackM; nDefense = GetDefenseM(); } else { if( hHitter && !HitParam.bFromProjectile ) { pState = static_cast(hHitter.GetPointer()); } else { if( HitParam.hWeapon ) { CDnProjectile *pHitterProjectile = static_cast( HitParam.hWeapon.GetPointer() ); if( pHitterProjectile ) { pState = pHitterProjectile->GetShooterStateSnapshot().get(); #if defined(PRE_ADD_PROJECTILE_SE_INFO) CDnStateBlow *pProjectileStateBlow = static_cast( HitParam.hWeapon.GetPointer() )->GetShooterStateBlow().get(); if( pProjectileStateBlow ) pHitterStateBlow = pProjectileStateBlow; #endif } } #if !defined(PRE_ADD_PROJECTILE_SE_INFO) if (hHitter&& hHitter->IsApplyPrefixOffenceSkill()) pState = static_cast(hHitter.GetPointer()); #endif if( hHitter && pState == NULL ) pState = static_cast(hHitter.GetPointer()); } } if( bCalcDamageFromStateEffect == false ) { int nAttack[2] = { 0, }; switch( HitParam.cAttackType ) { case 0: // ¹°¸® { nAttack[0] = pState->GetAttackPMin(); nAttack[1] = pState->GetAttackPMax(); #pragma region ++ [ ADD DAMAGE BY SELF ( BLOW_109 ) ] ++ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_109 ) ) { int aiAdditionalPAttack[ 2 ] = { 0 }; DNVector(DnBlowHandle) vlhBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_109, vlhBlows ); int iNumBlow = (int)vlhBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { aiAdditionalPAttack[ 0 ] += int((float)GetAttackPMin() * vlhBlows.at(i)->GetFloatValue()); aiAdditionalPAttack[ 1 ] += int((float)GetAttackPMax() * vlhBlows.at(i)->GetFloatValue()); } nAttack[ 0 ] += aiAdditionalPAttack[ 0 ]; nAttack[ 1 ] += aiAdditionalPAttack[ 1 ]; } #pragma endregion nDefense = GetDefenseP(); } break; case 1: // ¸¶¹ý case 2: //rlkt_test { nAttack[0] = pState->GetAttackMMin(); nAttack[1] = pState->GetAttackMMax(); #pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_180 ) ] ++ if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_180) ) { CDnActorState* pActorState = static_cast(hHitter.GetPointer()); CDnState* pSkillState = pActorState ? pActorState->GetStateStep(1) : NULL; if (pSkillState) { nAttack[0] += pSkillState->GetAttackPMin(); nAttack[1] += pSkillState->GetAttackPMax(); } } #pragma endregion #pragma region ++ [ ADD DAMAGE BY SELF ( BLOW_110 ) ] ++ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_110 ) ) { int aiAdditionalMAttack[ 2 ] = { 0 }; DNVector(DnBlowHandle) vlhBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_110, vlhBlows ); int iNumBlow = (int)vlhBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { aiAdditionalMAttack[ 0 ] += int((float)GetAttackMMin() * vlhBlows.at(i)->GetFloatValue()); aiAdditionalMAttack[ 1 ] += int((float)GetAttackMMax() * vlhBlows.at(i)->GetFloatValue()); } nAttack[ 0 ] += aiAdditionalMAttack[ 0 ]; nAttack[ 1 ] += aiAdditionalMAttack[ 1 ]; } #pragma endregion nDefense = GetDefenseM(); } break; } #pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_213 ) ] ++ if( pHitterStateBlow && m_pStateBlow->IsApplied(STATE_BLOW::BLOW_213) ) { int nAddAttack[2] = { 0, }; int HitterAttackP[2] = {pState->GetAttackPMin(), pState->GetAttackPMax()}; DNVector(DnBlowHandle) vlhBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_213, vlhBlows ); int iNumBlow = (int)vlhBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { nAddAttack[ 0 ] += int((float)HitterAttackP[0] * vlhBlows.at(i)->GetFloatValue()); nAddAttack[ 1 ] += int((float)HitterAttackP[1] * vlhBlows.at(i)->GetFloatValue()); } nAttack[ 0 ] += nAddAttack[ 0 ]; nAttack[ 1 ] += nAddAttack[ 1 ]; } #pragma endregion #pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_214 ) ] ++ if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_214) ) { int nAddAttack[2] = { 0, }; int HitterAttackM[2] = {pState->GetAttackMMin(), pState->GetAttackMMax()}; DNVector(DnBlowHandle) vlhBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_214, vlhBlows ); int iNumBlow = (int)vlhBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { nAddAttack[ 0 ] += int((float)HitterAttackM[0] * vlhBlows.at(i)->GetFloatValue()); nAddAttack[ 1 ] += int((float)HitterAttackM[1] * vlhBlows.at(i)->GetFloatValue()); } nAttack[ 0 ] += nAddAttack[ 0 ]; nAttack[ 1 ] += nAddAttack[ 1 ]; } #pragma endregion #pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_221 ) ] ++ if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_221)) { int nAddAttack[2] = { 0, }; int HitterAttackValue[2] = {0, }; switch( HitParam.cAttackType ) { case 0: //¹°¸® °ø°ÝÀ϶§. HitterAttackValue[0] = pState->GetAttackPMin(); HitterAttackValue[1] = pState->GetAttackPMax(); break; case 1: //¸¶¹ý °ø°ÝÀ϶§. HitterAttackValue[0] = pState->GetAttackMMin(); HitterAttackValue[1] = pState->GetAttackMMax(); break; } DNVector(DnBlowHandle) vlhBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_221, vlhBlows ); int iNumBlow = (int)vlhBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { nAddAttack[ 0 ] += int((float)HitterAttackValue[0] * vlhBlows.at(i)->GetFloatValue()); nAddAttack[ 1 ] += int((float)HitterAttackValue[1] * vlhBlows.at(i)->GetFloatValue()); } nAttack[ 0 ] += nAddAttack[ 0 ]; nAttack[ 1 ] += nAddAttack[ 1 ]; } #pragma endregion float fFinalDamageValue[4] = { CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue1 ), CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue2 ), CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue3 ), CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue4 ), }; float fFValue = GetFinalDamageConstant(); float fFinalDamage1 = (float)( pState->GetFinalDamage() / fFValue ) * fFinalDamageValue[3]; float fFinalDamage2 = powf( (float)( pState->GetFinalDamage() / fFValue ), fFinalDamageValue[1] ) * fFinalDamageValue[2]; float fResultFinalDamage = min( max(fFinalDamage1, fFinalDamage2), fFinalDamageValue[2] ); // 184, 185¹ø °ø°ÝÀÚ ÆÄÀ̳Πµ¥¹ÌÁö ¹°°ø/¸¶°ø ±¸ºÐ Àû¿ë »óÅÂÈ¿°ú float fResultAdditionalFinalDamage = 0.0f; if( 0 == HitParam.cAttackType ) // ¹°¸® °ø°Ý { #pragma region ++ [ fResultAdditionalFinalDamage BY HITTER ( BLOW_184 ) ] ++ if( pHitterStateBlow && pHitterStateBlow->IsApplied( STATE_BLOW::BLOW_184 ) ) { DNVector(DnBlowHandle) vlhFinalPDamageBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_184, vlhFinalPDamageBlows ); int iNumBlow = (int)vlhFinalPDamageBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { DnBlowHandle hBlow = vlhFinalPDamageBlows.at( i ); fResultAdditionalFinalDamage += hBlow->GetFloatValue(); } } #pragma endregion } else if (1 == HitParam.cAttackType || 2 == HitParam.cAttackType) // ¸¶¹ý °ø°Ý// rlkt_test { #pragma region ++ [ fResultAdditionalFinalDamage BY HITTER ( BLOW_185 ) ] ++ if( pHitterStateBlow && pHitterStateBlow->IsApplied( STATE_BLOW::BLOW_185 ) ) { DNVector(DnBlowHandle) vlhFinalPDamageBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_185, vlhFinalPDamageBlows ); int iNumBlow = (int)vlhFinalPDamageBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { DnBlowHandle hBlow = vlhFinalPDamageBlows.at( i ); fResultAdditionalFinalDamage += hBlow->GetFloatValue(); } } #pragma endregion } float fGausianResult = (float)GetGaussianRandom( nAttack[0], nAttack[1], GetRoom() ); fGausianResultProb = fGausianResult / nAttack[1]; fAttackPower = fGausianResult * fHitPer; float fDamageRatioBlowValue = 0.f; #pragma region ++ [ fDamageRatioBlowValue BY HITTER ( BLOW_050 ) ] ++ if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_050)) { DNVector(DnBlowHandle) vlhDamageRatioBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_050, vlhDamageRatioBlows ); int iNumBlow = (int)vlhDamageRatioBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { DnBlowHandle hBlow = vlhDamageRatioBlows.at( i ); fDamageRatioBlowValue += hBlow->GetFloatValue(); } } #pragma endregion #if defined(PRE_FIX_65287) //¹ß»çü¿¡ ÀÇÇØ¼­ FinalDamageRate°ªÀÌ ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì´Â ÀÌ ¼³Á¤°ªÀ» »ç¿ë Çϵµ·Ï ÇÑ´Ù. //½ºÅ³ÀÌ ³¡³ª°í ³ª¸é 50¹ø »óÅÂÈ¿°ú°¡ »ç¶óÁø ´ÙÀ½À̶ó ÀÌ ¼³Á¤°ªÀ» »ç¿ë ÇØ¾ß ÇÔ. float fShooterFinalDamageRate = 0.0f; if (HitParam.bFromProjectile) { CDnProjectile* pProjectile = static_cast( HitParam.hWeapon.GetPointer() ); fShooterFinalDamageRate = pProjectile ? pProjectile->GetShooterFinalDamageRate() : 0.0f; if (fShooterFinalDamageRate != 0.0f) fDamageRatioBlowValue = fShooterFinalDamageRate; } #endif // PRE_FIX_65287 fAttackPower = fAttackPower * ( 1.f + fResultFinalDamage + fDamageRatioBlowValue + fResultAdditionalFinalDamage ); #pragma region ++ [ fAttackPower BY HITTER ( BLOW_074 ) ] ++ // 74¹ø »óÅÂÈ¿°ú. ¹«Á¶°Ç ÃÖ´ë µ¥¹ÌÁö·Î °è»êµÊ.. if( pHitterStateBlow && pHitterStateBlow->IsApplied( STATE_BLOW::BLOW_074 ) ) fAttackPower = (float)nAttack[1]; #pragma endregion #pragma region ++ [ fAttackPower BY HITTER ( BLOW_209 ) ] ++ // ½Å±Ô ij¸¯ÅÍ(¾ÆÄ«µ¥¹Í °ü·Ã) // ±âº» °ø°Ý·Â ºñÀ² Áõ°¡..(ÀϹݰø°ÝÀϰæ¿ì¸¸....) // ½ºÅ³À» »ç¿ëÁßÀÌÁö ¾Ê°í , ¹ß»çü°¡ ¾Æ´Ï°Å³ª , ¹ß»çü¶ó¸é ½ºÅ³»ç¿ë ¹ß»çü°¡ ¾Æ´Ò¶§ // ÀÏ´Ü ¾ÆÄ«µ¥¹Í Àΰæ¿ì¸¸ »ç¿ë°¡´É Çϵµ·Ï ¼³Á¤ÀÌ µÇ¾îÀÖ´Â »óÅÂÀÌ´Ù , ´Ù¸¥Å¬·¡½º¿¡ Àû¿ë ÇÒ ¶§´Â ¿¹¿Ü»óȲÀ» Á»´õ Å×½ºÆ® ÇØÁÖ¼¼¿ä // < Ex> ½ºÅĽº·ù Ȱ¼ºÈ­ µÇ¾îÀÖ´Â »óÅ¿¡¼­ ¿¹¿Ü »óȲ È®ÀÎÇßÀ¸³ª ó¸®ÇÏÁö ¾ÊÀº »óÅ > if (false == hHitter->IsProcessSkill() && (( HitParam.bFromProjectile && !HitParam.bFromProjectileSkill ) || !HitParam.bFromProjectile ) && !hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_121) && !hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_129) //ÇØÅ·½ºÅÙ½º·ù) ) { if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_209) ) { DNVector(DnBlowHandle) vlBlowList; float fAddtionalAttackPower = 0.f; pHitterStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_209, vlBlowList); for (int i=0 ; i< (int)vlBlowList.size(); ++i ) { if(vlBlowList[i]->GetFloatValue() > 0.f) { fAddtionalAttackPower = fAttackPower * vlBlowList[i]->GetFloatValue(); break; } } fAttackPower += fAddtionalAttackPower; } } #pragma endregion if( fAttackPower < 0.f ) fAttackPower = 0.f; } //rlkt_damage! CDnSkill::SkillInfo *pDmgSkillInfo = NULL; DnSkillHandle hDmgSkill; if (HitParam.bFromProjectile && HitParam.hWeapon) hDmgSkill = static_cast(HitParam.hWeapon.GetPointer())->GetParentSkill(); else hDmgSkill = hHitter->GetProcessSkill(); bool bIsPVP = GetGameRoom()->bIsPvPRoom(); if (hDmgSkill) { pDmgSkillInfo = const_cast(hDmgSkill->GetInfo()); if (bIsPVP) { CDNGameDataManager::TPVPSkills* nSkillInfo = NULL; nSkillInfo = g_pDataManager->GetPVPSkillPDamage(pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel); if (nSkillInfo) { printf("hDmgSkill PVP OK atak: %.2f skill:%d lvl:%d\n", fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel); fAttackPower = (float)(fAttackPower*(float)(nSkillInfo->fPDamage + 1.f));//test printf("hDmgSkill PVP AFTER OK multi:%.4f atak: %.2f skill:%d lvl:%d\n", nSkillInfo->fPDamage, fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel); } } else { printf("hDmgSkill OK atak: %.2f skill:%d lvl:%d\n", fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel); TSkillLevelData *pData = g_pDataManager->GetSkillLevelData(pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel); if (pData) { if (pData->nPhyDamage > 0.01f && fAttackPower > 0.001f) fAttackPower = fAttackPower + (float)(fAttackPower*(float)(pData->nPhyDamage + 1.f));//test } printf("hDmgSkill AFTER OK atak: %.2f skill:%d lvl:%d\n", fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel); } } #pragma region ++ [ nDefense BY SELF ( BLOW_101 ~ BLOW_108 ) ] ++ // [OBT] Ãß°¡ ½ºÅ³ È¿°ú ±¸Çö - ¹æ¾î·Â º¯°æ (#7839) /////////////////////////////////////// STATE_BLOW::emBLOW_INDEX AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_NONE; switch( HitParam.DistanceType ) { case CDnDamageBase::DistanceTypeEnum::Melee: { if( 0 == HitParam.cAttackType ) { // ¹°¸® ¹Ð¸® ¹æ¾î·Â Àý´ë º¯°æ : 101 if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_101 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_101; else // ¹°¸® ¹Ð¸® ¹æ¾î·Â ºñÀ² º¯°æ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_102 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_102; } else if( 1 == HitParam.cAttackType || 2 == HitParam.cAttackType) //rlkt_test { // ¸¶¹ý ¹Ð¸® ¹æ¾î·Â Àý´ë º¯°æ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_105 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_105; else // ¸¶¹ý ¹Ð¸® ¹æ¾î·Â ºñÀ² º¯°æ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_106 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_106; } } break; case CDnDamageBase::DistanceTypeEnum::Range: { if( 0 == HitParam.cAttackType ) { // ¹°¸® ·¹ÀÎÁö ¹æ¾î·Â Àý´ë º¯°æ : 101 if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_103 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_103; else // ¹°¸® ·¹ÀÎÁö ¹æ¾î·Â ºñÀ² º¯°æ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_104 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_104; } else if( 1 == HitParam.cAttackType || 2 == HitParam.cAttackType) //rlkt_test { // ¸¶¹ý ·¹ÀÎÁö ¹æ¾î·Â Àý´ë º¯°æ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_107 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_107; else // ¸¶¹ý ·¹ÀÎÁö ¹æ¾î·Â ºñÀ² º¯°æ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_108 ) ) AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_108; } } break; } if( STATE_BLOW::BLOW_NONE != AppliedDefenseChangeBlowIndex ) { switch( AppliedDefenseChangeBlowIndex ) { // Àý´ë°ª º¯°æ case STATE_BLOW::BLOW_101: case STATE_BLOW::BLOW_103: case STATE_BLOW::BLOW_105: case STATE_BLOW::BLOW_107: { DNVector(DnBlowHandle) vlhDefenseAbChangeBlow; GetStateBlow()->GetStateBlowFromBlowIndex( AppliedDefenseChangeBlowIndex, vlhDefenseAbChangeBlow ); int iNumBlow = (int)vlhDefenseAbChangeBlow.size(); for( int i = 0; i < iNumBlow; ++i ) { DnBlowHandle hBlow = vlhDefenseAbChangeBlow.at( i ); int iValue = (int)hBlow->GetFloatValue(); nDefense += iValue; } } break; // ºñÀ² º¯°æ case STATE_BLOW::BLOW_102: case STATE_BLOW::BLOW_104: case STATE_BLOW::BLOW_106: case STATE_BLOW::BLOW_108: { DNVector(DnBlowHandle) vlhDefenseRtChangeBlow; GetStateBlow()->GetStateBlowFromBlowIndex( AppliedDefenseChangeBlowIndex, vlhDefenseRtChangeBlow ); float fChangeRatio = 1.0f; // º¹¼ö°³°¡ ÀÖ´Â °æ¿ì¸¦ °¨¾ÈÇØ¼­ 100%¸¦ ³Ñ¾î°¡´Â ¼öÄ¡¸¸ ´©Àû½ÃÄÑÁØ´Ù. int iNumBlow = (int)vlhDefenseRtChangeBlow.size(); for( int i = 0; i < iNumBlow; ++i ) { DnBlowHandle hBlow = vlhDefenseRtChangeBlow.at( i ); fChangeRatio += (hBlow->GetFloatValue()-1.0f); } nDefense += int( (float)nDefense*fChangeRatio ); } break; } } #pragma endregion float fDefensePower = 1.f; #if defined(PRE_ADD_SKILLBUF_RENEW) //¸ðµç °ø°Ý·Â °è»ê¿¡´Â ¹æ¾î·ÂÀÌ Àû¿ë µÈ´Ù. fDefenseWeight = hHitter->GetDefenseConstant(); fDefensePower = nDefense / fDefenseWeight; if( fDefensePower < 0.f ) fDefensePower = 0.f; else if( fDefensePower > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax ) ) fDefensePower = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax ); fDefensePower = 1.f - fDefensePower; //Å©¸®Æ¼ÄÃÀÎ °æ¿ì AttackPower¸¦ ¼³Á¤µÈ »ó¼ö°ªÀ» Àû¿ë½ÃŲ´Ù. if (HitParam.HitType == CDnWeapon::Critical) { //#57510 PvP¿¡¼­ Å©¸®Æ¼Äà µ¥¹ÌÁö 1.5 float fCriticalIncValue = 1.0f; if( GetGameRoom()->bIsPvPRoom() == true ) fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease_PVP ); else fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease ); fAttackPower = fAttackPower * fCriticalIncValue; } #else // PRE_ADD_SKILLBUF_RENEW if( HitParam.HitType == CDnWeapon::Critical ) { fDefensePower = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease ); } else { fDefenseWeight = hHitter->GetDefenseConstant(); fDefensePower = nDefense / fDefenseWeight; if( fDefensePower < 0.f ) fDefensePower = 0.f; else if( fDefensePower > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax ) ) fDefensePower = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax ); fDefensePower = 1.f - fDefensePower; } #endif // PRE_ADD_SKILLBUF_RENEW fResult = fAttackPower * fDefensePower; #pragma region ++ [ fResult *= fChangeRatio BY SELF ( BLOW_134, BLOW_135 ) ] ++ // ¹°¸®/¸¶¹ý µ¥¹ÌÁö º¯°æ #12354, #12353 /////////////////////////////////////////// if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_134 ) && 0 == HitParam.cAttackType ) { DNVector( DnBlowHandle ) vlhBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_134, vlhBlows ); float fChangeRatio = 1.0f; // º¹¼ö°³°¡ ÀÖ´Â °æ¿ì¸¦ °¨¾ÈÇØ¼­ 100%¸¦ ³Ñ¾î°¡´Â ¼öÄ¡¸¸ ´©Àû½ÃÄÑÁØ´Ù. #ifdef PRE_ADD_BUFF_STATE_LIMIT float fBuffStateRatioValue = 1.f; #endif for( int i = 0; i < (int)vlhBlows.size(); ++i ) { DnBlowHandle hBlow = vlhBlows.at( i ); float fValue = hBlow->GetFloatValue(); fChangeRatio += (fValue-1.0f); #ifdef PRE_ADD_BUFF_STATE_LIMIT if( hBlow->GetAddBlowStateType() == CDnActorState::AddBlowStateType::Equip_Buff_Level ) fBuffStateRatioValue += (fValue-1.0f); #endif } #ifdef PRE_ADD_BUFF_STATE_LIMIT float fMinLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Physical_Min ); float fMaxLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Physical_Max ); if(IsPlayerActor()) { if( fChangeRatio < fMinLimit ) //#77817 À¯Àú°¡ ¹Þ´Â µ¥¹ÌÁö Àϰæ¿ì¿¡´Â ÃÑ µ¥¹ÌÁö °¨¼Ò·®À» ±âÁØÀ¸·Î ¼³Á¤. fChangeRatio = fMinLimit; } else if(IsMonsterActor()) { if( fBuffStateRatioValue > fMaxLimit ) fChangeRatio += -fBuffStateRatioValue + fMaxLimit; } #else float fDamageChangeClampLowestRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DamageChangeClampLowestRatio ); if( fChangeRatio < fDamageChangeClampLowestRatio ) fChangeRatio = fDamageChangeClampLowestRatio; #endif if(fChangeRatio < 0) fChangeRatio = 0.f; fResult *= fChangeRatio; } else if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_135 ) && 1 == HitParam.cAttackType || IsAppliedThisStateBlow(STATE_BLOW::BLOW_135) && 2 == HitParam.cAttackType) //rlkt_test { DNVector( DnBlowHandle ) vlhBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_135, vlhBlows ); float fChangeRatio = 1.f; #ifdef PRE_ADD_BUFF_STATE_LIMIT float fBuffStateRatioValue = 1.f; #endif for( int i = 0; i < (int)vlhBlows.size(); ++i ) { DnBlowHandle hBlow = vlhBlows.at( i ); float fValue = hBlow->GetFloatValue(); fChangeRatio += (fValue-1.0f); #ifdef PRE_ADD_BUFF_STATE_LIMIT if( hBlow->GetAddBlowStateType() == CDnActorState::AddBlowStateType::Equip_Buff_Level ) fBuffStateRatioValue += (fValue-1.0f); #endif } #ifdef PRE_ADD_BUFF_STATE_LIMIT float fMinLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Magical_Min ); float fMaxLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Magical_Max ); if(IsPlayerActor()) { if( fChangeRatio < fMinLimit ) //#77817 À¯Àú°¡ ¹Þ´Â µ¥¹ÌÁö Àϰæ¿ì¿¡´Â ÃÑ µ¥¹ÌÁö °¨¼Ò·®À» ±âÁØÀ¸·Î ¼³Á¤. fChangeRatio = fMinLimit; } else if(IsMonsterActor()) { if( fBuffStateRatioValue > fMaxLimit ) fChangeRatio += -fBuffStateRatioValue + fMaxLimit; } #else float fDamageChangeClampLowestRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DamageChangeClampLowestRatio ); if( fChangeRatio < fDamageChangeClampLowestRatio ) fChangeRatio = fDamageChangeClampLowestRatio; #endif if(fChangeRatio < 0) fChangeRatio = 0.f; fResult *= fChangeRatio; } #pragma endregion #pragma region ++ [ fResult += fResult * fChangeRatio BY SELF ( BLOW_268 ) ] ++ #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) if (IsAppliedThisStateBlow( STATE_BLOW::BLOW_268 )) { DNVector( DnBlowHandle ) vlhBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_268, vlhBlows ); float fChangeRatio = 0.0f; for( int i = 0; i < (int)vlhBlows.size(); ++i ) { DnBlowHandle hBlow = vlhBlows.at( i ); if (hBlow && hBlow->IsEnd() == false) { CDnDamageChagneBlow* pDamageChageBlow = static_cast(hBlow.GetPointer()); if (pDamageChageBlow && pDamageChageBlow->IsActivated() == true && pDamageChageBlow->GetLeftCoolTime() > 0.0f) { fChangeRatio += pDamageChageBlow->GetDamageRate(); } } } if (fChangeRatio >= 0.0f) { fResult += fResult * fChangeRatio; } } #endif // PRE_ADD_TOTAL_LEVEL_SKILL #pragma endregion if( HitParam.HasElement != CDnActorState::ElementEnum_Amount ) { fElementWeight = 1.f; fElementWeight = ( ( 1.f + pState->GetElementAttack( HitParam.HasElement ) ) * ( 1.f - GetElementDefense( HitParam.HasElement ) ) ); #ifndef PRE_ADD_BUFF_STATE_LIMIT fElementWeight = max( fElementWeight, CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ElementMinRevision ) ); #endif fResult *= fElementWeight; } // Å©¸®Æ¼Äà ÀúÇ× °è»êÇØ¼­ ´ë¹ÌÁö ±ï¾ÆÁØ´Ù. (ºê·¹ÀÌÅ· Æ÷ÀÎÆ®(½´ÆÛ¾Æ¸Ó ºê·¹ÀÌÅ©)°¡ ¼³Á¤µÇ¾î ÀÖÁö ¾Ê¾Æ¾ßÇÔ) if( HitParam.HitType == CDnWeapon::Critical && false == HitParam.bBreakSuperAmmor) { float fCriticalValue = hHitter->GetCriticalConstant(); float fCriticalResistProb = GetCriticalResistance() / fCriticalValue; if( fCriticalResistProb > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalResistanceMax ) ) fCriticalResistProb = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalResistanceMax ); if( _rand(GetRoom())%100 < (int)( fCriticalResistProb * 100.f ) ) { #if defined(PRE_FIX_51491) //Å©¸®Æ¼Ä÷Π¹ß»ýÇß´ø µ¥¹ÌÁö °¡»ê °ªÀ» ¾ø¾Ø´Ù.. //#57510 PvP¿¡¼­ Å©¸®Æ¼Äà µ¥¹ÌÁö 1.5 float fCriticalIncValue = 1.0f; if( GetGameRoom()->bIsPvPRoom() == true ) fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease_PVP ); else fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease ); fResult = fResult / fCriticalIncValue; #else fResult *= CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalResistance ); #endif // PRE_FIX_51491 m_HitParam.HitType = CDnWeapon::CriticalRes; } } #pragma region ++ [ pComboDamageLimitBlow BY SELF ( BLOW_242 ) ] ++ // #52332 ÀÏÁ¤ HIT¼ö ÀÌÈÄ¿¡ µ¥¹ÌÁö °¨¼ÒµÇ´Â È¿°ú ±¸Çö // 242¹ø »óÅÂÈ¿°ú Àû¿ëµÇ¾î ÀÖ´Â °æ¿ì, Áö±Ý µ¥¹ÌÁö °è»ê¿¡ »ç¿ëµÈ ½ºÅ³/¾×Å͸¦ ÀÌ¿ëÇØ¼­ HitÄ«¿îÆ® Á¦ÇѰªÀ» °»½ÅÇÑ´Ù.. if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_242 ) ) { CDnSkill::SkillInfo *pSkillInfo = NULL; DnSkillHandle hSkill; if (HitParam.bFromProjectile && HitParam.hWeapon) hSkill = static_cast( HitParam.hWeapon.GetPointer() )->GetParentSkill(); else hSkill = hHitter->GetProcessSkill(); if (hSkill) pSkillInfo = const_cast(hSkill->GetInfo()); DNVector(DnBlowHandle) vlBlows; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_242, vlBlows ); int nBlowCount = (int)vlBlows.size(); for (int i = 0; i < nBlowCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow) { CDnComboDamageLimitBlow* pComboDamageLimitBlow = dynamic_cast(hBlow.GetPointer()); if (pComboDamageLimitBlow) pComboDamageLimitBlow->UpdateHitCount(pSkillInfo, HitParam); } } } #pragma endregion // »óÅÂÈ¿°ú¿¡¼­ Ãß°¡ µ¥¹ÌÁö¸¦ ÁÙ ¼ö ÀÖÀ½. fResult += m_pStateBlow->OnCalcDamage( fResult, m_HitParam ); #if defined(PRE_FIX_59680) //¼­¸Õ ÆÛÆêÀÇ OnCalcDamage¸¦ È£Ãâ ÇÒ¶§ ÁÖÀÎ ¾×ÅÍÀÇ StateBlowÀÇ OnCalcDamageµµ È£ÃâÀÌ µÇ¾î¾ß ÁÖÀÎ ¾×ÅÍ µ¥¹ÌÁö Àû¿ëµÉ¶§ È¿°ú°¡ Á¤»ó Àû¿ëµÈ´Ù. //Ŭ·¹¸¯ÀÇ È¦¸®½¯µåÀÇ °æ¿ì Àڽſ¡°Ô CDnAddStateOnHitBlow(178) »óÅÂÈ¿°ú°¡ Àû¿ëµÇ°í, ÀÌÈÄ¿¡ ¼­¸ÕÆÛÆêÀÌ ¼Òȯ µÉ°æ¿ì, ¼­¸ÕÆÛÆêÀº ÀÌ »óÅÂÈ¿°ú¸¦ //°¡Áö°í ÀÖÁö ¾Ê´Ù. ±×·¡¼­ ¼­¸ÕÆÛÆêÀ¸·Î µ¥¹ÌÁö°¡ Ŭ·¹¸¯¿¡ Àû¿ëµÇÁö¸¸ µ¥¹ÌÁö¿¡ ÀÇÇÑ HPÁõ°¡ »óÅÂÈ¿°ú´Â ¹ßµ¿µÇÁö ¾Ê´Â´Ù. if (IsMonsterActor()) { DnActorHandle hSummonerActor; CDnStateBlow *pOwnerStateBlow = NULL; CDnMonsterActor* pMonsterActor = dynamic_cast(m_MySmartPtr.GetPointer()); if (pMonsterActor && pMonsterActor->IsSummonedMonster() && pMonsterActor->IsPuppetSummonMonster()) hSummonerActor = pMonsterActor->GetSummonerPlayerActor(); if(hSummonerActor) pOwnerStateBlow = hSummonerActor->GetStateBlow(); if (pOwnerStateBlow) pOwnerStateBlow->OnCalcDamage(fResult, m_HitParam); } #endif // PRE_FIX_59680 // OnTargetHit½Ã µ¥¹ÌÁöÈ®ÀÎÀ» À§ÇØ [2011/02/15 semozz] m_HitParam.nCalcDamage = (int)fResult; hHitter->GetStateBlow()->OnTargetHit( GetMySmartPtr() ); #pragma region ++ [ fResult -= fAbsorbDamage BY SELF ( BLOW_243 ) ] ++ if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_243 ) ) { float fAbsorbDamage = 0.f; int nAbsorbSP = 0; DNVector( DnBlowHandle ) vlhManaShieldBlow; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_243, vlhManaShieldBlow ); for( DWORD n=0; n(vlhManaShieldBlow[n].GetPointer()); pManShieldBlow->CalcManaShield( fResult , fAbsorbDamage , nAbsorbSP ); } if( nAbsorbSP > GetSP() ) { fAbsorbDamage -= (fAbsorbDamage * (nAbsorbSP - GetSP()) / nAbsorbSP); nAbsorbSP = GetSP(); } if( fAbsorbDamage > fResult ) fAbsorbDamage = fResult; fResult -= fAbsorbDamage; SetSP( GetSP() -nAbsorbSP ); RequestHPMPDelta( ElementEnum::ElementEnum_Amount, -nAbsorbSP, UINT_MAX, true , true ); } #pragma endregion #pragma region ++ [ fResult = 0.0f; BY SELF ( BLOW_051 ) ] ++ #if defined(PRE_FIX_61382) if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_051)) { DNVector(DnBlowHandle) vlhTransmitBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_051, vlhTransmitBlows ); int iNumBlow = (int)vlhTransmitBlows.size(); for( int i = 0; i < iNumBlow; ++i ) { CDnTransmitDamageBlow* pTransmitDamageBlow = static_cast(vlhTransmitBlows[i].GetPointer()); //µ¥¹ÌÁö Àü´ÞµÇ´Â ¾×ÅÍÀÇ È÷Æ® ¿©ºÎ¸¦ È®ÀÎ ÇØ¼­ È÷Æ® °¡´ÉÀ϶§¸¸ µ¥¹ÌÁö Àü´ÞÇÑ´Ù. DnActorHandle hTargetActor = pTransmitDamageBlow->GetActorHandle(); bool isEnableTransmitDamage = false; if (hTargetActor) { if (hTargetActor->IsMonsterActor()) { CDnMonsterActor* pMonsterActor = static_cast(hTargetActor.GetPointer()); isEnableTransmitDamage = pMonsterActor ? pMonsterActor->IsEnableNoDamage() == false : true; } else isEnableTransmitDamage = true; } //µ¥¹ÌÁö Àü´Þ °¡´É ÇÏ¸é µ¥¹ÌÁö Àü´Þ ½ÃŲ´Ù. if (isEnableTransmitDamage == true) pTransmitDamageBlow->TransmitDamage( fResult , m_HitParam ); } //µ¥¹ÌÁö Àü´Þ ÇÏ°í ³ª¼­ µ¥¹ÌÁö 0À¸·Î ¸®¼Â ½ÃÅ´.. fResult = 0.0f; } #endif // PRE_FIX_61382 #pragma endregion #pragma region ++ [ STAGE DAMAGE LIMIT ] ++ #ifdef PRE_ADD_STAGE_DAMAGE_LIMIT CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); if( pTask && pTask->GetStageDamageLimit()->fDamageLimit > 0.f ) { if( hHitter ) { CDnPlayerActor *pPlayerActor = NULL; if( hHitter->IsPlayerActor() ) { pPlayerActor = static_cast(hHitter.GetPointer()); } else if( hHitter->IsMonsterActor() ) { CDnMonsterActor *pMonsterActor = static_cast(hHitter.GetPointer()); if( pMonsterActor && pMonsterActor->GetSummonerPlayerActor() ) pPlayerActor = static_cast(hHitter.GetPointer()); } if( pPlayerActor ) { bool bNotifyInterface = false; float fBaseAttackPower = 0.f; if( HitParam.cAttackType == 0) { fBaseAttackPower = pState->GetAttackPMax() * fGausianResultProb * fHitPer; bNotifyInterface = pPlayerActor->GetDamageLimitInfo()->bPhysicalAttack; } else if (HitParam.cAttackType == 1) { fBaseAttackPower = pState->GetAttackMMax() * fGausianResultProb * fHitPer; bNotifyInterface = pPlayerActor->GetDamageLimitInfo()->bMagicalAttack; } else if (HitParam.cAttackType == 2) //rlkt_test { fBaseAttackPower = pState->GetAttackMMax() * fGausianResultProb * fHitPer; bNotifyInterface = pPlayerActor->GetDamageLimitInfo()->bMagicalAttack; } if( fResult > (fBaseAttackPower * pTask->GetStageDamageLimit()->fDamageLimit) ) { fResult = (fBaseAttackPower * pTask->GetStageDamageLimit()->fDamageLimit); #ifdef PRE_ADD_STAGE_LIMIT_INTERFACE if( bNotifyInterface == true ) HitParam.bStageLimit = true; #endif } } } } #endif #pragma endregion if( fResult < 0.f ) fResult = 0.f; return fResult; } float CDnActor::CalcDamage( CDnDamageBase *pHitter, SHitParam &HitParam ) { float fResult = PreCalcDamage( pHitter, HitParam ); #if defined( NODAMAGE ) || defined( STRESS_TEST ) return fResult; #endif #if defined(PRE_ADD_MISSION_COUPON) INT64 nSaveHP = m_nHP; SetHP((INT64)( m_nHP - fResult )); m_nHP = (INT64)( nSaveHP - fResult ); #else m_nHP = (INT64)( m_nHP - fResult ); #endif #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) if (IsAppliedThisStateBlow( STATE_BLOW::BLOW_268 )) { float fHpRate = 1.0f; if (m_nMaxHP > 0) fHpRate = (float)m_nHP / (float)m_nMaxHP; DNVector( DnBlowHandle ) vlhBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_268, vlhBlows ); float fChangeRatio = 0.0f; for( int i = 0; i < (int)vlhBlows.size(); ++i ) { DnBlowHandle hBlow = vlhBlows.at( i ); if (hBlow && hBlow->IsEnd() == false) { CDnDamageChagneBlow* pDamageChageBlow = static_cast(hBlow.GetPointer()); if (pDamageChageBlow) { float fHPLimit = pDamageChageBlow->GetHpLimit(); if (fHpRate < fHPLimit && pDamageChageBlow->IsActivated() == false && pDamageChageBlow->GetLeftCoolTime() == 0.0f) { pDamageChageBlow->ApplyDamageChange(); } } } } } #endif // PRE_ADD_TOTAL_LEVEL_SKILL return fResult; } void CDnActor::Die( DnActorHandle hHitter ) { // ¸ó½ºÅÍ ¸·Å¸Ä£ °Íµµ CP Á¡¼ö ó¸®ÇؾßÇØ¼­ À̰÷¿¡¼­ ´ëü ½ÃÄÑ ÁØ´Ù. if( hHitter && hHitter->IsMonsterActor() && IsMonsterActor() ) { DnActorHandle hSummonMasterPlayerActor = static_cast(hHitter.GetPointer())->GetSummonerPlayerActor(); if( hSummonMasterPlayerActor ) hHitter = hSummonMasterPlayerActor; } #if defined( PRE_ADD_58761 ) // Á×¾úÀ»‹š ·Î±× ³²±â±â CDNGameRoom *pRoom = GetGameRoom(); if( pRoom && CDnWorld::GetInstance(pRoom).GetMapSubType() == EWorldEnum::MapSubTypeNest) { if( hHitter && hHitter->IsMonsterActor() && IsPlayerActor() ) { DnMonsterActorHandle hMonster = hHitter; int nSkillID = 0; if(hMonster->GetProcessSkill()) nSkillID = hMonster->GetProcessSkill()->GetClassID(); CDNUserSession *pSession = pRoom->GetUserSession( GetSessionID() ); if (pSession) pRoom->NestDeathLog( pSession, hMonster->GetMonsterClassID(), nSkillID, pSession->GetUserJob(), pSession->GetLevel()); else _DANGER_POINT(); } } #endif #if defined(PRE_FIX_44884) bool bStateBlowProcessed = true; if (IsDie()) bStateBlowProcessed = m_pStateBlow->OnDie( hHitter ); if (IsDie()) OnDie(hHitter); #else OnDie( hHitter ); bool bStateBlowProcessed = m_pStateBlow->OnDie( hHitter ); #endif // PRE_FIX_44884 bool bCheckDie = false; if( false == bStateBlowProcessed ) { if( IsStandHit( m_HitParam.szActionName.c_str() ) ) m_HitParam.szActionName = "Die", bCheckDie = true; if( IsStun( m_HitParam.szActionName.c_str() ) && !IsAir( m_HitParam.szActionName.c_str() ) ) m_HitParam.szActionName = "Die", bCheckDie = true; if( !bCheckDie ) { // Ȧµå ½ºÅ³ ¶§¹®¿¡ Stay Á¶°Çµµ Æ÷ÇÔ.. ¾È±×·¯¸é Die ¾×¼ÇÀÌ ¹ßµ¿ÀÌ ¾ÈµÇ¾î¼­ hold ¸Â°í Çѹ濡 Á×À» °æ¿ì Ŭ¶ó¿¡¼­ "stand" ¾×¼ÇÀ¸·Î // OnDamage ÆÐŶÀ» ¹Þ¾Æ ¼± ä·Î Á×°Ô µÊ.. if( IsStay( m_HitParam.szActionName.c_str() ) ) m_HitParam.szActionName = "Die", bCheckDie = true; if( IsAir( m_HitParam.szActionName.c_str() ) ) { if( IsExistAction( "Die_Air" ) ) m_HitParam.szActionName = "Die_Air", bCheckDie = true; } if( IsDown( m_HitParam.szActionName.c_str() ) ) { if( IsExistAction( "Die_Down" ) ) m_HitParam.szActionName = "Die_Down", bCheckDie = true; } if( !bCheckDie ) m_HitParam.szActionName = "Die"; } } else { // ¸ó½ºÅͰ¡ Á×À¸¸é¼­ »ç¿ëÇÏ´Â ½ºÅ³ ¶§¹®¿¡ Die ¾×¼ÇÀÌ ¾Æ´Ï¶ó ±×³É stand ½ÃÅ´. (#16331) m_HitParam.szActionName = "Stand"; } m_bEnableNormalSuperAmmor = false; if (hHitter) { if (hHitter->IsMonsterActor()) { CDnMonsterActor* pMonster = static_cast(hHitter.GetPointer()); if (pMonster && pMonster->IsCannonMonsterActor()) { CDnCannonMonsterActor* pCannonMonster = static_cast(hHitter.GetPointer()); if (pCannonMonster && pCannonMonster->GetMasterPlayerActor() && pCannonMonster->GetMasterPlayerActor()->IsPlayerActor()) { CDnPlayerActor* pPlayerActor = static_cast(pCannonMonster->GetMasterPlayerActor().GetPointer()); if( pPlayerActor ) pPlayerActor->OnKillMonster(GetMySmartPtr()); } } } else if (hHitter->IsPlayerActor()) { CDnPlayerActor* pPlayerActor = static_cast(hHitter.GetPointer()); if( pPlayerActor ) pPlayerActor->OnKillMonster(GetMySmartPtr()); } } // °¢ ÆÄƼ¿øµé¿¡°Ô ¸ó½ºÅͰ¡ Á×¾ú´Ù°í ó¸®ÇØÁÜ. // NOTE: µ¶°É¸®°í Á×´Â ¼ø°£¿¡ Ŭ¶óÀÌ¾ðÆ®¸¦ ²ô´Ï±ñ ¼­¹ö°¡ Á״´Ù. pTask°¡ ¾²·¹±â°ªÀ¸·Î ³ª¿È.. CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); if ( pTask ) { for( DWORD i=0; i< pTask->GetRoom()->GetUserCount(); i++ ) { CDNGameRoom::PartyStruct *pStruct = pTask->GetRoom()->GetPartyData(i); if (!pStruct) continue; if( !IsMonsterActor() ) continue; CDnMonsterActor* pMonster = static_cast(this); if( pStruct->pSession && pStruct->pSession->GetQuest() ) pStruct->pSession->GetQuest()->OnDieMonster(pMonster->GetMonsterClassID()); } } } void CDnActor::OnDamage( CDnDamageBase *pHitter, SHitParam &HitParam, HitStruct *pHitStruct ) { //¿©±â µé¾î ¿Â ½ÃÁ¡Àº IsHitable¿¡¼­ üũ µÇ°í µé¾î ¿ÔÀ½. //µ¥¹ÌÁö ó¸® Àü¿¡ »óÅÂÈ¿°ú¸¦ Á¦°Å.. RemoveStateEffectByHitSignal(pHitStruct); DnActorHandle hHitterActor = pHitter->GetActorHandle(); if( hHitterActor && hHitterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_183) == false ) { #if defined(PRE_ADD_PREFIX_SYSTE_RENEW) hHitterActor->ApplyPrefixOffenceSkillToTarget_New(GetActorHandle()); #else hHitterActor->ApplyPrefixOffenceSkillToTarget(GetActorHandle()); #endif } m_HitParam = HitParam; DnActorHandle hHitter = pHitter->GetActorHandle(); CDnStateBlow *pHitterStateBlow = hHitter->GetStateBlow(); #if defined(PRE_ADD_PROJECTILE_SE_INFO) if( hHitter && HitParam.bFromProjectile && HitParam.hWeapon ) { CDnStateBlow *pProjectileStateBlow = static_cast( HitParam.hWeapon.GetPointer() )->GetShooterStateBlow().get(); if( pProjectileStateBlow ) pHitterStateBlow = pProjectileStateBlow; } #endif #ifdef PRE_ADD_EXPORT_DPS_INFORMATION if( CDnDPSReporter::IsActive() && hHitter && hHitter->IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast( hHitter.GetPointer()); if(CDnDPSReporter::GetInstance().IsEnabledUser(pPlayerActor->GetCharacterDBID())) CDnDPSReporter::GetInstance().StartReport(); } float fDPS_DAMAGE = 0; #endif CDnWeapon::HitTypeEnum HitType = CDnWeapon::Normal; // ¸íÁß·ü °è»ê SetDamageRemainTime( hHitter->GetUniqueID(), HitParam.RemainTime , hHitter->GetCurrentActionIndex() ); SetLastDamageHitUniqueID( hHitter->GetUniqueID(), HitParam.iUniqueID ); m_fStiffDelta = 0.f; if( m_fDownDelta > 0.f ) m_fLastDownRatio *= 0.5f; m_fDownDelta = 0.f; bool bAir = false; if( IsAir() && IsHit() ) bAir = true; bool bHitSuccess = CheckDamageAction( hHitter ); // ¹°¸®°ø°ÝÀ¸·Î ¸¶¹ý°ø°ÝÀ¸·Î º¯°æ.. [2011/02/21 semozz] if (hHitter && hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_180)) { if (0 == m_HitParam.cAttackType) { //BLOW_180ÀÌ °ø°ÝÀÚ¿¡ Àû¿ëµÇ¾îÀÖÀ¸¸é ¸ðµç ¹°¸® °ø°ÝÀ» ¸¶¹ý °ø°ÝÀ¸·Î º¯°æÇÑ´Ù. m_HitParam.cAttackType = 1; } } if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_182) ) { //¼Ó¼º °ø°Ý ¼³Á¤ÀÌ µÇÀú ÀÖÁö ¾ÊÀ»¶§¸¸ º¯°æ?? if( m_HitParam.HasElement == CDnActorState::ElementEnum_Amount ) { DNVector(DnBlowHandle) vlChangeElementBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_182, vlChangeElementBlows ); CDnState::ElementEnum eElementType = CDnState::ElementEnum_Amount; if (!vlChangeElementBlows.empty()) { eElementType = CDnState::ElementEnum(int(vlChangeElementBlows.at(0)->GetFloatValue())); } if (eElementType != CDnActorState::ElementEnum_Amount) m_HitParam.HasElement = eElementType; } } if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_149 ) == false ) // ¾óÀ½°¨¿Á »óÅÂÈ¿°ú °É·ÈÀ» ¶§´Â OnDefenseAttack À» ¹Þ¾Æ¼­ ó¸®ÇÏ´Â ÆÐ¸µ, ºí·Ï »óÅÂÈ¿°ú 󸮸¦ ÇÏÁö ¾ÊÀ½. { CDnState* pAttackerState = NULL; if( hHitter && !HitParam.bFromProjectile ) { pAttackerState = static_cast(hHitter.GetPointer()); } else { if( HitParam.hWeapon ) pAttackerState = static_cast( HitParam.hWeapon.GetPointer() )->GetShooterStateSnapshot().get(); #if !defined(PRE_ADD_PROJECTILE_SE_INFO) if (hHitter&& hHitter->IsApplyPrefixOffenceSkill()) pAttackerState = static_cast(hHitter.GetPointer()); #endif if( hHitter && pAttackerState == NULL ) pAttackerState = static_cast(hHitter.GetPointer()); } #ifdef PRE_ADD_MONSTER_CATCH bool bCheckOnDefense = true; if( IsPlayerActor() ) { // ¸ó½ºÅÍ¿¡ ÀâÈù »óÅ¿¡¼­´Â ½ºÅ³ °ü·Ã ³»¿ëµé ¹«½Ã. if( static_cast(this)->IsCatchedByMonster() || m_HitParam.bReleaseCatchActor ) bCheckOnDefense = false; } // ¶§¸° ³à¼®ÀÎ hActor ¿¡¼­ state ¸¦ °¡Á®´Ù »ç¿ëÇÏ¸é ½ºÅ³ ¾×¼ÇÀÌ ÀÌ¹Ì ³¡³­ »óÅÂÀÏ ¼ö Àֱ⠶§¹®¿¡ Æò¼Ò °ø°Ý·Â/¹æ¾î·ÂÀÏ ¼ö ÀÖÀ¸¹Ç·Î // ¹ß»çü¿¡ ½Ç¾î¼­ º¸³»´Â °Í±îÁö °í·ÁµÈ pAttackerState ¸¦ »ç¿ëÇÑ´Ù. // pAttackerState ¸¦ ÇÔ¼ö ³»ºÎ¿¡¼­ »ç¿ëÇÒ °æ¿ì, ¹Ýµå½Ã ³»ºÎ¿¡¼­ NULL Æ÷ÀÎÅÍ Ã¼Å©¸¦ ÇØ¾ß ÇÔ. if( bCheckOnDefense ) bHitSuccess = m_pStateBlow->OnDefenseAttack( hHitter, pAttackerState, m_HitParam, bHitSuccess ); #else bHitSuccess = m_pStateBlow->OnDefenseAttack( hHitter, pAttackerState, m_HitParam, bHitSuccess ); #endif } // µ¥¹ÌÁö ¹Ý»ç »óÅÂÈ¿°ú¿¡ ÀÇÇØ hitter °¡ ¸ó½ºÅÍÀÎ °æ¿ì Die ó¸®µÇ¾î °´Ã¼°¡ destroy µÉ ¼ö ÀÖ´Ù. // Ç÷¹À̾îÀÎ °æ¿ì °´Ã¼°¡ ÆÄ±«µÇÁö ¾ÊÀ¸¹Ç·Î CheckDamageVelocity() ÇÔ¼ö°¡ È£ÃâµÇ¾î ÀûÀýÇÏ°Ô // Çǰݾ׼ÇÀÌ ³ª¿Ã ¼ö ÀÖµµ·Ï ó¸®ÇÑ´Ù.#23559 // ¸ó½ºÅÍÇÑÅ× ¸ÂÀÚ¸¶ÀÚ µ¥¹ÌÁö ¹Ý»ç·Î ¸ó½ºÅͰ¡ Á×À¸¸é ¼Óµµ °ªÀÌ Á¤È®È÷ ¼ÂÆÃ ¾ÈµÇ¾î µ¿ÀÏÇÑ ¹®Á¦°¡ ³ª¿Ã ¼ö ÀÖÁö¸¸ // ¿ì¼± Ç÷¹À̾îÂʸ¸ ó¸®ÇصдÙ. if( hHitter->IsMonsterActor() ) { if( !hHitter || hHitter->IsDie() ) return; } bool isBreakSuperArmorBlow = false; if( bHitSuccess ) { // °æÁ÷ ½Ã°£ °è»ê float fStiffResult = 0.f; if( GetStiffResistance() > 0 ) fStiffResult = ( hHitter->GetStiff() * m_HitParam.fStiffProb ) / GetStiffResistance(); fStiffResult *= CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffRevision ); if( fStiffResult < 0.001f ) fStiffResult = 0.001f; // CPacketCompressStream::FLOAT_SHORT À» »ç¿ëÇϱ⶧¹®¿¡ ¹üÀ§¸¦ ¹þ¾î³ª´Â ÀÛÀº °ªÀÌ µÇÁö¾Êµµ·Ï ¼³Á¤ÇÑ´Ù. if( fStiffResult <= 0.f ) { fStiffResult = 0.05f; } else { float fStiffMax = 0.f; #if defined PRE_ADD_PVP_STIFF_MAX if( GetGameRoom()->bIsPvPRoom() == true ) fStiffMax = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax_PVP ); else fStiffMax = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax ); #else fStiffMax = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax ); #endif if( fStiffResult > fStiffMax ) fStiffResult = fStiffMax; } m_fStiffDelta = s_fMaxStiffTime * fStiffResult; // ´Ù¿îµô·¹ÀÌ ·£´ý°ª ¼³Á¤ if( !IsDown() ) { m_fLastDownRatio = 1.f; } float fTemp = ( 3.f * ( 1.f - GetDownDelayProb() ) ) * m_fLastDownRatio; int nTemp = (int)( fTemp * DOWN_DELAY_RANDOM_RANGE * 100.f ); if( nTemp == 0 ) m_fDownDelta = fTemp; else m_fDownDelta = fTemp - DOWN_DELAY_RANDOM_RANGE + ( _rand(GetRoom())%( nTemp * 2 ) / 100.f ); if( m_fDownDelta >= 3.f ) m_fDownDelta = 3.f; if( m_fDownDelta <= 0.01f ) m_fDownDelta = 0.01f; // Å©¸®Æ¼Äà °è»ê float fCritical = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalValue ); float fCriticalValue = hHitter->GetLevelWeightValue() * fCritical; float fCriticalProb = 0.f; if( fCriticalValue > 0.f ) fCriticalProb = hHitter->GetCritical() / fCriticalValue; else g_Log.Log(LogType::_SESSIONCRASH, L"fCriticalValue = 0.f ClassID=%d\n", hHitter->GetClassID() ); float fAddCiriticalValue = 0.0f; if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_250)) { DNVector( DnBlowHandle ) vlhCriticalIncBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_250, vlhCriticalIncBlows ); int nListCount = (int)vlhCriticalIncBlows.size(); for (int i = 0; i < nListCount; ++i) { DnBlowHandle hBlow = vlhCriticalIncBlows[i]; if (hBlow) fAddCiriticalValue += hBlow->GetFloatValue(); } } if( pHitterStateBlow ) { if( pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_251) ) { DNVector(DnBlowHandle) vlhCriticalIncBlows; pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_251, vlhCriticalIncBlows ); int nListCount = (int)vlhCriticalIncBlows.size(); for (int i = 0; i < nListCount; ++i) { DnBlowHandle hBlow = vlhCriticalIncBlows[i]; if (hBlow) fAddCiriticalValue += hBlow->GetFloatValue(); } } } fCriticalProb += fAddCiriticalValue; if( fCriticalProb > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax ) ) fCriticalProb = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax ); bool bBreakSuperAmmor = false; //½´ÆÛ¾Æ¸Óºê·¹ÀÌÅ© »óÅÂÈ¿°ú °É·Á ÀÖ°í, È®·üÀÌ ¸ÂÀ¸¸é Å©¸®Æ¼Ä÷Πº¯°æ.( ¸é¿ªÀÌ ¾Æ´Ï¾î¾ß ÇÑ´Ù..) if (hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_162) && !IsImmuned(STATE_BLOW::BLOW_162)) { DNVector( DnBlowHandle ) vlhBreakSuperArmors; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_162, vlhBreakSuperArmors ); float fRate = 0.0f; DnSkillHandle hSkill; if (!vlhBreakSuperArmors.empty()) { const CDnSkill::SkillInfo* pSkillInfo = vlhBreakSuperArmors.at(0)->GetParentSkillInfo(); if (pSkillInfo) hSkill = hHitter->FindSkill(pSkillInfo->iSkillID); if (hSkill && CDnSkill::UsingResult::Success == hSkill->CanExecute()) { fRate = vlhBreakSuperArmors.at(0)->GetFloatValue(); } } bBreakSuperAmmor = rand() % 10000 <= (fRate * 10000.0f); if (bBreakSuperAmmor) { fCriticalProb = 1.0f; m_HitParam.bBreakSuperAmmor = true; if (hSkill && CDnSkill::Passive == hSkill->GetSkillType()) { // PassiveSkill ÄðŸÀÓ Ç¥½Ã¸¦ À§ÇÑ ÆÐŶ Àü¼Û... BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); DWORD dwUniqueID = hHitter ? hHitter->GetUniqueID() : -1; int nSkillID = hSkill->GetClassID(); Stream.Write( &dwUniqueID, sizeof(dwUniqueID) ); Stream.Write( &nSkillID, sizeof(nSkillID)); hHitter->Send(eActor::SC_PASSIVESKILL_COOLTIME, &Stream); //½ÇÁ¦ ÄðŸÀÓ ½ÃÀÛ. hSkill->OnBeginCoolTime(); } //½´ÆÛ¾Æ¸Óºê·¹ÀÌÅ© ÀÌÆåÆ® Ç¥½Ã ÆÐŶ Àü¼Û.. { //ÀÌÆåÆ® Ç¥½Ã¿ë ÆÐŶÀ» Àü¼Û.. BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); DWORD dwUniqueID = hHitter ? hHitter->GetUniqueID() : -1; STATE_BLOW::emBLOW_INDEX blowIndex = STATE_BLOW::BLOW_162; bool bShowEffect = true; Stream.Write( &dwUniqueID, sizeof(dwUniqueID) ); Stream.Write( &blowIndex, sizeof(blowIndex)); Stream.Write( &bShowEffect, sizeof(bShowEffect)); hHitter->Send(eActor::SC_SHOW_STATE_EFFECT, &Stream); } } } //162¹ø »óÅÂÈ¿°ú¿¡ ÀÇÇØ ½´ÆÛ ¾Æ¸Ó°¡ ±úÁ³´ÂÁö È®ÀÎ if (bBreakSuperAmmor) isBreakSuperArmorBlow = true; //79¹ø »óÅÂÈ¿°ú°¡ °É·Á ÀÖÀ¸¸é ¹«Á¶°Ç ½´ÆÛ ¾Æ¸Ó ±úÁü.. if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_079)) isBreakSuperArmorBlow = true; EtVector3 vVelocity = m_HitParam.vVelocity; // ½ºÅÏ °è»ê int nStunProb = (int)( CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunMax ) * 100.f ); if( GetStunResistance() > 0 ) { float fLocalTemp = powf( (float)( hHitter->GetStun() / GetStunResistance() ), CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunRevisioin ) ) * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunRevision2 ); if( fLocalTemp > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunMax ) ) fLocalTemp = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunMax ); nStunProb = (int)( fLocalTemp * 100.f ); } bool isAppliedForceSturn = false; // Ÿ°ÝÀÚ°¡ °­Á¦ ½ºÅÏ »óÅÂÈ¿°ú°¡ ÀÖ´Â »óȲÀ̶ó¸é ÇØ´ç »óÅÂÈ¿°ú ¼öÄ¡·Î ÀÖ´Â È®·ü °ª (0.0~1.0)À» ´õÇÑ´Ù. if( hHitter && hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_133 ) ) { DNVector( DnBlowHandle ) vlhStunBlow; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_133, vlhStunBlow ); for( int i = 0; i < (int)vlhStunBlow.size(); ++i ) nStunProb += int(vlhStunBlow.at(i)->GetFloatValue() * 100.0f); isAppliedForceSturn = true; } // if( hHitter->GetStun() > 0 ) nStunProb = (int)( ( ( 1.f - ( hHitter->GetStun() / GetStunResistance() ) ) * 100 ) * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunRevisioin ) ); nStunProb = (int)( nStunProb * m_HitParam.fDamage ); if( _rand(GetRoom())%100 < nStunProb ) { if( IsStandHit( m_HitParam.szActionName.c_str() ) ) { m_HitParam.szActionName = "Stun"; } else if( IsAir( m_HitParam.szActionName.c_str() ) ) { if( strstr( m_HitParam.szActionName.c_str(), "High" ) == NULL ) { m_HitParam.szActionName = "Hit_AirUp"; } vVelocity = m_HitParam.vVelocity * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunVelocityRevision ) * ( 1.f + pHitStruct->fStunVelocityRevision ); } else if( IsDown( m_HitParam.szActionName.c_str() ) ) { m_HitParam.szActionName = "Hit_AirUp"; } //½ºÅÏÀÌ µÇ´õ¶óµµ Å©¸®Æ¼ÄÃÀÌ ¹ß»ýµÇ¾î¾ß ÇÔ. //±×·¡¼­ STATE_BLOW::BLOW_133 »óÅÂÈ¿°ú°¡ ´Ù¸é StunÀ¸·Î ¹«Á¶°Ç ¼³Á¤Çϰí //STATE_BLOW::BLOW_133»óÅÂÈ¿°ú°¡ ÀÖ°í, hitTypeÀÌ ¼³Á¤µÇ¾î ÀÖÀ¸¸é hitTypeÀ» SturnÀ¸·Î ¹Ù²ÙÁö ¸»°í À¯Áö if (!isAppliedForceSturn) HitType = CDnWeapon::Stun; else if (HitType == CDnWeapon::Normal) HitType = CDnWeapon::Stun; m_fStiffDelta = 0.f; } if ( m_HitParam.HasElement == CDnActorState::Fire && IsAppliedThisStateBlow(STATE_BLOW::BLOW_042)) // È÷Æ® ¼Ó¼ºÀÌ È­¿°À̸ç , È­»ó¿¡ °É·ÁÀÖ´Â »óÅÂÀ̶ó¸é { if (hHitter && hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_222)) // ¶§¸°³à¼®ÀÌ È­¿°¼Ó¼º Å©¸® »óÅÂÈ¿°ú¸¦ µé°íÀÖ´Ù¸é. { DNVector( DnBlowHandle ) vBurnCriticalBlows; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_222, vBurnCriticalBlows ); if (!vBurnCriticalBlows.empty()) { if(vBurnCriticalBlows.at(0)) { CDnBurnCriticalBlow *pBurnCriticalBlow = static_cast(vBurnCriticalBlows.at(0).GetPointer()); if(pBurnCriticalBlow->GetMultiplyRatio() > 0) fCriticalProb = fCriticalProb + ( fCriticalProb * ( (float)pBurnCriticalBlow->GetMultiplyRatio() * 1/100 ) ); if(pBurnCriticalBlow->GetAddValueRatio() > 0) fCriticalProb = fCriticalProb + (pBurnCriticalBlow->GetAddValueRatio() / fCriticalValue); if( fCriticalProb > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax ) ) fCriticalProb = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax ); } } } } //½ºÅÏÈ®·ü °è»ê ÀÌÈÄ Å©¸®Æ¼Äà Ȯ·ü °è»êÀ¸·Î º¯°æ. if( _rand(GetRoom())%100 < (int)( fCriticalProb * 100.f ) ) { vVelocity = m_HitParam.vVelocity * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalVelocityRevision ) * ( 1.f + pHitStruct->fCriticalVelocityRevision ); HitType = CDnWeapon::Critical; #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) //Å©¸®Æ¼ÄÃÀÎ °æ¿ì ÅëÇÕ·¹º§½ºÅ³ÀÇ »óÅÂÈ¿°ú if (hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_267)) { DNVector( DnBlowHandle ) vlhBlows; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_267, vlhBlows ); int nCount = (int)vlhBlows.size(); for( int i = 0; i < (int)vlhBlows.size(); ++i ) { CDnAddCriticalRateBlow* pBlow = static_cast(vlhBlows[i].GetPointer()); if (pBlow && pBlow->IsActivated() == false && pBlow->GetLeftCoolTime() == 0.0f) pBlow->ApplyCriticalIncBlow(); } } #endif // PRE_ADD_TOTAL_LEVEL_SKILL //rlkt_mastery! //printf("%s, OnCriticalHit Passive %d \n ", __FUNCTION__, 7529); //mastery 1 dark avenger /* CDnPlayerActor *pPlayer = static_cast(hHitter.GetPointer()); boost::shared_ptr pEvent(IDnObserverNotifyEvent::Create(EVENT_ONCRITICALHIT)); pEvent->SetSkillID(hHitter->GetProcessSkill()->GetClassID()); pPlayer->Notify(pEvent);*/ CDnPlayerActor *pPlayer = static_cast(hHitter.GetPointer()); if (pPlayer && pPlayer->IsPlayerActor()) { printf("%s Notify EVENT_ONCRITICALHIT\n",__FUNCTION__); boost::shared_ptr pEvent(IDnObserverNotifyEvent::Create(EVENT_ONCRITICALHIT)); pEvent->SetSkillID(pPlayer->GetLastUsedSkill()); pPlayer->Notify(pEvent); //boost::shared_ptr pEvent(IDnObserverNotifyEvent::Create(EVENT_ONCRITICALHIT)); ////pEvent->SetSkillID(pPlayer->GetLastUsedSkill()); //pPlayer->Notify(pEvent); } /* CDnPlayerActor *pPlayer = static_cast(hHitter.GetPointer()); shared_ptr pNotifyEvent(new CDnOnCriticalHitMessage); shared_ptr pOnCriticalEvent = shared_polymorphic_downcast(pNotifyEvent); pOnCriticalEvent->SetSkillID(hHitter->GetProcessSkill()->GetClassID()); pPlayer->Notify(pNotifyEvent);*/ } // ¿¡¾î ÄÞº¸ °è»ê if( IsAir() && IsHit() ) { m_nAirComboCount++; hHitter->OnAirCombo( m_nAirComboCount ); } else m_nAirComboCount = 0; m_HitParam.vVelocity = vVelocity; } else HitType = CDnWeapon::Defense; m_HitParam.HitType = HitType; // µ¥¹ÌÁö °è»ê switch( HitType ) { case CDnWeapon::Normal: case CDnWeapon::Critical: case CDnWeapon::Stun: case CDnWeapon::CriticalRes: { // ¹«°Ô¿¡ µû¶ó °¡¼Óµµ ÁÙ¿©ÁØ´Ù. if( GetWeight() > 0.f ) m_HitParam.vVelocity.y /= GetWeight(); if( GetWeight() > 1.f ) { float fTemp = m_HitParam.vVelocity.z; float fTest = CalcMovement( fTemp, 1.f, FLT_MAX, FLT_MIN, m_HitParam.vResistance.z ); if( m_HitParam.vVelocity.z * fTest > 0.f ) { m_HitParam.vVelocity.x /= powf( 1.1f, GetWeight() ); m_HitParam.vVelocity.z /= powf( 1.1f, GetWeight() ); } } // ´ë¹ÌÁö »ó°ü°ü°è Ã¼Å©ÇØ¿ä int nDamageType = m_HitParam.nDamageType; // #13885 À̽´ °ü·Ã. if( hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_086 ) ) { // ÆÀ ¹ÝÀü »óÅÂÈ¿°ú Çϳª¸¸ Àû¿ëµÈ´Ù. DNVector( DnBlowHandle ) vlReverseTeamBlows; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_086, vlReverseTeamBlows ); _ASSERT( false == vlReverseTeamBlows.empty() ); if( false == vlReverseTeamBlows.empty() ) { DnBlowHandle hBlow = vlReverseTeamBlows.front(); CDnReverseTeamBlow* pReverseTeamBlow = static_cast(hBlow.GetPointer()); if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_CHANGE == pReverseTeamBlow->GetType() ) { switch( nDamageType ) { case 0: // Enemy -> Friend nDamageType = 1; break; case 1: // Friend -> Enemy nDamageType = 0; // #50166 À̽´°ü·Ã Hittalbe¿¡¼­¸¸ ó¸®ÇÑ´Ù. break; case 2: // All -> All break; } } else if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_ALL == pReverseTeamBlow->GetType() ) { // Ÿ°Ý´ë»ó all ·Î ¹Ù²ãÁÜ. nDamageType = 2; } } } //rlkt_damage bool bCalcDamage = true; float fDamage = 0.f; switch( nDamageType ) { case 0: // Enemy if( GetTeam() == hHitter->GetTeam() ) bCalcDamage = false; break; case 1: // Friend if( GetTeam() != hHitter->GetTeam() ) bCalcDamage = false; break; case 2: // All break; } if( bCalcDamage ) { fDamage = CalcDamage( hHitter, m_HitParam ); #ifdef PRE_ADD_EXPORT_DPS_INFORMATION fDPS_DAMAGE = fDamage; #endif } // Á×¾ú³ª üũ if( GetHP() <= 0.f ) Die( hHitter ); if (fDamage > 0.0f && //µ¥¹ÌÁö°¡ ÀÖ°í GetHP() > 0.0f && //»ç¸ÁÀÌ ¾Æ´Ï°í !IsAppliedThisStateBlow(STATE_BLOW::BLOW_183)) //Á¢µÎ¾î »óÅÂÈ¿°ú ¹«½Ã(±¸¿ï¸ðµå) ¾Æ´Ñ°æ¿ì) { #if defined(PRE_ADD_PREFIX_SYSTE_RENEW) ProcessPrefixDefenceSkill_New(hHitterActor); #else ProcessPrefixDefenceSkill(hHitterActor); #endif // PRE_ADD_PREFIX_SYSTE_RENEW } bool bSuccessNormalDamage = true; int nSuperAmmorTime = 0; if( !IsDie() ) { // Skill Super Ammor Check // if( m_HitParam.nSkillSuperAmmorIndex == -1 || ( m_HitParam.nSkillSuperAmmorIndex != -1 && m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] > 0 ) { bool bApplySuperAmmor = false; if( m_HitParam.nSkillSuperAmmorIndex != -1 && m_HitParam.nSkillSuperAmmorIndex < 0) break; if( m_HitParam.nSkillSuperAmmorIndex == -1 ) { bApplySuperAmmor = true; } else if( m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] > 0 ) { int nAmmorDamage = m_HitParam.nSkillSuperAmmorDamage;// * (( HitType == CDnWeapon::Critical ) ? 2 : 1); // ½´ÆÛ ¾Æ¸Ó º¸È£ »óÅ ȿ°ú°¡ Àû¿ë µÇ¾î ÀÖÀ¸¸é ½´ÆÛ ¾Æ¸Ó °è»ê ¾ÈÇÔ.[2010/12/28 semozz] bool isApplySuperArmorShield = false; isApplySuperArmorShield = this->IsAppliedThisStateBlow(STATE_BLOW::BLOW_156); // [2011/02/09 semozz] // °¡µð¾ð Æ÷½ºÀÇ Shield»óÅÂÈ¿°ú°¡ Àû¿ë µÇ¾î ÀÖÀ»¶§µµ ½´ÆÛ¾Æ¸Ó´Â ±úÁöÁö ¾Ê´Â´Ù. // ½´ÆÛ¾Æ¸Ó º¸È£°ü·ÃÀÌ ¿ì¼±¼øÀ§°¡ °¡Àå ³ô´Ù. if (!isApplySuperArmorShield) isApplySuperArmorShield = this->IsAppliedThisStateBlow(STATE_BLOW::BLOW_055); //½´ÆÛ¾Æ¸Ó ºê·¹ÀÌÅ© »óÅÂÈ¿°ú Àû¿ëµÇ¾î ÀÖÀ¸¸é ¹«Á¶°Ç ½´ÆÛ¾Æ¸Ó 0À¸·Î if (isBreakSuperArmorBlow) { m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] = 0; } else if (!isApplySuperArmorShield) { ////////////////////////////////////////////////////////////////////////// // 142¹ø ½´ÆÛ¾Æ¸Ó °ø°Ý·Â ºñÀ² »óÅÂÈ¿°ú if( hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_142 ) ) { DNVector(DnBlowHandle) vlBlows; float fValue = 1.0f; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_142, vlBlows ); for( int i = 0; i < (int)vlBlows.size(); ++i ) { DnBlowHandle hBlow = vlBlows.at( i ); fValue += (hBlow->GetFloatValue() - 1.0f); } nAmmorDamage = int((float)nAmmorDamage * fValue); } ////////////////////////////////////////////////////////////////////////// m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] -= nAmmorDamage; } if( m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] <= 0 ) { m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] = 0; hHitter->OnBreakSkillSuperAmmor( m_HitParam.nSkillSuperAmmorIndex, m_nLastUpdateSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex], nAmmorDamage ); OnBreakSkillSuperAmmor( m_HitParam ); } else bApplySuperAmmor = true; } if( bApplySuperAmmor ) { bSuccessNormalDamage = false; nSuperAmmorTime = m_nSkillSuperAmmorTime; // ´ë¹ÌÁö °¨¼è½ÃÄÑÁØ´Ù. SetHP( GetHP() + (INT64)( fDamage * m_fSkillSuperAmmorDamageDecreaseProb ) ); #ifdef PRE_ADD_EXPORT_DPS_INFORMATION fDPS_DAMAGE += (int)( fDamage * m_fSkillSuperAmmorDamageDecreaseProb ); #endif } // Normal Super Ammor Check if( m_bEnableNormalSuperAmmor == true ) { if( m_HitParam.fDurability >= m_fBreakNormalSuperAmmorDurability ) m_bEnableNormalSuperAmmor = false; else { bSuccessNormalDamage = false; nSuperAmmorTime = m_nNormalSuperAmmorTime; } } if( pHitStruct->nSuperAmmorTime > 0 ) nSuperAmmorTime = pHitStruct->nSuperAmmorTime; } bool bSuperAmmorReset = true; ////////////////////////////////////////////////////////////////////////// // ¾ÆÄ«µ¥¹Í Æ÷½º ¾Æ¿ô ½ºÅ³ ó¸® [2011/07/04 semozz] // ¹«°Ô°ª Á¦ÇÑ °ªÀÌ ÀÖ°í, ¼³Á¤µÈ ¹«°Ô°ª º¸´Ù ¾×ÅÍÀÇ ¹«°Ô°¡ Àû´Ù¸é ½´ÆÛ¾Æ¸Ó »ó°ü ¾øÀÌ ¹°¸®°ª Àû¿ë if( 0 < m_HitParam.nWeightValueLimit ) { if( (float)m_HitParam.nWeightValueLimit >= GetWeight() ) { //¹°¸®°ª Àû¿ëÀ» À§Çؼ­ bSuccessNormalDamage´Â true·Î º¯°æÇϰí. bSuccessNormalDamage = true; //½´ÆÛ¾Æ¸Ó °ª ¸®¼ÂÀº ¾ÈµÇµµ·ÏÇÑ´Ù.. bSuperAmmorReset = false; //½´ÆÛ¾Æ¸Ó°¡ ±úÁö¸é(0) hitµ¿ÀÛÀ» Çϰí, ½´ÆÛ¾Æ¸Ó°¡ ±úÁöÁö ¾ÊÀ¸¸é Hitµ¿ÀÛÀ» Á¦°Å ÇÑ´Ù. //#39137 ¸ó½ºÅͰ¡ Á×Àº °æ¿ì´Â ½ºÅµ if (!IsDie() && m_HitParam.nSkillSuperAmmorIndex>=0 && m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] > 0) m_HitParam.szActionName.clear(); } } ////////////////////////////////////////////////////////////////////////// //ÀÌ »óÅÂÈ¿°ú°¡ °É·Á ÀÖ´Â »óÅ¿¡¼­ ÇÇ°Ý µ¿ÀÛÀ» Çϸé Escape¿¡¼­ ¼³Á¤µÈ ÇÇ°Ý µ¿ÀÛÀÌ Áß°£¿¡ Ãë¼ÒµÊ. if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_218)) { #if defined(PRE_FIX_50007) //#50007 EscapeÁß¿¡µµ Á×´Â µ¿ÀÛÀ¸·Î´Â º¯°æÀÌ µÇ¾î¾ß ÇÔ.(Dieµ¿ÀÛÀÌ ¾Æ´Ñ °æ¿ì¸¸ Hitµ¿ÀÛ Á¦°Å) if (strstr(m_HitParam.szActionName.c_str(), "Die") == NULL) #endif // PRE_FIX_50007 m_HitParam.szActionName.clear(); } m_HitParam.bSuccessNormalDamage = bSuccessNormalDamage; m_HitParam.nSuperAmmorDelay = nSuperAmmorTime; if( bSuccessNormalDamage ) { m_nNormalSuperAmmorTime = 0; if (bSuperAmmorReset) memset( m_nSkillSuperAmmorValue, 0, sizeof(m_nSkillSuperAmmorValue) ); CheckDamageVelocity( hHitter ); // ¸Â¾ÒÀ»¶§ ¸®¼ÂÇÒ°Íµé ¸®¼Â MAMovementBase *pMovement = GetMovement(); if( pMovement ) { pMovement->ResetMove(); pMovement->ResetLook(); } if( !m_HitParam.szActionName.empty() ) { #ifdef PRE_FIX_81750 CDnChangeStandActionBlow::ReleaseStandChangeSkill( GetActorHandle(), true ); #endif SetActionQueue( m_HitParam.szActionName.c_str(), 0, 3.f, 0.f, false ); } } else { int nDelay = (int)( nSuperAmmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) ); if( nDelay > 0 ) { SetPlaySpeed( (DWORD)( nSuperAmmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) ), 0.03f ); if( m_HitParam.hWeapon && m_HitParam.hWeapon->GetEquipType() != CDnWeapon::Arrow ) { #ifdef PRE_FIX_HITSTIFF // ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°ú°¡ ¿ì¼± 󸮴ë»óÀ̹ǷΠ»óÅÂÈ¿°ú Àû¿ëÁßÀ̶ó¸é SetPlaySpeed() ÇÔ¼ö ¹«½Ã. if( false == (0 < hHitter->GetFrameStopRefCount() || hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 )) ) { hHitter->SetPlaySpeed( 100, 0.03f ); } #else hHitter->SetPlaySpeed( 100, 0.03f ); #endif // #ifdef PRE_FIX_HITSTIFF } } m_HitParam.szActionName.clear(); } } break; case CDnWeapon::Defense: m_HitParam.vVelocity *= 0.5f; m_HitParam.vVelocity.y = 0.f; if( m_HitParam.hWeapon && m_HitParam.hWeapon->GetEquipType() != CDnWeapon::Arrow ) { //#ifdef PRE_FIX_HITSTIFF // ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°ú°¡ ¿ì¼± 󸮴ë»óÀ̹ǷΠ»óÅÂÈ¿°ú Àû¿ëÁßÀ̶ó¸é SetPlaySpeed() ÇÔ¼ö ¹«½Ã. if( false == (0 < hHitter->GetFrameStopRefCount() || hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 )) ) { hHitter->SetPlaySpeed( 100, 0.03f ); } //#else // hHitter->SetPlaySpeed( 100, 0.03f ); //#endif // #ifdef PRE_FIX_HITSTIFF } CheckDamageVelocity( hHitter ); // ¿¡´µ ½Ã۱¸ if( !m_HitParam.szActionName.empty() ) SetActionQueue( m_HitParam.szActionName.c_str(), 0, 3.f, 0.f, false ); break; } // OutputDebug( "µ¥¹ÌÁö : %s, %.2f, %.2f ( %.2f, %.2f )\n", m_HitParam.szActionName.c_str(), m_HitParam.vVelocity.y, m_HitParam.vResistance.y, GetVelocity() ? GetVelocity()->y :0.f, GetResistance() ? GetResistance()->y : 0.f); // ¹«±â ¼Ò¸®, ÆÄƼŬ µîÀ» ó¸®Çϱâ À§ÇØ ÄÝÇØÁØ´Ù. if( m_HitParam.hWeapon ) { m_HitParam.hWeapon->OnHitSuccess( GetMySmartPtr(), HitType, m_HitParam.vPosition, m_HitParam.bFirstHit ); if( HitParam.hWeapon->GetWeaponType() & CDnWeapon::Projectile ) { CDnProjectile *pProjectile = static_cast(HitParam.hWeapon.GetPointer()); if( pProjectile ) pProjectile->OnDamageSuccess( GetMySmartPtr(), m_HitParam ); else HitParam.hWeapon->SetDestroy(); } } // ½ºÅ³ ½ÃÀüÁß Çǰݽà ½ºÅ³ Ãë¼Ò. if( false == m_HitParam.szActionName.empty() ) { // ½ºÅ³ ¾×¼Ç Áß Çǰݽà ½ºÅ³ Ãë¼Ò¿¡ ´ëÇÑ °ÍÀº IsProcessSkill() ·Î üũÇÏÁö ¾Ê°í °´Ã¼ÀÇ Á¸Àç À¯¹«¸¸ üũÇÑ´Ù. // IsFinished() ·Î ³»ºÎ¿¡¼­ üũÇϸé PlayAniProcess ³»ºÎ¿¡¼­ GetCurrentAction() ÀÌ ¾×¼Ç Å¥ °ªÀ» ¿ì¼±Çؼ­ // ¾ò¾î¿À±â ¶§¹®¿¡ À§¿¡¼­ Çǰݾ׼ÇÀÌ SetActionQueue·Î ¼ÂÆÃµÇ¸é ½ºÅ³ÀÌ ³¡³­ °ÍÀ¸·Î ÆÇ´ÜµÇ¾î ¾Æ·¡ ±¸¹®ÀÌ ½ÇÇàµÇÁö ¾Ê´Â´Ù. if( m_hProcessSkill ) { // ¿À¶ó ½ºÅ³ ½ÃÀü Áß.. ±×·¯´Ï±î »óÅÂÈ¿°ú ´Ù µé¾î°¡±â ÀÌÀü¿¡ Ÿ°ÝµÇ¾ú´Ù¸é ¿À¶ó ½ºÅ³ÀÌ ¿ÂÀüÈ÷ »ç¿ëµÈ °ÍÀÌ ¾Æ´Ô if( IsEnabledAuraSkill() && m_hProcessSkill->IsAuraOn() ) { //#41352 ¿À¶ó ½ºÅ³ Ãë¼ÒµÉ¶§ Ŭ¶óÀÌ¾ðÆ®·Î Ãë¼Ò ÆÐŶÀ» Àü¼ÛÇØ¾ßÇÔ.. CmdFinishAuraSkill(m_hAuraSkill->GetClassID()); OnSkillAura( m_hAuraSkill, false ); m_hProcessSkill.Identity(); OutputDebug( "### ¿À¶ó½ºÅ³ ÇǰݴçÇØ¼­ ĵ½½µÊ!!\n" ); } else { m_hCanceledSkill = m_hProcessSkill; m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.f ); m_hProcessSkill.Identity(); } } } // ÇöÀç ¿ÀÅä ÆÐ½Ãºê ½ºÅ³Àº ÇǰݵǾúÀ» ¶§ ¹Û¿¡ ¹ßµ¿µÉ ¶§°¡ ¾øÀ½. UseAutoPassiveSkill( 0, 0.0f ); if( hHitter ) hHitter->OnHitSuccess( CDnActionBase::m_LocalTime, GetMySmartPtr(), pHitStruct ); #ifdef PRE_ADD_EXPORT_DPS_INFORMATION if( CDnDPSReporter::IsActive() && hHitter && hHitter->IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast( hHitter.GetPointer()); if(CDnDPSReporter::GetInstance().IsEnabledUser(pPlayerActor->GetCharacterDBID())) { DNVector(DnActorHandle) hVecList; ScanActor( GetRoom(), *hHitter->GetPosition() , 500.f , hVecList ); CDnDPSReporter::GetInstance().ApplyAreaMonsterCount( (int)hVecList.size() ); CDnDPSReporter::GetInstance().ApplyBaseData( &m_HitParam , fDPS_DAMAGE ); CDnDPSReporter::GetInstance().ApplyTargetData(GetActorHandle()); CDnDPSReporter::GetInstance().EndReport(); } } #endif } void CDnActor::RequestDamage( CDnDamageBase *pHitter, int nSeed, INT64 nDamage ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); char cHitterType = pHitter->GetDamageObjectType(); DWORD dwUniqueID = pHitter->GetDamageObjectUniqueID(); ASSERT( dwUniqueID != -1 && "À߸øµÈ DamageBase ¾ÆÀ̵ð" ); bool bSendWeaponSerialID = false; DWORD dwWeaponUniqueID = -1; INT64 nWeaponSerialID = -1; int nActionIndex = GetElementIndex( m_HitParam.szActionName.c_str() ); if( m_HitParam.hWeapon ) { if( m_HitParam.hWeapon->GetSerialID() == -1 ) dwWeaponUniqueID = m_HitParam.hWeapon->GetUniqueID(); else { bSendWeaponSerialID = true; nWeaponSerialID = m_HitParam.hWeapon->GetSerialID(); } } INT64 nCurrentHP = GetHP(); Stream.Write( &nSeed, sizeof(int) ); Stream.Write( &cHitterType, sizeof(char) ); Stream.Write( &dwUniqueID, sizeof(DWORD) ); Stream.Write( &bSendWeaponSerialID, sizeof(bool) ); if( bSendWeaponSerialID ) Stream.Write( &nWeaponSerialID, sizeof(INT64) ); else Stream.Write( &dwWeaponUniqueID, sizeof(DWORD) ); Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Write( &nDamage, sizeof(INT64) ); Stream.Write( &nCurrentHP, sizeof(INT64) ); // ÀÏ´Ü ³Ö¾î³ñ´Ï´Ù. Stream.Write( &m_HitParam.HitType, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( ( GetVelocity() ) ? GetVelocity() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( ( GetResistance() ) ? GetResistance() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( &m_HitParam.vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( &EtVec3toVec2(m_HitParam.vViewVec), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Write( &m_HitParam.bFirstHit, sizeof(bool) ); //Stream.Write( &m_HitParam.nBoneIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Write( &m_fStiffDelta, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10000.f ); Stream.Write( &m_fDownDelta, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 1000.f ); Stream.Write( &m_HitParam.nSuperAmmorDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Write( &m_HitParam.bSuccessNormalDamage, sizeof(bool) ); Stream.Write( &m_HitParam.DistanceType, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); // #32722 Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ½ºÅ³ »ç¿ëÇÑ´Ù´Â ÆÐŶÀÌ µµÂøÇϱâ Àü¿¡ ¼­¹ö¿¡¼­ ÇÇ°ÝµÉ °æ¿ì Ŭ¶óÀÌ¾ðÆ®¸¸ ½ºÅ³ ¾×¼ÇÀÌ Äµ½½µÇ´Â °Í ¼öÁ¤. int iCanceledSkillID = 0; if( IsPlayerActor() ) { if( m_hCanceledSkill ) { iCanceledSkillID = m_hCanceledSkill->GetClassID(); m_hCanceledSkill.Identity(); } else if( IsDie() ) // ½ºÅ³ ¾²´Ù°¡ Á×Àº °æ¿ì¿£ CanceledSkillID ¸¦ -1 ·Î º¸³»Á༭ Ŭ¶óÂÊ¿¡¼­ ¾Ë ¼ö ÀÖµµ·Ï ÇÑ´Ù. { iCanceledSkillID = -1; } } Stream.Write( &iCanceledSkillID, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); ////////////////////////////////////////////////////////////////////////// // Àӽà // ToDo : ÁØ¿µ¾¾²²¼­ ³ªÁß¿¡ ºÁÁÖ¼Å¾ß ÇÔ. Àӽ÷Π¾ÈÁ×°Ô¸¸ ¸·¾ÆµÒ. int nSuperArmorValue = 0; // Ç÷¹À̾îÀÇ ½´ÆÛ¾Æ¸Ó°¡ 33000 ±îÁö µÇ´Â °æ¿ì°¡ ÀÖ¾î ¾ÐÃàÇÏÁö ¾Ê°í ¼­¹ö¿¡¼­ º¸³À´Ï´Ù. (#10065) Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int) ); Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nLastUpdateSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int) ); //Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); //Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nLastUpdateSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); // Combo ½ÌÄí Stream.Write( &m_HitParam.HasElement, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); #if defined( PRE_ADD_LOTUSGOLEM ) Stream.Write( &m_HitParam.bIgnoreShowDamage, sizeof(bool) ); #endif // #if defined( PRE_ADD_LOTUSGOLEM ) #ifdef PRE_ADD_STAGE_LIMIT_INTERFACE Stream.Write( &m_HitParam.bStageLimit, sizeof(bool) ); #endif switch( pHitter->GetDamageObjectType() ) { case DamageObjectTypeEnum::Actor: { DnActorHandle hActor = pHitter->GetActorHandle(); if( !hActor ) break; if( dwUniqueID >= 100000 ) { CDnPlayerActor *pPlayer = ( hActor->IsPlayerActor() ) ? static_cast(hActor.GetPointer()) : NULL; if( !pPlayer ) break; int nComboCount = pPlayer->GetComboCount(); int nComboDelay = pPlayer->GetComboDelay(); Stream.Write( &nComboCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Write( &nComboDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); } // (#11415) À̽´ °ü·Ã, ¼ÒȯµÈ ·¼¸¯ÀÌ °ø°ÝÇÏ´Â °Íµµ ÄÞº¸ Ä«¿îÆ®¿¡ Æ÷ÇÔ½ÃŲ´Ù. // Á÷Á¢ Ç÷¹À̾°Ô¼­ ¼ÒȯµÈ ¸ó½ºÅÍ Å¸ÀÔÀÎÁö ±¸ºÐÇØ¼­ ¸Â´Ù¸é ÆÐŶ¿¡ ½Ç¾î¼­ º¸³½´Ù. // Ŭ¶óÂÊ¿¡¼­µµ ¸¶Âù°¡Áö·Î ÆÇ´Ü. else if( hActor->IsMonsterActor() ) { CDnMonsterActor* pMonsterActor = static_cast(hActor.GetPointer()); // ·¼¸¯(¼Òȯ¸÷)ÀÌ hit ÇßÀ» °æ¿ì ¼ÒȯÇÑ Ç÷¹À̾°Ô ÄÞº¸ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù. (#11415) DnActorHandle hSummonMasterPlayer = pMonsterActor->GetSummonerPlayerActor(); if( hSummonMasterPlayer && hSummonMasterPlayer->IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast(hSummonMasterPlayer.GetPointer()); int nComboCount = pPlayerActor->GetComboCount(); int nComboDelay = pPlayerActor->GetComboDelay(); Stream.Write( &nComboCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Write( &nComboDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); } else if( CDnActorState::Cannon == pMonsterActor->GetActorType() ) { // ´ëÆ÷ ¸ó½ºÅͰ¡ hit ÇßÀ» °æ¿ì ¸¶½ºÅÍ ¾×ÅÍÀÇ ÄÞº¸ Ä«¿îÆ®¸¦ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù. (#25778) CDnCannonMonsterActor* pCannonMonster = static_cast( pMonsterActor ); DnActorHandle hPlayerActor = pCannonMonster->GetMasterPlayerActor(); int nComboCount = 0; int nComboDelay = 0; if( hPlayerActor && hPlayerActor->IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast(hPlayerActor.GetPointer()); int nComboCount = pPlayerActor->GetComboCount(); int nComboDelay = pPlayerActor->GetComboDelay(); } Stream.Write( &nComboCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Write( &nComboDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); } } } break; case DamageObjectTypeEnum::Prop: break; } OnDamageWriteAdditionalPacket( &Stream ); Send( eActor::SC_ONDAMAGE, &Stream ); // #31022 Â÷Á® »óÅÂÈ¿°ú¿¡¼­ µ¹¸° ¾×¼ÇÀÇ hit ½Ã±×³Î·Î ¸ÂÀº °æ¿ì ¸¶Áö¸· µ¥¹ÌÁö·Î ±â·ÏÇÏÁö ¾Ê´Â´Ù. // È­¿° »óÅÂÈ¿°ú¿¡¼­ ÆÛ°¡¼­ ¾²´Âµ¥ ¿µÇâÀ» ÁÖÁö ¾Ê±â À§ÇØ.. DnActorHandle hHitter = pHitter->GetActorHandle(); if( hHitter && false == hHitter->IsOnSignalFromChargerSE() ) m_iLastDamage = nDamage; } void CDnActor::OnRequestHPMPDelta( /*IN OUT*/ INT64& nHPMPDelta, const DWORD dwHitterUniqueID, bool bIsMPDelta /* = false */ ) { if( false == bIsMPDelta && 0 < nHPMPDelta ) { // 141¹ø Ä¡·áºñÀ²º¯°æ »óÅÂÈ¿°ú. if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_141 ) ) { DNVector(DnBlowHandle) vlBlows; float fValue = 1.0f; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_141, vlBlows ); for( int i = 0; i < (int)vlBlows.size(); ++i ) { DnBlowHandle hBlow = vlBlows.at( i ); fValue += (hBlow->GetFloatValue() - 1.0f); } nHPMPDelta = INT64((float)nHPMPDelta * fValue); } } } // ¼­¹öÂÊ HP/MP ´Â ¹Ù²îÁö ¾ÊÀ¸¹Ç·Î ¹Ýµå½Ã µû·Î ¼­¹öÀÇ HPµµ Á¶ÀýÇØÁÙ °Í! #ifdef PRE_FIX_77172 void CDnActor::RequestHPMPDelta( ElementEnum eElement, INT64 nHPMPDelta, const DWORD dwHitterUniqueID, bool bIsMPDelta /*= false */, bool bShowValue, CDnDamageBase::SHitParam* pHitParam/* = NULL*/, bool bKeepJumpMovement /*=false*/ ) #else // PRE_FIX_77172 void CDnActor::RequestHPMPDelta( ElementEnum eElement, INT64 nHPMPDelta, const DWORD dwHitterUniqueID, bool bIsMPDelta /*= false */, bool bShowValue, CDnDamageBase::SHitParam* pHitParam/* = NULL*/ ) #endif // PRE_FIX_77172 { OnRequestHPMPDelta( nHPMPDelta, dwHitterUniqueID, bIsMPDelta ); #if defined(PRE_FIX_59680) //¼­¸Õ ÆÛÆêÀÇ TransmitDamageBlow(51)¿¡ ÀÇÇØ¼­ Á¤»óÀûÀÎ Hit½Ã±×³Î 󸮰¡ ¾ÈµÇ´Â °æ¿ì RecoverHPByAttack(248) »óÅÂÈ¿°ú°¡ Á¤»ó 󸮵ÇÁö ¾Ê´Â Çö»ó ¹ß»ýµÊ. //51¹ø »óÅÂÈ¿°ú¿¡¼­ ÁÖÀÎ ¾×ÅÍ·Î µ¥¹ÌÁö 󸮸¦ ÀÌÂÊ ÇÔ¼ö È£Ãâ·Î Çϴµ¥, ¿©±â¼­ HitParam°ª¿¡ µ¥¹ÌÁö¸¦ ¼³Á¤ ÇØ ³õ¾Æ¾ß 248¹ø »óÅÂÈ¿°ú¿¡¼­ Á¤»óÀûÀ¸·Î //HPȸº¹À» ÇÒ ¼ö ÀÖ´Ù.(248¹ø »óÅÂÈ¿°ú¿¡¼­ TargetActor°¡ SummonMonsterÀÏ °æ¿ì ÁÖÀÎ ¾×ÅÍÀÇ HitParam Á¤º¸¸¦ ¾ò¾î ¿Í¾ß ÇÔ.) if (bIsMPDelta == false) { m_HitParam.nCalcDamage = -nHPMPDelta; } #endif // PRE_FIX_59680 BYTE pBuffer[ 32 ]; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &eElement, sizeof(ElementEnum), CPacketCompressStream::INTEGER_CHAR ); Stream.Write( &nHPMPDelta, sizeof(INT64) ); Stream.Write( &dwHitterUniqueID, sizeof(DWORD) ); Stream.Write( &bIsMPDelta, sizeof(bool) ); Stream.Write( &bShowValue, sizeof(bool) ); #if defined(PRE_FIX_59308) int nHitType = pHitParam ? pHitParam->HitType : CDnWeapon::Normal; Stream.Write( &nHitType, sizeof(int) ); #endif // PRE_FIX_59308 #ifdef PRE_FIX_77172 Stream.Write( &bKeepJumpMovement, sizeof(bool) ); #endif // PRE_FIX_77172 Send( eActor::SC_SETHPMP_DELTA, &Stream ); } // È®·ü ¹ßµ¿À¸·Î ¾î¶² ÀÏÀ» ¼öÇàÇÏ´Â »óÅÂÈ¿°ú°¡ ¼­¹ö·ÎºÎÅÍ ¹ßµ¿µÇ¾ú´Ù°í Ŭ¶óÇÑÅ× ¾Ë·ÁÁÜ. ÇöÀç ¼­¹ö¿¡¼­ Ŭ¶ó·Î ½î±â¸¸ ÇÒ¶§ »ç¿ëµÊ. // ÇöÀç ÆäÀÌ¹é ¸¶³ª¿¡¼­ »ç¿ëÁß. void CDnActor::RequestSEProbSuccess( int iSkillID, STATE_BLOW::emBLOW_INDEX eBlowIndex ) { BYTE pBuffer[ 16 ]; CPacketCompressStream Stream( pBuffer, 16 ); Stream.Write( &iSkillID, sizeof(int) ); Stream.Write( &eBlowIndex, sizeof(STATE_BLOW::emBLOW_INDEX) ); Send( eActor::SC_STATEEFFECT_PROB_SUCCESS, &Stream ); } void CDnActor::RequestCooltimeReset( int iSkillID ) { BYTE pBuffer[ 4 ]; CPacketCompressStream Stream( pBuffer, 16 ); Stream.Write( &iSkillID, sizeof(int) ); Send( eActor::SC_COOLTIME_RESET, &Stream ); } bool CDnActor::Compare_PreStateOrder( CDnActor::PreStateStruct &a, CDnActor::PreStateStruct &b ) { return ( a.nOffset < b.nOffset ) ? true : false; } void CDnActorActionStateCache::LoadAction( CDnActor* pActor, const char* szFullPathName, \ std::vector* pVecActionElementList, \ std::vector>& ActionState, \ std::vector>& ActionCustomState, \ std::vector>& CanMoveState ) { // ij½¬ µÇ¾î ÀÖ´Â Á¤º¸°¡ ÀÖ´ÂÁö È®ÀÎ { //CPerformanceLog log("loadaction-cache"); std::map::iterator itor; { ScopeLock lock(m_Lock); itor = m_mRepository.find( szFullPathName ); } if( itor != m_mRepository.end() ) { ActionState.reserve( (*itor).second.VecPreActionState.size() ); ActionCustomState.reserve( (*itor).second.VecPreActionCustomState.size() ); CanMoveState.reserve( (*itor).second.VecPreCanMoveState.size() ); ActionState = (*itor).second.VecPreActionState; ActionCustomState = (*itor).second.VecPreActionCustomState; CanMoveState = (*itor).second.VecPreCanMoveState; return; } } SData data; int nValue = 0; std::vector VecList; CEtActionSignal *pSignal; for( DWORD i=0; i< pVecActionElementList->size(); i++ ) { // STE_State VecList.clear(); for( int j=0; ; j++ ) { nValue = 0; pSignal = pActor->GetSignal( i, STE_State, j ); if( pSignal ) { StateStruct *pStruct = (StateStruct *)pSignal->GetData(); nValue = CDnActorState::s_nActorStateIndex[pStruct->nStateOne] | CDnActorState::s_nActorStateIndex[pStruct->nStateTwo] | CDnActorState::s_nActorStateIndex[pStruct->nStateThree]; } else break; VecList.push_back( CDnActor::PreStateStruct( nValue, pSignal->GetStartFrame() ) ); } if( VecList.empty() ) VecList.push_back( CDnActor::PreStateStruct( nValue, 0 ) ); else std::sort( VecList.begin(), VecList.end(), pActor->Compare_PreStateOrder ); data.VecPreActionState.push_back( VecList ); // STE_CustomState VecList.clear(); for( int j=0; ; j++ ) { nValue = 0; pSignal = pActor->GetSignal( i, STE_CustomState, j ); if( pSignal ) { CustomStateStruct *pStruct = (CustomStateStruct *)pSignal->GetData(); nValue = CDnActorState::s_nActorStateIndex[pStruct->nStateOne] | CDnActorState::s_nActorStateIndex[pStruct->nStateTwo] | CDnActorState::s_nActorStateIndex[pStruct->nStateThree]; } else break; VecList.push_back( CDnActor::PreStateStruct( nValue, pSignal->GetStartFrame() ) ); } if( VecList.empty() ) VecList.push_back( CDnActor::PreStateStruct( nValue, 0 ) ); else std::sort( VecList.begin(), VecList.end(), pActor->Compare_PreStateOrder ); data.VecPreActionCustomState.push_back( VecList ); // STE_CanMove VecList.clear(); for( int j=0; ; j++ ) { nValue = 0; pSignal = pActor->GetSignal( i, STE_CanMove, j ); if( pSignal ) { CanMoveStruct *pStruct = (CanMoveStruct *)pSignal->GetData(); nValue = pStruct->bCanMove; } else break; VecList.push_back( CDnActor::PreStateStruct( nValue, pSignal->GetStartFrame() ) ); } if( VecList.empty() ) VecList.push_back( CDnActor::PreStateStruct( nValue, 0 ) ); else std::sort( VecList.begin(), VecList.end(), pActor->Compare_PreStateOrder ); data.VecPreCanMoveState.push_back( VecList ); } // ij½¬Á¤º¸ ±â·Ï { ScopeLock lock(m_Lock); m_mRepository.insert( std::make_pair(szFullPathName, data) ); } ActionState.reserve( data.VecPreActionState.size() ); ActionCustomState.reserve( data.VecPreActionCustomState.size() ); CanMoveState.reserve( data.VecPreCanMoveState.size() ); ActionState = data.VecPreActionState; ActionCustomState = data.VecPreActionCustomState; CanMoveState = data.VecPreCanMoveState; } bool CDnActor::LoadAction( const char *szFullPathName ) { bool bResult = CDnActionBase::LoadAction( szFullPathName ); if( !bResult ) return false; CDnActorActionStateCache::GetInstance().LoadAction( this, szFullPathName, m_pVecActionElementList, m_VecPreActionState, m_VecPreActionCustomState, m_VecPreCanMoveState ); return bResult; } void CDnActor::FreeAction() { CDnActionBase::FreeAction(); SAFE_DELETE_VEC( m_VecPreActionState ); } void CDnActor::LinkWeapon( int nEquipIndex ) { switch( m_hWeapon[nEquipIndex]->GetEquipType() ) { case CDnWeapon::Sword: case CDnWeapon::Axe: case CDnWeapon::Hammer: case CDnWeapon::SmallBow: case CDnWeapon::BigBow: case CDnWeapon::CrossBow: case CDnWeapon::Staff: case CDnWeapon::Book: case CDnWeapon::Orb: case CDnWeapon::Puppet: case CDnWeapon::Mace: case CDnWeapon::Flail: case CDnWeapon::Wand: case CDnWeapon::Shield: case CDnWeapon::Gauntlet: m_hWeapon[nEquipIndex]->LinkWeapon( GetMySmartPtr(), nEquipIndex ); break; case CDnWeapon::Arrow: m_hWeapon[nEquipIndex]->LinkWeapon( GetMySmartPtr(), m_hWeapon[0] ); break; } } void CDnActor::AttachWeapon( DnWeaponHandle hWeapon, int nEquipIndex, bool bDelete ) { #if defined(PRE_ADD_50907) if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_237)) { if (IsChangeWeaponLock() == true) { //¹«±â ÇØÁ¦ »óÅÂÈ¿°ú°¡ Àû¿ë µÈ ½ÃÁ¡Àε¥ ¹«±â ÀåÂøÀÌ µÇ´Â °æ¿ì¶ó¸é ÀÌ ½ÃÁ¡¿¡ º¯°æÀº ¾ÈµÇµµ·Ï ½ºÅµÇϰí, //OrigWeapon ¹«±â Á¤º¸¸¦ °»½ÅÇÑ´Ù. SetOrigWeaponWhenDisarmament(hWeapon, bDelete); return; } } #endif // PRE_ADD_50907 if( m_hWeapon[nEquipIndex] ) { DetachWeapon( nEquipIndex ); } m_hWeapon[nEquipIndex] = hWeapon; m_bSelfDeleteWeapon[nEquipIndex] = bDelete; m_hWeapon[nEquipIndex]->CreateObject(); LinkWeapon( nEquipIndex ); #if defined(PRE_ADD_50907) if (IsSkipOnAttatchDetachWeapon() == true) return; #endif // PRE_ADD_50907 MASkillUser::OnAttachWeapon( m_hWeapon[ nEquipIndex ], nEquipIndex ); } void CDnActor::DetachWeapon( int nEquipIndex ) { if( !m_hWeapon[nEquipIndex] ) return; #if defined(PRE_ADD_50907) if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_237)) { if (IsChangeWeaponLock() == true) return; } #endif // PRE_ADD_50907 m_hWeapon[nEquipIndex]->FreeObject(); m_hWeapon[nEquipIndex]->UnlinkWeapon(); if( m_bSelfDeleteWeapon[nEquipIndex] ) { SAFE_RELEASE_SPTR( m_hWeapon[nEquipIndex] ); m_bSelfDeleteWeapon[nEquipIndex] = false; } m_hWeapon[nEquipIndex].Identity(); #if defined(PRE_ADD_50907) if (IsSkipOnAttatchDetachWeapon() == true) return; #endif // PRE_ADD_50907 MASkillUser::OnDetachWeapon( m_hWeapon[ nEquipIndex ], nEquipIndex ); } void CDnActor::ShowWeapon( int nEquipIndex, bool bShow ) { if( m_hWeapon[nEquipIndex] ) m_hWeapon[nEquipIndex]->ShowWeapon( bShow ); } bool CDnActor::IsStay( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Stay ) ? true : false; return false; } bool CDnActor::IsMove( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Move ) ? true : false; return false; } bool CDnActor::IsAttack( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Attack ) ? true : false; return false; } bool CDnActor::IsHit( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Hit ) ? true : false; return false; } bool CDnActor::IsAir( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Air ) ? true : false; return false; } bool CDnActor::IsDown( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Down ) ? true : false; return false; } bool CDnActor::IsStun( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Stun ) ? true : false; return false; } bool CDnActor::IsStiff( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Stiff ) ? true : false; return false; } bool CDnActor::IsFly( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionCustomState[nIndex][0].nState & ActorCustomStateEnum::Custom_Fly ) ? true : false; return false; } bool CDnActor::IsGround( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionCustomState[nIndex][0].nState & ActorCustomStateEnum::Custom_Ground ) ? true : false; return false; } bool CDnActor::IsStandHit( const char *szActionName ) { int nIndex; int nState = 0; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) nState = m_VecPreActionState[nIndex][0].nState; else return false; if( nState == ActorStateEnum::Hit || nState == ( ActorStateEnum::Hit | ActorStateEnum::Stiff ) ) return true; return false; } int CDnActor::GetState( const char *szActionName ) { int nIndex; if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return m_VecPreActionState[nIndex][0].nState; return 0; } int CDnActor::GetState( int nElementIndex ) { if( nElementIndex < 0 || nElementIndex >= (int)m_VecPreActionState.size() ) return 0; return m_VecPreActionState[nElementIndex][0].nState; } // SetPlaySpeed ¿Í´Â º°°³·Î ÇÁ·¹ÀÓ º¯°æ, ÇÁ·¹ÀÓ Á¤Áö »óÅÂÈ¿°ú°¡ Begin/End µÉ ¶§ ¸¶´Ù ¾÷µ¥ÀÌÆ® µÇ´Â ÇÔ¼öÀÌ´Ù. // Àû¿ëµÈ ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°úÀÇ °ªµéÀ» ¸ð¾Æ ÇѲ¨¹ø¿¡ °ªÀ» ´õÇØ¼­ ¼ÂÆÃÇØÁØ´Ù. // FrameStop »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é ¾Æ¿¹ 0 ÇÁ·¹ÀÓÀ¸·Î ó¸®. // ¸¸¾à »óÅÂÈ¿°ú°¡ ºñ¾îÀÖ´Ù¸é 60 ÇÁ·¹ÀÓÀ¸·Î º¹±¸½ÃÄÑÁØ´Ù. // SetPlaySpeed ¿Í´Â º°°³·Î µ¹¾Æ°¡Áö¸¸ ProcessPlaySpeed() ¿¡¼­ Á¾·áµÈ ÈÄ¿¡ ÀÌ ÇÔ¼ö¸¦ Çѹø ´õ È£ÃâÇØ¼­ »óÅÂÈ¿°úµé·Î // ¿µÇâÀ» ¹Þ´Â ÃÖÁ¾ ÇÁ·¹ÀÓÀ» ´Ù½Ã ¾÷µ¥ÀÌÆ® ÇØÁÖ¾î¾ß ÇÑ´Ù. µû¶ó¼­ »óÅÂÈ¿°úÂÊ¿¡¼­´Â SetPlaySpeed ÇÔ¼ö¸¦ »ç¿ëÇØ¼­´Â ¾ÈµÈ´Ù. void CDnActor::UpdateFPS( void ) { // ÇÁ¶ø ¾×ÅÍ´Â process ¸¦ µ¹Áö ¾Ê±â ¶§¹®¿¡ playspeed Á¶ÀýÇÏ¸é ¾ÈµÈ´Ù. #26354 if( ActorTypeEnum::PropActor == GetActorType() ) return; float fFrameRatio = 1.0f; if( m_bModifyPlaySpeed ) { fFrameRatio = m_fPlaySpeed; float fPrevFPS = CDnActionBase::m_fFPS; CDnActionBase::SetFPS( 60.f * fFrameRatio ); for( DWORD i=0; iGetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * fPrevFPS; // »õ·Î Àû¿ëµÉ ÇÁ·¹ÀÓ ½ºÇǵå·Î RemainTime Àç °è»ê. m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / ( CDnActionBase::m_fFPS) * 1000.f ) ); } } } else { ResetPlaySpeed(); // ÇÁ·¹ÀÓ Á¤Áö »óÅÂÈ¿°ú. Çϳª¶óµµ °É·ÁÀÖ´Ù¸é ¸ðµç ÇÁ·¹ÀÓ Á¤Áö. if( 0 < GetFrameStopRefCount() ) { float fPrevFPS = CDnActionBase::m_fFPS; CDnActionBase::SetFPS( 0.0f ); fFrameRatio = 0.0f; } else if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 ) || IsAppliedThisStateBlow( STATE_BLOW::BLOW_144 ) || IsAppliedThisStateBlow( STATE_BLOW::BLOW_220) ) { #ifdef PRE_ADD_SLOW_DEBUFF_LIMIT float fBuffFrameRatio = 0.0f; #endif // PRE_ADD_SLOW_DEBUFF_LIMIT // ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°úµéÀÇ °ªÀ» ¸ð¾Æ¼­ Àû¿ë. DNVector( DnBlowHandle ) vlhFrameBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_025, vlhFrameBlows ); for( int i = 0; i < (int)vlhFrameBlows.size(); ++i ) { DnBlowHandle hBlow = vlhFrameBlows.at( i ); #ifdef PRE_ADD_SLOW_DEBUFF_LIMIT if( hBlow->GetAddBlowStateType() == AddBlowStateType::Equip_Buff_Level ) fBuffFrameRatio += hBlow->GetFloatValue(); else fFrameRatio += hBlow->GetFloatValue(); #else // PRE_ADD_SLOW_DEBUFF_LIMIT fFrameRatio += hBlow->GetFloatValue(); #endif // PRE_ADD_SLOW_DEBUFF_LIMIT } // #27320 µ¿»ó »óÅÂÈ¿°úµµ ÇÁ·¹ÀÓ ´À·ÁÁüÀÇ È¿°ú°¡ ÀÖ´Ù. vlhFrameBlows.clear(); GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_144, vlhFrameBlows ); for( int i = 0; i < (int)vlhFrameBlows.size(); ++i ) { DnBlowHandle hBlow = vlhFrameBlows.at( i ); #ifdef PRE_ADD_SLOW_DEBUFF_LIMIT if( hBlow->GetAddBlowStateType() == AddBlowStateType::Equip_Buff_Level ) fBuffFrameRatio += static_cast(hBlow.GetPointer())->GetFrameBlowArg(); else fFrameRatio += static_cast(hBlow.GetPointer())->GetFrameBlowArg(); #else // PRE_ADD_SLOW_DEBUFF_LIMIT fFrameRatio += static_cast(hBlow.GetPointer())->GetFrameBlowArg(); #endif // PRE_ADD_SLOW_DEBUFF_LIMIT } vlhFrameBlows.clear(); GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_220, vlhFrameBlows ); for( int i = 0; i < (int)vlhFrameBlows.size(); ++i ) { DnBlowHandle hBlow = vlhFrameBlows.at( i ); #ifdef PRE_ADD_SLOW_DEBUFF_LIMIT if( hBlow->GetAddBlowStateType() == AddBlowStateType::Equip_Buff_Level ) fBuffFrameRatio += hBlow->GetFloatValue(); else fFrameRatio += hBlow->GetFloatValue(); #else // PRE_ADD_SLOW_DEBUFF_LIMIT fFrameRatio += hBlow->GetFloatValue(); #endif // PRE_ADD_SLOW_DEBUFF_LIMIT } #ifdef PRE_ADD_SLOW_DEBUFF_LIMIT if( GetGameRoom() && GetGameRoom()->bIsPvPRoom() ) { if( fBuffFrameRatio < CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Min ) ) fBuffFrameRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Min ); else if( fBuffFrameRatio > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Max ) ) fBuffFrameRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Max ); } fFrameRatio += fBuffFrameRatio; #endif // PRE_ADD_SLOW_DEBUFF_LIMIT if( fFrameRatio < 0.0f ) fFrameRatio = 0.0f; float fPrevFPS = CDnActionBase::m_fFPS; CDnActionBase::SetFPS( 60.0f * fFrameRatio ); for( DWORD i=0; iGetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * fPrevFPS; // »õ·Î Àû¿ëµÉ ÇÁ·¹ÀÓ ½ºÇǵå·Î RemainTime Àç °è»ê. m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / ( CDnActionBase::m_fFPS ) * 1000.f ) ); } } } else { fFrameRatio = 1.0f; float fPrevFPS = CDnActionBase::m_fFPS; // ¿ø»óº¹±¸ CDnActionBase::SetFPS( 60.0f ); for( DWORD i=0; iGetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * fPrevFPS; if( m_hVecLastHitListByRemainTime[i] ) m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / ( CDnActionBase::m_fFPS ) * 1000.f ) ); } } m_hVecLastHitListByRemainTime.clear(); } } if( IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast(this); pPlayerActor->OnChangePlaySpeed( 0, fFrameRatio ); } } void CDnActor::AddedFrameStop( void ) { ++m_iFrameStopRefCount; // #28345 ¸ó½ºÅÍÀÎ °æ¿ì AI ¸¦ ²¨ÁÖÁö ¾ÊÀ¸¸é ÇÁ·¹ÀÓ ¸ØÃçÁø µ¿¾È ¾×¼ÇÀÌ »õ·Î ¼ÂÆÃµÇ¸é¼­ // 0 ÇÁ·¹ÀÓÀ¸·Î ¹Ù²î¾î¹ö¸®´Â ¹®Á¦°¡ »ý±è. if( IsMonsterActor() ) { static_cast(this)->SetAIState( MAAiReceiver::Disable, false ); } UpdateFPS(); }; void CDnActor::RemovedFrameStop( void ) { m_iFrameStopRefCount--; if( m_iFrameStopRefCount < 0 ) m_iFrameStopRefCount = 0; // #28345 ¸ó½ºÅÍÀÎ °æ¿ì AI ¸¦ ²¨ÁÖÁö ¾ÊÀ¸¸é ÇÁ·¹ÀÓ ¸ØÃçÁø µ¿¾È ¾×¼ÇÀÌ »õ·Î ¼ÂÆÃµÇ¸é¼­ // 0 ÇÁ·¹ÀÓÀ¸·Î ¹Ù²î¾î¹ö¸®´Â ¹®Á¦°¡ »ý±è. if( IsMonsterActor() ) { if( 0 == m_iFrameStopRefCount ) { static_cast(this)->SetAIState( MAAiReceiver::Threat, false ); } } UpdateFPS(); }; void CDnActor::SetPlaySpeed( DWORD dwFrame, float fSpeed ) { //// ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°ú°¡ ¿ì¼± 󸮴ë»óÀ̹ǷΠ»óÅÂÈ¿°ú Àû¿ëÁßÀ̶ó¸é SetPlaySpeed() ÇÔ¼ö ¹«½Ã. //if( 0 < GetFrameStopRefCount() || IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 ) ) // return; if( m_bModifyPlaySpeed == true ) return; // ÇÁ¶ø ¾×ÅÍ´Â process ¸¦ µ¹Áö ¾Ê±â ¶§¹®¿¡ playspeed Á¶ÀýÇÏ¸é ¾ÈµÈ´Ù. #26354 if( ActorTypeEnum::PropActor == GetActorType() ) return; m_bModifyPlaySpeed = true; m_PlaySpeedStartTime = CDnActionBase::m_LocalTime; m_dwPlaySpeedTime = dwFrame; m_fPlaySpeed = fSpeed; UpdateFPS(); } void CDnActor::ProcessPlaySpeed( LOCAL_TIME LocalTime, float fDelta ) { if( m_bModifyPlaySpeed == false ) return; if( m_PlaySpeedStartTime == 0 ) m_PlaySpeedStartTime = LocalTime; if( LocalTime - m_PlaySpeedStartTime > m_dwPlaySpeedTime ) { //m_bModifyPlaySpeed = false; // ResetPlaySpeed ÇÔ¼ö ³»ºÎ¿¡¼­ È£ÃâµÊ. ResetPlaySpeed(); UpdateFPS(); return; } } // #15065 À̽´ °ü·Ã. // °áºù ½Ã ÇÁ·¹ÀÓ ¸ØÃß´Â °Í SetPlaySpeed ÇÔ¼ö È£ÃâÇÒ ¶§ ÀÌ¹Ì Å¸°Ý¶§¹®¿¡ Àá±ñ PlaySpeed Á¶Á¤µÇ´Â ŸÀ̹ÖÀÏ ¶§°¡ À־ // ÇÔ¼öÈ£ÃâÀÌ ¾ÃÈú ¶§°¡ ÀÖ´Ù. CDnFreezingBlow::OnBegin() ¿¡¼­ SetPlaySpeed() È£ÃâÇϱâ Àü¿¡ ¸®¼Â½Ã۰í È£ÃâÇÑ´Ù. void CDnActor::ResetPlaySpeed() { if( m_bModifyPlaySpeed == false ) return; for( DWORD i=0; iGetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * CDnActionBase::m_fFPS; m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / 60.f * 1000.f ) ); } } CDnActionBase::SetFPS( 60.f ); if( IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast(this); pPlayerActor->OnChangePlaySpeed( 0, 60.0f / CDnActionBase::m_fFPS ); } // Note: SignalEndTime ÀÌ º¹±¸ ½ÃÄÑÁØ ³ðµéÀº ¿©±â¼­ ³¯¸³´Ï´Ù. //m_hVecLastHitListByRemainTime.clear(); m_bModifyPlaySpeed = false; } void CDnActor::SyncClassTime( LOCAL_TIME LocalTime ) { CDnActionBase::m_LocalTime = LocalTime; MASkillUser::m_LocalTime = LocalTime; } void CDnActor::OnClash( EtVector3 &vPosition, OnClashFloorCheckType bFloorClash ) { if( !IsDie() && IsHit() && ( IsAir() || IsDown() ) && !IsStun() ) { float fDecrease = 0.85f; if( GetVelocity()->x != 0.f ) { SetVelocityX( -GetVelocity()->x * fDecrease ); SetResistanceX( -GetResistance()->x ); } if( GetVelocityValue()->z < -120.f ) { float fVelocityValue = GetVelocityValue()->z; // ÀÏÁ¤ ÀÌ»óÀÇ Ãæ°ÝÀÏ °æ¿ì¿¡´Â »è°¨ÇØÁØ´Ù. Áö±Ý»óÅ¿¡¼± 300 ÀÌ ÃÖÀû.. if( fVelocityValue < -300.f ) fVelocityValue = -300.f; float fYVel = 5.f + ( -fVelocityValue * 0.01f ); // if( fYVel > 8.f ) fYVel = 8.f; // if( fVelocityValue > // OutputDebug( "PrevVel Z : %.2f PrevVel Y : %.2f - %.2f\n", GetVelocity()->z, GetVelocity()->y, GetVelocityValue()->z ); SetVelocityZ( -GetVelocity()->z * ( 1.35f - ( 1.f / 4.f * ( -fVelocityValue * 0.01f ) ) ) ); SetResistanceZ( -GetResistance()->z ); SetVelocityY( fYVel ); SetResistanceY( -18.f ); // OutputDebug( "Vel Z : %.2f Vel Y : %.2f\n", GetVelocity()->z, GetVelocity()->y ); // OutputDebug( "Res Z : %.2f Res Y : %.2f\n", GetResistance()->z, GetResistance()->y ); EtVector3 vLook; vLook = -m_Cross.m_vZAxis; vLook.y = 0.f; EtVec3Normalize( &vLook, &vLook ); Look( EtVector2( vLook.x, vLook.z ) ); if( IsDie() ) SetActionQueue( "Die_Air", 0, 0.f ); else SetActionQueue( "Hit_AirUp", 0, 0.f ); if( m_HitParam.hWeapon ) { m_HitParam.hWeapon->OnHitSuccess( GetMySmartPtr(), CDnWeapon::Stun, vPosition, true ); } } else { if( GetVelocity()->z != 0.f ) { SetVelocityZ( -GetVelocity()->z * fDecrease ); SetResistanceZ( -GetResistance()->z ); } } } } bool CDnActor::IsHittable( DnActorHandle hHitter, LOCAL_TIME LocalTime, HitStruct *pHitSignal, int iHitUniqueID /*= -1*/ ) { #if !defined( _FINAL_BUILD ) if( bIsIgnoreHit() ) return false; #endif // #if !defined( _FINAL_BUILD ) bool isSelfCheck = false; isSelfCheck = pHitSignal ? (pHitSignal->isSelfCheck?true:false) : false; //ÀڽŠüũ°¡ ¼³Á¤µÇ¾î ÀÖÁö ¾ÊÀ»¶§¸¸(false°¡ ±âº». ƯÁ¤(¿Î½º ½ºÅ³...)¿¡¼­¸¸ true·Î ¼³Á¤. //true·Î ¼³Á¤µÇ¾î ÀÖÀ¸¸é Àڽŵµ Hitó¸®.. if (false == isSelfCheck) if( hHitter == GetMySmartPtr() ) return false; if( IsDie() ) return false; CDnActorState::ActorTypeEnum actorType = GetActorType(); if( actorType == CDnActorState::Npc ) return false; //ActorType [0:All/1:User/2:Monster] if (pHitSignal) { switch(pHitSignal->nActorType) { case 1: //User(Àû¿ë ´ë»óÀÌ À¯ÀúÀε¥ ÇöÀç actor°¡ À¯Àú°¡ ¾Æ´Ï¶ó¸é) { if (!IsPlayerActor()) return false; } break; case 2: //Monster(Àû¿ë ´ë»óÀÌ ¸ó½ºÅÍ Àε¥ ¸ó½ºÅͰ¡ ¾Æ´Ï¶ó¸é) { if (!IsMonsterActor()) return false; } break; } } if( GetLastDamageHitUniqueID( hHitter->GetUniqueID() ) != -1 ) { if( GetLastDamageHitUniqueID( hHitter->GetUniqueID() ) == iHitUniqueID ) if( GetDamageRemainTime( hHitter->GetUniqueID() ) >= LocalTime ) return false; } else if( GetDamageRemainTime( hHitter->GetUniqueID() ) >= LocalTime ) { bool bIsChangedByInputAction = false; // #69997 ÀÌÀü ¾×¼Ç¿¡¼­ ¹ß»ýÇÑ È÷Æ®½Ã±×³ÎÀÌ ´ÙÀ½¾×¼Ç¿¡µµ ¿µÇâÀ» ¹ÌÄ¡´Â ºÎºÐ ¼öÁ¤. if( m_nLastDamageHitterActionIndex > 0 && m_nLastDamageHitterActionIndex != hHitter->GetCurrentActionIndex() ) { if( hHitter->GetProcessSkill() ) { bIsChangedByInputAction = hHitter->GetProcessSkill()->IsChainInputAction( hHitter->GetCurrentAction() ); } } if( bIsChangedByInputAction == false && hHitter->IsOnSignalFromChargerSE() == false ) { return false; } } // hit ½Ã±×³Î ±¸°£°ú ÆÀ¸¸ Á¦´ë·Î üũµÈ´Ù¸é 149¹ø ¾óÀ½°¨¿Á »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é ¹«Á¶°Ç ¸Âµµ·Ï µÈ´Ù. // if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_149 ) && pHitSignal ) { //¾óÀ½°¨¿ÁÀÌ´õ¶óµµ »óÅÂÈ¿°ú ÇÊÅͰ¡ Àû¿ë µÇ¾î ÀÖÀ¸¸é ¸ÕÀú ÇÊÅÍ Àû¿ë üũ if( pHitSignal->StateEffectFilter != 0 ) { // ÇöÀç ¿¤¸®¸àÅ»·ÎµåÀÇ ¾ÆÀ̽à ÇÁ·¢¼Ç¿¡¼­¸¸ ¿¹¿ÜÀûÀ¸·Î 2°¡ÁöÀÇ »óÅÂÈ¿°ú ÇÊÅ͸µÀ» °É°í Àִµ¥ // µÑ Áß¿¡ Çϳª¸¸ hit µÇ±æ ¿øÇϱ⠶§¹®¿¡ ¸ÕÀú üũµÈ °ÍÀº ´ÙÀ½ ÇÊÅ͸µ¿¡ °É¸®Áö ¾Êµµ·Ï ÇÑ´Ù. #28747 // ¿¹¿Ü Á¶°Ç¿¡ °É¸®Áö ¾ÊÀ¸¸é ÀϹÝÀûÀ¸·Î ó¸®ÇÔ. if( false == hHitter->CheckHitSignalStateEffectFilterException( GetUniqueID(), pHitSignal->StateEffectFilter) ) { return false; } else if( false == m_pStateBlow->IsApplied( (STATE_BLOW::emBLOW_INDEX)pHitSignal->StateEffectFilter ) ) { return false; } } int nOriginalTeam = GetOriginalTeam(); int nHitterTeam = hHitter->GetTeam(); //¾óÀ½ °¨¿Á »óÅ¿¡¼­´Â Àû¿¡°Ô´Â ¸ÂÀ¸¸é ¾ÈµÇ°í, ¾Æ±º¿¡°Ô´Â ¸Â¾Æ¾ß ÇÑ´Ù.?? if (nOriginalTeam != nHitterTeam) return false; else { //Àû¿¡°Ô ¶§¸®´Â °æ¿ì Àε¥.. ÀڽŠÀ̶ó¸é if (pHitSignal->nTargetType == 0 && GetMySmartPtr() == hHitter->GetMySmartPtr() ) return false; //¾óÀ½ °¨¿Á »óÅ¿¡¼­´Â ¾Æ±º¿¡°Ô´Â ¹«Á¶°Ç ¸Â¾Æ¾ß ÇÑ´Ù.. return true; } } ////////////////////////////////////////////////////////////////////////// // ignorecanhit °¡ ²¨Á®ÀÖ°í ¹«Àû »óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é ¸ÂÁö ¾Ê´Â´Ù. if( pHitSignal ) { if( pHitSignal->bIgnoreCanHit == TRUE ) { DNVector(DnBlowHandle) vBlows; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_099, vBlows ); for( int i = 0; i < (int)vBlows.size(); ++i ) { if( vBlows[i]->GetFloatValue() == -1 ) return false; } } else if( m_pStateBlow->IsApplied(STATE_BLOW::BLOW_099) ) { return false; } #if !defined(PRE_FIX_73833) // ¹«°Ô°ª Á¦ÇÑ °ªÀÌ ÀÖ´Ù¸é ÁöÁ¤µÈ ¹«°Ô°ª ÀÌÇϰ¡ µÇ¾úÀ» ¶§¸¸ ¸Â´Â´Ù. if( 0 < pHitSignal->nWeightValueLimit ) { if( (float)pHitSignal->nWeightValueLimit < GetWeight() ) return false; } #endif } else if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_099 ) ) return false; if( hHitter->GetProcessSkill() ) { bool bResist = false; if( !IsHittableSkill( hHitter->GetProcessSkill()->GetClassID() , bResist ) ) { if( bResist ) { SendAddSEFail( CDnStateBlow::ADD_FAIL_BY_IMMUNE , STATE_BLOW::BLOW_154 ); } return false; } } #if defined(PRE_ADD_50923) //¹«Àû »óÅÂÈ¿°ú Typeº° Àû¿ëÀÌ µÇ¾î ÀÖÀ¸¸é if ( m_pStateBlow->IsApplied(STATE_BLOW::BLOW_239)) { DNVector(DnBlowHandle) vResult; m_pStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_239, vResult); //¹«Àû Type °ªµéÀ» ¸®½ºÆ®·Î ´ã¾Æ ³õ´Â´Ù. std::map invincibleTypeList; for( UINT i=0 ; i(hBlow.GetPointer()); if (NULL == pInvincibleTypeBlow) continue; int nInvincibleTypeValue = pInvincibleTypeBlow->GetInvincibleTypeValue(); invincibleTypeList.insert(std::make_pair(nInvincibleTypeValue, nInvincibleTypeValue)); } if (hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_240)) { DNVector(DnBlowHandle) vResultImmunByType; CDnStateBlow *pHitterStateBlow = hHitter->GetStateBlow(); if (pHitterStateBlow) pHitterStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_240, vResultImmunByType); for( UINT i=0 ; i(hBlow.GetPointer()); if (NULL == pImmuneTypeBlow) continue; int nImmuneTypeValue = pImmuneTypeBlow->GetImmuneTypeValue(); std::map::iterator findIter = invincibleTypeList.find(nImmuneTypeValue); if (findIter != invincibleTypeList.end()) invincibleTypeList.erase(findIter); } //¹«Àû Type ¹«½Ã »óÅÂÈ¿°ú·Î ÀüºÎ Á¦°Å°¡ µÇ¾î¾ß HitµÉ ¼ö ÀÖ´Ù. //¸®½ºÆ®°¡ ³²¾Æ ÀÖ´Ù¸é ¹«½Ã »óÅÂÈ¿°ú°¡ ¾øÀ¸¹Ç·Î HitµÉ ¼ö ¾ø´Ù. if (invincibleTypeList.empty() == false) return false; } //¹«Àû »óÅÂÈ¿°ú Type ¹«½Ã »óÅÂÈ¿°ú°¡ Hitter¿¡ Àû¿ë µÇ¾î ÀÖÁö ¾ÊÀ¸¸é HitµÉ ¼ö ¾ø´Ù. else return false; } #endif // PRE_ADD_50923 // ¾×¼ÇÅø¿¡¼­ »óÅÂÈ¿°ú ÇÊÅ͸µÀÌ ÁöÁ¤µÇ¾îÀÖÀ¸¸é üũÇÑ´Ù. if( pHitSignal ) { #ifdef PRE_ADD_HITDIRECTION EtVector3 vDir = *GetPosition() - *hHitter->GetPosition(); EtVec3Normalize( &vDir, &vDir ); switch( pHitSignal->CheckHitDirection ) { // front case 1: { // ÇǰÝÀÚ°¡ ¶§¸° ³ðÀ» ¹Ù¶óº¸°í ÀÖ´Â °æ¿ì hit ó¸®. float fDot = EtVec3Dot( &vDir, &(m_Cross.m_vZAxis) ); if( fDot >= -0.1f ) // ¹üÀ§´Â ÇǰÝÀÚ(ÀϹÝÀûÀÎ °æ¿ì Ç÷¹À̾î)¿¡°Ô À¯¸®ÇÏ°Ô ¼³Á¤. return false; } break; // back case 2: { // ÇǰÝÀÚ°¡ ¶§¸° ³ðÀ» µîÁö°í ÀÖ´Â °æ¿ì hit ó¸®. float fDot = EtVec3Dot( &vDir, &(m_Cross.m_vZAxis) ); if( fDot < 0.1f ) return false; } break; } #endif // #ifdef PRE_ADD_HITDIRECTION #if defined(PRE_ADD_57090) ////////////////////////////////////////////////////////////////////////// //#57090 ƯÁ¤ ´ë»óÀÌ °ø°Ý´çÇÏÁö ¾Ê°Ô ÇÏ´Â ±â´É - ¼³Á¤µÈ »óÅÂÈ¿°ú°¡ Àû¿ë µÇ¾î ÀÖÀ¸¸é È÷Æ® µÇÁö ¾ÊÀ½. //StateEffectFilterº¸´Ù ¿ì¼± °Ë»ç... std::vector vlTokens; string strArgument = pHitSignal->szUnStateEffectFilter ? pHitSignal->szUnStateEffectFilter : ""; TokenizeA( strArgument, vlTokens, ";" ); if (vlTokens.empty() == false) { int nTokenSize = (int)vlTokens.size(); for (int i = 0; i < nTokenSize; ++i) { STATE_BLOW::emBLOW_INDEX emBlowIndex = (STATE_BLOW::emBLOW_INDEX)atoi(vlTokens[i].c_str()); if( true == m_pStateBlow->IsApplied( emBlowIndex ) ) { return false; } } } ////////////////////////////////////////////////////////////////////////// #endif // PRE_ADD_57090 if( pHitSignal->StateEffectFilter != 0 ) { // ÇöÀç ¿¤¸®¸àÅ»·ÎµåÀÇ ¾ÆÀ̽à ÇÁ·¢¼Ç¿¡¼­¸¸ ¿¹¿ÜÀûÀ¸·Î 2°¡ÁöÀÇ »óÅÂÈ¿°ú ÇÊÅ͸µÀ» °É°í Àִµ¥ // µÑ Áß¿¡ Çϳª¸¸ hit µÇ±æ ¿øÇϱ⠶§¹®¿¡ ¸ÕÀú üũµÈ °ÍÀº ´ÙÀ½ ÇÊÅ͸µ¿¡ °É¸®Áö ¾Êµµ·Ï ÇÑ´Ù. #28747 // ¿¹¿Ü Á¶°Ç¿¡ °É¸®Áö ¾ÊÀ¸¸é ÀϹÝÀûÀ¸·Î ó¸®ÇÔ. if( false == hHitter->CheckHitSignalStateEffectFilterException( GetUniqueID(), pHitSignal->StateEffectFilter) ) { return false; } else if( false == m_pStateBlow->IsApplied( (STATE_BLOW::emBLOW_INDEX)pHitSignal->StateEffectFilter ) ) { return false; } } #ifdef PRE_ADD_MONSTER_CATCH // ¸ó½ºÅÍ¿¡ ÀâÈù°ÇÁö üũÇÏ´Â Ç÷¡±×°¡ ÄÑÁ® ÀÖ´Ù¸é ¸ó½ºÅÍ¿¡°Ô ÀâÈù °æ¿ì¸¸ ±¸ºÐ. if( TRUE == pHitSignal->bIsCatchedActor ) { if( IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast(this); if( false == pPlayerActor->IsCatchedByMonster() ) { return false; } } } #endif // #ifdef PRE_ADD_MONSATER_CATCH // ÁÖº¯¿¡ ³»°¡ ¼ÒȯÇÑ ·¼¸¯ ¸ó½ºÅÍÀÎÁö ¾Æ´ÑÁö ±¸ºÐÇØÁÜ. ¼îÅ© ¿Àºê ·¼¸¯ ½ºÅ³¿¡¼­ »ç¿ëÇÔ. if( TRUE == pHitSignal->bUseMyRelicFilter ) { bool bIsMyRelicMonster = hHitter->IsMyRelicMonster( GetMySmartPtr() ); if( bIsMyRelicMonster ) return true; else return false; } // #13885 À̽´ °ü·Ã. int nTargetType = pHitSignal->nTargetType; if( hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_086 ) ) { // ÆÀ ¹ÝÀü »óÅÂÈ¿°ú Çϳª¸¸ Àû¿ëµÈ´Ù. DNVector( DnBlowHandle ) vlReverseTeamBlows; hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_086, vlReverseTeamBlows ); _ASSERT( false == vlReverseTeamBlows.empty() ); if( false == vlReverseTeamBlows.empty() ) { DnBlowHandle hBlow = vlReverseTeamBlows.front(); CDnReverseTeamBlow* pReverseTeamBlow = static_cast(hBlow.GetPointer()); if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_CHANGE == pReverseTeamBlow->GetType() ) { switch( nTargetType ) { case 0: // Enemy -> Friend nTargetType = 1; break; case 1: // Friend -> Enemy { // #50166 Æø¹ß°ü·Ã ½Ã±×³ÎÀº ±âÁ¸»óŸ¦ À¯ÁöÇϵµ·Ï ÇÑ´Ù. if(pHitSignal->fDamageProb > 0) nTargetType = 1; else nTargetType = 0; } break; case 2: // All -> All { // #51871 À̽´°ü·Ã All ŸÀÔÀÏ °æ¿ì¿¡µµ µ¥¹ÌÁö°¡ Àִ°æ¿ì ¿µÇâÀ» ³¢Ä¡Áö ¾Êµµ·Ï ¼³Á¤ÇÕ´Ï´Ù. if(pHitSignal->fDamageProb > 0) nTargetType = 1; } break; } } else if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_ALL == pReverseTeamBlow->GetType() ) { // Ÿ°Ý´ë»ó all ·Î ¹Ù²ãÁÜ. nTargetType = 2; } } } switch( nTargetType ) { case 0: // Enemy if( GetTeam() == hHitter->GetTeam() ) return false; if( GetMySmartPtr() == hHitter->GetMySmartPtr() ) return false; if( false == pHitSignal->bIgnoreCanHit && false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_138 ) ) { if( !CDnActorState::IsHittable() ) return false; } break; case 1: // Friend if( GetTeam() != hHitter->GetTeam() ) return false; #ifdef PRE_FIX_63315 // #63315 - TargetType ÀÌ Friend ÀÏ °æ¿ì¿¡µµ Hittable °Ë»çÇϵµ·Ï Ãß°¡. if( false == pHitSignal->bIgnoreCanHit && false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_138 ) ) { if( !CDnActorState::IsHittable() ) return false; } #endif // PRE_FIX_63315 break; case 2: // All // CanHit ½Ã±×³ÎÀÌ false ÀÏ ¶§ hit ½Ã±×³Î targettype ÀÌ all ÀÌ¶óµµ Àû±ºÀº hit µÇÁö ¾Êµµ·Ï ¼öÁ¤. (#10570) if( GetTeam() != hHitter->GetTeam() ) { // Hit ½Ã±×³Î¿¡ CanHit ¹«½ÃÇÏ´Â Ç÷¡±× ÄÑÁ® ÀÖÀ¸¸é ¹«Á¶°Ç ¸ÂÀ» ¼ö ÀÖ´Â »óÅ·ΠÆÇ´Ü. // 138¹ø »óÅÂÈ¿°ú °É·ÈÀ» ¶§µµ ¸¶Âù°¡Áö. (#19619) if( false == pHitSignal->bIgnoreCanHit && false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_138 ) ) { if( !CDnActorState::IsHittable() ) return false; } } break; } switch( pHitSignal->nStateCondition ) { case 0: // Normal if( GetState() == CDnActorState::Down ) return false; break; case 1: // Down if( !( GetState() & CDnActorState::Down ) ) return false; break; case 2: // Normal + Down break; case 3: // All break; } } return true; } bool CDnActor::IsHittableSkill( int iSkillIndex , bool &bSendResist ) { // ƯÁ¤ ½ºÅ³¿¡ ´ëÇÑ ¹«Àû ó¸® [2010/11/22 semozz] if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_154 ) ) { DNVector(DnBlowHandle) vResult; m_pStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_154, vResult); for( UINT i=0 ; i(hBlow.GetPointer()); if ( pInvincibleAtBlow && pInvincibleAtBlow->IsInvincibleAt(iSkillIndex) ) { bSendResist = pInvincibleAtBlow->IsEnableSendResist(); return false; } } } } return true; } void CDnActor::Show( bool bShow ) { m_bShow = bShow; } void CDnActor::ResetActor() { Show( true ); m_fDownDelta = 0.f; m_fDieDelta = 0.f; m_fStiffDelta = 0.f; m_mapLastDamageTime.clear(); m_mapLastHitUniqueID.clear(); m_nLastDamageHitterActionIndex = 0; m_LastHitSignalTime = 0; m_nLastHitSignalIndex = -1; m_bModifyPlaySpeed = false; m_PlaySpeedStartTime = 0; m_dwPlaySpeedTime = 0; m_bEnableNormalSuperAmmor = false; m_nNormalSuperAmmorTime = 0; m_fBreakNormalSuperAmmorDurability = 0.f; // CDnActionBase::SetFPS( 60.f ); CDnActionBase::ResetActionBase(); MAActorRenderBase::ResetActorRenderBase(); ResetMove(); ResetLook(); SetVelocity( EtVector3( 0.f, 0.f, 0.f ) ); SetResistance( EtVector3( 0.f, 0.f, 0.f ) ); SetAddHeight( 0.f ); SetMagnetLength( 0.f ); SetMagnetDir( EtVector2( 0.f, 0.f ) ); m_vlForceSettedHitElement.clear(); if( IsCustomAction() ) ResetCustomAction(); SetActionQueue( "Stand", 0, 0.f, 0.f, false, false ); } void CDnActor::ProcessCollision( EtVector3 &vMove ) { m_pMovement->PushAndCollisionCheck( vMove ); } void CDnActor::ProcessState( LOCAL_TIME LocalTime, float fDelta ) { CDnActorState::ProcessState( LocalTime, fDelta ); // #48950 ½´¸Ó¾Æ¸Ó°¡ ±úÁø °æ¿ì¿£ MoveY ½Ã±×³Î °ª ¸®¼ÂÇØÁØ´Ù. if( IsHit() ) { ResetMoveYDistance(); } if( m_pStateBlow && false == IsNpcActor() ) { m_pStateBlow->Process( LocalTime, fDelta ); ProcessReservedRemoveBlows(); ExecuteKillAfterProcessStateBlow(); } } void CDnActor::SendAddSEFail( int iAddSEResult, STATE_BLOW::emBLOW_INDEX emBlowIndex ) { BYTE pBuffer[ 16 ]; CPacketCompressStream Stream( pBuffer, 16 ); Stream.Write( &iAddSEResult, sizeof(int) ); Send( eActor::SC_ADD_STATE_EFFECT_DENIED, &Stream ); } void CDnActor::PushSummonMonster( DnMonsterActorHandle hMonster, const SummonMonsterStruct* pSummonMonsterStruct, bool bReCreateFollowStageMonster/* = false*/ ) { //if( bReCreateFollowStageMonster ) // return; if( 0 == pSummonMonsterStruct->nGroupID ) { m_listSummonMonster.push_back( hMonster ); } } bool CDnActor::bIsCanSummonMonster( const SummonMonsterStruct* pSummonMonsterStruct ) { // 0 ÀÌ¸é °³Ã¼¼ö Á¦ÇÑÀ» ÇÏÁö ¾Ê°Ú´Ù´Â °ÍÀÓ~! if( pSummonMonsterStruct->nMaxCount == 0 ) return true; // ±×·ì ID °¡ Á¤ÀǵǾî ÀÖ´Ù¸é ±×·ì map ÀÇ ¸®½ºÆ®¸¦ ã¾Æ¼­ ó¸®. int iCount = 0; if( IsPlayerActor() && 0 < pSummonMonsterStruct->nGroupID ) { if( 0 < m_mapSummonMonsterByGroup.count( pSummonMonsterStruct->nGroupID ) ) { std::list& listSummonedGroupMonster = m_mapSummonMonsterByGroup[ pSummonMonsterStruct->nGroupID ]; for( std::list::iterator itor=listSummonedGroupMonster.begin(); itor!=listSummonedGroupMonster.end(); ) { DnMonsterActorHandle hMonster = *itor; if( hMonster ) { ++iCount; ++itor; } else itor = listSummonedGroupMonster.erase( itor ); } if( iCount < pSummonMonsterStruct->nMaxCount ) return true; } else return true; } else { for( std::list::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end() ; ) { DnMonsterActorHandle hMonster = *itor; if( hMonster ) { if( hMonster->GetMonsterClassID() == pSummonMonsterStruct->MonsterID ) ++iCount; ++itor; } else itor = m_listSummonMonster.erase( itor ); } if( iCount < pSummonMonsterStruct->nMaxCount ) return true; } return false; } int CDnActor::AddStateBlow( STATE_BLOW::emBLOW_INDEX emBlowIndex, const CDnSkill::SkillInfo* pParentSkill, int nDurationTime, const char *szParam, bool bOnPlayerInit/* = false*/, bool bCheckCanBegin/* = true*/ , bool bEternity /*=false*/ ) { // ºÎȰ Á¦¿ÜÇϰí Á×¾úÀ» ¶© »óÅÂÈ¿°ú Ãß°¡ ¾ÈµÊ // PvP ¶ó¿îµå¸ðµå ¶ó¿îµå Àç½ÃÀ۽à Á×Àº»óÅ¿¡¼­ »óÅÂÈ¿°ú¸¦ °É¾îÁÙ¶§ bOnPlayerInit = true ·Î ³Ñ¾î¿Í¼­ Die üũ ¾ÈÇÔ. by ±è¹ä if( false == bOnPlayerInit ) if( IsDie() && STATE_BLOW::emBLOW_INDEX::BLOW_057 != emBlowIndex ) return -1; if( !m_pStateBlow ) return -1; int iAddSEResult = m_pStateBlow->CanAddThisBlow( pParentSkill, emBlowIndex ); switch( iAddSEResult ) { case CDnStateBlow::ADD_FAIL_BY_IMMUNE: { // ½ÇÆÐÇÑ ÀÌÀ¯¿¡ µû¶ó.. SendAddSEFail( iAddSEResult, emBlowIndex ); return -1; } break; case CDnStateBlow::ADD_FAIL_BY_DIED: OutputDebug( "[Add State Effect Failed by die]\n" ); return -1; case CDnStateBlow::ADD_FAIL_BY_INVINCIBLE: OutputDebug( "[Add State Effect Failed by Invincible]\n" ); return -1; case CDnStateBlow::ADD_FAIL_BY_REVIVAL: OutputDebug( "[Add State Effect Failed by Revival blow!]\n" ); return -1; case CDnStateBlow::ADD_FAIL_BY_GUILDBLOW_PRIORITY: return -1; case CDnStateBlow::ADD_FAIL_BY_PROB_SKILL_INVINCIBLE: OutputDebug( "[Add State Effect Failed by Prob Skill Invincible]\n" ); return -1; case CDnStateBlow::ADD_FAIL_BY_COMBOLIMITBLOW: OutputDebug( "[Add State Effect Failed by ComboLimitBlow]\n" ); return -1; } //¼Óµµ¸¦ º¯°æÇÏ´Â È¿°ú Àû¿ëµÉ¶§ AccelÈ¿°ú ÀÌ¹Ì Àû¿ë µÇ¾î ÀÖ´Ù¸é //AccelÈ¿°ú´Â Á¦°Å(STATE_END?)µÈ´Ù.. switch(emBlowIndex) { case STATE_BLOW::BLOW_076: case STATE_BLOW::BLOW_025: case STATE_BLOW::BLOW_144: { if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_220)) { DNVector(DnBlowHandle) vlhFrameBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_220, vlhFrameBlows ); for( int i = 0; i < (int)vlhFrameBlows.size(); ++i ) { DnBlowHandle hBlow = vlhFrameBlows.at(i); if (hBlow) hBlow->SetState(STATE_BLOW::STATE_END); } } } break; } #if defined(PRE_ADD_50923) //240»óÅÂÈ¿°ú´Â Çϳª¾¿¸¸ Àû¿ëµÇ¾î¾ß ÇÑ´Ù. »õ·Î¿î 240¹ø »óÅÂÈ¿°ú°¡ µé¾î ¿À¸é ±âÁ¸°Å //Á¦°Å Çϵµ·ÏÇÑ´Ù. if (emBlowIndex == STATE_BLOW::BLOW_240) { if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_240)) { DNVector(DnBlowHandle) vlhFrameBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_240, vlhFrameBlows ); for( int i = 0; i < (int)vlhFrameBlows.size(); ++i ) { DnBlowHandle hBlow = vlhFrameBlows.at(i); if (hBlow) hBlow->SetState(STATE_BLOW::STATE_END); } } } #endif // PRE_ADD_50923 DnBlowHandle hBlow = m_pStateBlow->CreateStateBlow( GetMySmartPtr(), pParentSkill, emBlowIndex, nDurationTime, szParam ); if( !hBlow ) return -1; // È®·üÀÌ ÀÖ´Â »óÅÂÈ¿°ú´Â È®·ü¿¡ °É¸®¸é »óÅÂÈ¿°ú ¾È °É¸². // Ŭ¶óÂÊ¿¡µµ ¿Ö »óÅÂÈ¿°ú Ãß°¡°¡ ½ÇÆÐÇß´ÂÁö ÀÌÀ¯´Â ¾Ë¾Æ¾ß ÇϹǷΠÀÌÀ¯¸¦ ÆÐŶÀ¸·Î º¸³»ÁÜ. if( bCheckCanBegin && (false == hBlow->CanBegin()) ) { SendAddSEFail( CDnStateBlow::ADD_FAIL_BY_PROBABILITY, emBlowIndex ); //hBlow->Release(); #if defined(PRE_FIX_49208) //#49208 ÀÌ¹Ì Àû¿ëµÈ »óÅÂÈ¿°ú°¡ OnBeginÀÌ È£Ãâ µÈ »óÅ¿¡¼­ DuplicatedµÈ »óÅÂÈ¿°ú¸¦ ¿©±â¿¡¼­ ¹Ù·Î DeleteÇØ ¹ö¸®¸é referenceÄ«¿îÆ®°¡ ¾î±ß³ª°Ô µÊ. if (hBlow->IsDuplicated() == false) #endif // PRE_FIX_49208 SAFE_RELEASE_SPTR( hBlow ); OutputDebug( "[Add State Effect Failed by probability fail!] BlowIndex: %d\n", emBlowIndex ); return -1; } else { if( hBlow->IsDuplicated() ) return hBlow->GetBlowID(); else { hBlow->SetParentSkillInfo( pParentSkill ); //hBlow->SetParentSkillID( iParentSkillID ); //hBlow->SetParentSkillLevelID( iParentSkillLevelID ); // ¹«Àû »óÅÂÈ¿°ú µé¾î°¡¸é µ¶, ºÒ »óÅÂÈ¿°ú´Â Á¦°ÅÇÑ´Ù.. if( hBlow->GetBlowIndex() == STATE_BLOW::BLOW_099 ) { // È­»ó°ú Áßµ¶ »óÅÂÈ¿°ú¸¦ Á¦°Å. if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_042 ) || IsAppliedThisStateBlow( STATE_BLOW::BLOW_044 ) ) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_042, vlBlows ); GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_044, vlBlows ); for( int i = 0; i < (int)vlBlows.size(); ++i ) { DnBlowHandle hBlow = vlBlows.at( i ); int iBlowID = hBlow->GetBlowID(); CmdRemoveStateEffectFromID( iBlowID ); } } } hBlow->SetEternity( bEternity ); return m_pStateBlow->AddStateBlow( hBlow ); } } } void CDnActor::DelStateBlow( STATE_BLOW::emBLOW_INDEX emBlowIndex ) { if( !m_pStateBlow ) return; m_pStateBlow->RemoveStateBlowByBlowDefineIndex( emBlowIndex ); } int CDnActor::RemoveStateBlowByBlowDefineIndex( STATE_BLOW::emBLOW_INDEX emBlowIndex ) { if( !m_pStateBlow ) return -1; return m_pStateBlow->RemoveStateBlowByBlowDefineIndex( emBlowIndex ); } void CDnActor::RemoveStateBlowFromID( int nStateBlowID ) { if( !m_pStateBlow ) return; m_pStateBlow->RemoveStateBlowFromID( nStateBlowID ); } void CDnActor::RemoveAllBlow() { DNVector(DnBlowHandle) vlAppliedStateBlow; GetAllAppliedStateBlow( vlAppliedStateBlow ); int iNumStateBlow = (int)vlAppliedStateBlow.size(); for( int iBlow = 0; iBlow < iNumStateBlow; ++iBlow ) m_pStateBlow->RemoveStateBlowFromID( vlAppliedStateBlow.at( iBlow )->GetBlowID() ); ApplyPassiveSkills(); } void CDnActor::RemoveAllBlowExpectPassiveSkill() { DNVector(DnBlowHandle) vlAppliedStateBlow; GetAllAppliedStateBlow( vlAppliedStateBlow ); int iNumStateBlow = (int)vlAppliedStateBlow.size(); for( int iBlow = 0; iBlow < iNumStateBlow; ++iBlow ) { DnBlowHandle hBlow = vlAppliedStateBlow.at( iBlow ); if( !hBlow ) continue; if( bIsPassiveSkill( hBlow ) ) continue; // ±Ù¿ø ¾ÆÀÌÅÛÀÇ È®·ü ½ºÅ³ ¹«½Ã »óÅÂÈ¿°ú´Â Á׾ ³²¾ÆÀÖ¾î¾ß ÇÑ´Ù. if( IsShouldRemainBlowWhenDie( hBlow ) ) continue; m_pStateBlow->RemoveStateBlowFromID( hBlow->GetBlowID() ); } } bool CDnActor::IsShouldRemainBlowWhenDie( DnBlowHandle hBlow ) { bool bResult = false; if( hBlow ) { if( hBlow->IsFromSourceItem() ) return true; if( hBlow->IsEternity() ) return true; } return bResult; } int CDnActor::GetNumAppliedStateBlow( void ) { return m_pStateBlow->GetNumStateBlow(); } DnBlowHandle CDnActor::GetAppliedStateBlow( int iIndex ) { return m_pStateBlow->GetStateBlow( iIndex ); } bool CDnActor::IsAppliedThisStateBlow( STATE_BLOW::emBLOW_INDEX iBlowIndex ) { if( !m_pStateBlow ) return false; return m_pStateBlow->IsApplied( iBlowIndex ); } void CDnActor::GetAllAppliedStateBlow(DNVector(DnBlowHandle)& /*IN OUT*/ out) { int nSize = m_pStateBlow->GetNumStateBlow(); if( 0 < nSize ) out.reserve( out.capacity() + nSize ); // 20080916 ¼º´É°³¼± for ( int i = 0 ; i < nSize ; i++ ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i); if( hBlow && STATE_BLOW::STATE_END != hBlow->GetBlowState() ) out.push_back(hBlow); } } void CDnActor::GetAllAppliedStateBlowBySkillID(int nSkillID, DNVector(DnBlowHandle)& /*IN OUT*/ out) { int nSize = m_pStateBlow->GetNumStateBlow(); if( 0 < nSize ) out.reserve( out.capacity() + nSize ); // 20080916 ¼º´É°³¼± for ( int i = 0 ; i < nSize ; i++ ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i); if( hBlow ) { const CDnSkill::SkillInfo* pSkillinfo = hBlow->GetParentSkillInfo(); if( pSkillinfo && pSkillinfo->iSkillID == nSkillID && STATE_BLOW::STATE_END != hBlow->GetBlowState() ) { out.push_back(hBlow); } } } } void CDnActor::GatherAppliedStateBlowByBlowIndex( STATE_BLOW::emBLOW_INDEX BlowIndex, DNVector(DnBlowHandle)& /*IN OUT*/ out ) { int iNumStateBlow = m_pStateBlow->GetNumStateBlow(); for( int i = 0; i < iNumStateBlow; ++i ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlow( i ); if( hBlow && hBlow->GetBlowIndex() == BlowIndex && STATE_BLOW::STATE_END != hBlow->GetBlowState() ) out.push_back( hBlow ); } } void CDnActor::OnSkillProjectile( CDnProjectile *pProjectile ) { MASkillUser::OnSkillProjectile( pProjectile ); if( pProjectile ) { if( IsProcessSkill() || IsEnabledToggleSkill() ) { DnSkillHandle hSkill; if( IsProcessSkill() ) hSkill = m_hProcessSkill; else if( IsEnabledToggleSkill() ) hSkill = GetEnabledToggleSkill(); _ASSERT( hSkill && "ÇÁ·ÎÁ§Å¸ÀÏÀ» ½ð ½ºÅ³ÀÌ ¾ø´Ù´Â?" ); pProjectile->SetParentSkill( hSkill ); for( DWORD i = 0; i < hSkill->GetStateEffectCount(); i++ ) { CDnSkill::StateEffectStruct *pStruct = hSkill->GetStateEffectFromIndex(i); if( pStruct->ApplyType == CDnSkill::ApplySelf ) continue; pProjectile->AddStateEffect( *pStruct ); } if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_167 ) ) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_167, vlBlows ); if( false == vlBlows.empty() ) { int iForceSkillLevel = (int)vlBlows.front()->GetFloatValue(); pProjectile->SetSummonMonsterForceSkillLevel( iForceSkillLevel ); } } ////////////////////////////////////////////////////////////////////////// //¾Ö¾î·Î »þ¿ö ½ºÅ³¿¡ »ç¿ëµÉ »óÅÂÈ¿°ú 󸮸¦ À§Çؼ­ ¹ß»çü°¡ »ý¼º µÉ¶§ ÇöÀç ½ºÅ³ÀÌ ½ÃÀü ÁßÀÎ °æ¿ì ÇØ´ç ½ºÅ³¿¡ ¹ß»çü¸¦ ´ã¾Æ ³õ´Â´Ù. //ÇöÀç »ç¿ëÁßÀÎ ½ºÅ³ÀÌ 242»óÅÂÈ¿°ú¸¦ °¡Áö°í ÀÖ´Â ½ºÅ³À̸é if (hSkill) { bool bExistState = false; int nStateEffectCount = hSkill->GetStateEffectCount(); for (int i = 0; i < nStateEffectCount; ++i) { CDnSkill::StateEffectStruct* pSE = hSkill->GetStateEffectFromIndex( i ); if (pSE && (STATE_BLOW::emBLOW_INDEX)pSE->nID == STATE_BLOW::BLOW_242) { bExistState = true; break; } } if (bExistState == true) { LOCAL_TIME skillStartTime = hSkill->GetSkillStartTime(); pProjectile->SetSkillStartTime(skillStartTime); //¹ß»çü¿¡µµ ½ºÅ³ ½ÃÀÛ ½Ã°£À» ¼³Á¤ ÇØ³õ´Â´Ù. hSkill->AddProjectile(pProjectile); } } } #if defined(PRE_FIX_68645) //129¹ø »óÅÂÈ¿°ú°¡ ÀÖ°í, °­Á¦ ¼Ó¼º ¼³Á¤ÀÌ ÀÖ´Â °æ¿ì ¹ß»çü¿¡ ¼³Á¤ ÇØ ³õ´Â´Ù. if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_129 ) ) { DNVector(DnBlowHandle) vlhChangeActionSetBlow; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_129, vlhChangeActionSetBlow ); // ¾×¼Ç ¼Â º¯°æ »óÅÂÈ¿°ú´Â ¿©·¯°³ ÀÖÀ» ¼ö ÀÖ´Ù. int iNumBlow = (int)vlhChangeActionSetBlow.size(); for( int i = 0; i < iNumBlow; ++i ) { if( !vlhChangeActionSetBlow[i] ) continue; CDnChangeActionSetBlow* pChangeActionSetBlow = static_cast( vlhChangeActionSetBlow.at(i).GetPointer() ); if (pChangeActionSetBlow->IsEnable() == true) { CDnChangeActionStrProcessor* pProcessor = pChangeActionSetBlow->GetChangeActionStrProcessor(); // ¾×¼Ç º¯°æ ¹ßÇöŸÀÔÀÌ ºñȰ¼ºÈ­ »óÅÂÀ϶§´Â NULL ¸®ÅϵÊ. if( pProcessor && m_vlForceSettedHitElement.empty() == false) { ElementEnum forceElement = (ElementEnum)m_vlForceSettedHitElement[0]; pProjectile->SetForceHitElement(forceElement); } } } } //////////////////////////////////////////////////////////////////////////////////////////////////// #endif // PRE_FIX_68645 } } void CDnActor::OnInitializeNextStage( void ) { // ÁøÇàÁßÀÎ ÆÐ½Ãºê ¾×¼Ç ½ºÅ³Àº ²¨¹ö¸² if( m_hProcessSkill ) { if( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) && m_hProcessSkill->GetDurationType() == CDnSkill::Instantly ) { m_hProcessSkill->OnEnd( 0, 0.0f ); m_hProcessSkill.Identity(); } } // ÁøÇàÁßÀÎ ¿À¶ó ½ºÅ³ ¿ª½Ã ²¨¹ö¸² if( m_hAuraSkill ) { OnSkillAura( m_hAuraSkill, false ); } // °áºù »óÅÂÈ¿°ú °É·Á ÀÖ´Âä·Î À̵¿µÇ´Â °æ¿ì´Â °ÅÀÇ ¾ø°ÚÁö¸¸ ¸¸¾à ±×·¸´Ù¸é Á¦°ÅÇÔ. if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_041 ) ) m_pStateBlow->RemoveStateBlowByBlowDefineIndex( STATE_BLOW::BLOW_041 ); RemoveNonAvailableStateBlow(); // Note: ¸Ê À̵¿µÉ ¶§ È£ÃâµÊ. ¸¶Áö¸·À¸·Î ¶§·È´ø ³ðµé ¸®½ºÆ®¸¦ À̰÷¿¡¼­ ÃʱâÈ­ÇØÁÖÁö ¾ÊÀ¸¸é ÀÌÀü ½ºÅ×ÀÌÁö¿¡¼­ // ¶§·È´ø ¾ÖµéÀÌ ³²¾ÆÀÖÀ» ¼ö ÀÖ´Ù. ±×·± »óȲ¿¡¼­ Hit ÇÁ·Î¼¼½º°¡ ÇÔ µ¹¾Æ°¡¸é »¶³². m_hVecLastHitList.clear(); m_hVecLastHitListByRemainTime.clear(); m_iCantMoveReferenceCount = 0; m_iCantActionReferenceCount = 0; // ¸¶Áö¸· Ÿ°ÝµÈ È÷Æ®½Ã±×³Î °ü·Ã Á¤º¸ ¾÷µ¥ÀÌÆ® m_mapLastDamageTime.clear(); m_mapLastHitUniqueID.clear(); m_nLastDamageHitterActionIndex = 0; RefreshState(); } // ¿©±â ÇÔ¼ö ³»¿ëÀÌ ¹Ù²î¸é Ŭ¶óÀÌ¾ðÆ®¿¡¼­µµ SC_START_PVPROUND ÆÐŶ 󸮺κРº¯°æµÇ¾î¾ßÇÑ´Ù. void CDnActor::OnInitializePVPRoundRestart( void ) { // ÁøÇàÁßÀÎ ÆÐ½Ãºê ¾×¼ÇÀÌ ÀÖ´Ù¸é Á¾·á. if( m_hProcessSkill ) { if( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) && m_hProcessSkill->GetDurationType() == CDnSkill::Instantly ) { m_hProcessSkill->OnEnd( 0, 0.0f ); m_hProcessSkill.Identity(); } } // ÁøÇàÁßÀÎ AutoPassive ½ºÅ³ Á¾·á. EndAutoPassiveSkill( CDnActionBase::m_LocalTime, 0.0f ); // ¾ÆÀÌÅÛ½ºÅ³ Á¾·á if( m_hItemSkill ) { if( m_hItemSkill->IsFinished() ) { m_hItemSkill->OnEnd( 0, 0.f ); deque::iterator iter = find( m_dqhItemSkillList.begin(), m_dqhItemSkillList.end(), m_hItemSkill ); _ASSERT( m_dqhItemSkillList.end() != iter ); m_dqhItemSkillList.erase( iter ); SAFE_RELEASE_SPTR( m_hItemSkill ); } } // ÁøÇàÁßÀÎ ¿À¶ó ½ºÅ³ÀÌ ÀÖ´Ù¸é Á¾·á. if( m_hAuraSkill ) { OnSkillAura( m_hAuraSkill, false ); } // ÁøÇàÁßÀÎ Åä±Û ½ºÅ³ÀÌ ÀÖ´Ù¸é Á¾·á. if( m_hToggleSkill ) { OnSkillToggle( m_hToggleSkill, false ); } // ¸ðµç »óÅÂÈ¿°ú ¸®¼Â RemoveAllBlowExpectPassiveSkill(); if( IsPlayerActor() ) { CDnPlayerActor *pPlayer = static_cast(this); pPlayer->RemoveAllBubbles( false ); } m_hVecLastHitList.clear(); m_hVecLastHitListByRemainTime.clear(); // ¸¶Áö¸· ¶§·È´ø È÷Æ®½Ã±×³Î Á¤º¸ ¾÷µ¥ÀÌÆ® m_mapLastDamageTime.clear(); m_mapLastHitUniqueID.clear(); m_nLastDamageHitterActionIndex = 0; for( std::list::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end() ; itor++ ) { DnMonsterActorHandle hMonster = *itor; if( hMonster ) hMonster->CmdSuicide( false, false ); } SAFE_DELETE_VEC( m_listSummonMonster ); std::list suicideMonsterList; map >::iterator iter = m_mapSummonMonsterByGroup.begin(); for( iter; iter != m_mapSummonMonsterByGroup.end(); ++iter ) { // Á¦ÇÑ ½Ã°£ ´Ù µÇ¾î È¥ÀÚ »ç¶óÁø ¼Òȯ ¸ó½ºÅÍ´Â ¸®½ºÆ®¿¡ invalidÇÑ Çڵ鸸 ³²¾Æ ÀÖÀ¸¹Ç·Î °¨¾È. list& listSummonedMonsters = iter->second; list::iterator iterList = listSummonedMonsters.begin(); for( iterList; iterList != listSummonedMonsters.end(); ) { if( *iterList ) { DnMonsterActorHandle hMonster = *iterList; //CmdSuicideÇÔ¼ö ³»ºÎ¿¡¼­ PlayerActor::OnDieSummonedMonsterÈ£ÃâµÊ. //ÀÌ ÇÔ¼ö¿¡¼­ m_mapSummonMonsterByGroup/listSummonMonster¸®½ºÆ®¿¡¼­ Á¦°ÅÇÔ. //±×·¡¼­ CmdSuicideµÉ ³à¼®µéÀ» ¸®½ºÆ®¿¡ ´ã¾Æ¼­ ¾Æ·¡ÂÊ¿¡¼­ ó¸® Çϵµ·Ï ÇÔ.. //hMonster->CmdSuicide( false, false ); suicideMonsterList.push_back(hMonster); ++iterList; } else { iterList = listSummonedMonsters.erase( iterList ); } } } //À§¿¡¼­ ¸®½ºÆ®¿¡ ´ã¾Æ ³õÀº CmdSuicideµÉ ³à¼®µé ó¸®ÇÑ´Ù. for( std::list::iterator itor=suicideMonsterList.begin() ; itor!=suicideMonsterList.end() ; itor++ ) { DnMonsterActorHandle hMonster = *itor; if( hMonster ) hMonster->CmdSuicide( false, false ); } m_mapSummonMonsterByGroup.clear(); } void CDnActor::ResetStateEffect( int nSkillDurationType ) { m_pStateBlow->ResetStateBlowBySkillType( nSkillDurationType ); } void CDnActor::ProcessPress() { if( m_nPressLevel == 0 ) return; if( IsDie() ) return; if( IsFly() ) return; if( IsUnderGround() ) return; DNVector(DnActorHandle) hVecList; if( m_iLastProcessPressCount > 0 ) hVecList.reserve( m_iLastProcessPressCount ); EtVector3 vAniDist = *GetPosition(); vAniDist.x -= GetAniDistance()->x; vAniDist.z -= GetAniDistance()->z; float fScanRadius = 0.0f; if( m_Press == Press_Circle ) fScanRadius = (float)GetUnitSize() + 50.f; else if( m_Press == Press_Capsule ) fScanRadius = (float)GetUnitSize()*2.0f + 50.f; int nCount = ScanActor( GetRoom(), vAniDist, fScanRadius, hVecList ); if( nCount > 0 ) { for( int i=0; iIsDie() ) continue; if( hVecList[i]->GetPressLevel() > m_nPressLevel ) continue; if( hVecList[i]->GetPressLevel() == -1 ) continue; if( m_Press == Press_NoneSameCircle && hVecList[i]->m_Press == Press_NoneSameCircle ) continue; ProcessPress( hVecList[i] ); } m_iLastProcessPressCount = nCount; } } void CDnActor::ProcessPress( DnActorHandle hTarget ) { EtVector2 Dir; float Dist = 0.0f; bool bCheckPress = false; if( GetPress() == CDnActorState::Press_Circle && hTarget->GetPress() == CDnActorState::Press_Circle ) { if( CheckPressCircle2Clrcle2( GetMySmartPtr(), hTarget, Dir, Dist ) ) { hTarget->MoveToWorld( Dir * Dist ); bCheckPress = true; } } else if( GetPress() == CDnActorState::Press_Capsule && hTarget->GetPress() == CDnActorState::Press_Capsule ) { if( CheckPressCapsule2Capsule2( GetMySmartPtr(), hTarget, Dir, Dist ) ) { hTarget->MoveToWorld( Dir * Dist ); bCheckPress = true; } } else if( GetPress() == CDnActorState::Press_Capsule && hTarget->GetPress() == CDnActorState::Press_Circle ) { if( CheckPressCapsule2Circle2( GetMySmartPtr(), hTarget, Dir, Dist ) ) { hTarget->MoveToWorld( Dir * Dist ); bCheckPress = true; } } else if( GetPress() == CDnActorState::Press_Circle && hTarget->GetPress() == CDnActorState::Press_Capsule ) { if( CheckPressCapsule2Circle2( hTarget, GetMySmartPtr(), Dir, Dist ) ) { hTarget->MoveToWorld( -Dir * Dist ); bCheckPress = true; } } if( bCheckPress ) { if( hTarget->IsPlayerActor() ) { CDnPlayerActor *pPlayer = (CDnPlayerActor *)hTarget.GetPointer(); if( pPlayer->GetPlayerSpeedHackChecker() ) ((CDnPlayerSpeedHackChecker*)pPlayer->GetPlayerSpeedHackChecker())->SetCheckPress( true, Dist ); } } } bool CDnActor::CheckPressCircle2Clrcle2( DnActorHandle hActor1, DnActorHandle hActor2, EtVector2 &Dir, float &Dist ) { EtVector2 vDir; int nSumSize; vDir = EtVec3toVec2( *hActor2->GetPosition() - *hActor1->GetPosition() ); nSumSize = hActor1->GetUnitSize() + hActor2->GetUnitSize(); float fLength = D3DXVec2Length( &vDir ); if( fLength > (float)nSumSize ) return false; D3DXVec2Normalize( &Dir, &vDir ); Dist = (float)( nSumSize - fLength ); return true; } bool CDnActor::CheckPressCapsule2Capsule2( DnActorHandle hActor1, DnActorHandle hActor2, EtVector2 &Dir, float &Dist ) { // ÀÚ½ÅÀÇ ¿ùµå»ó ĸ½¶¿µ¿ª ±¸Çϰí(Á÷¼±) int nSizeX = hActor1->GetUnitSizeParam1(); int nSizeZ = hActor1->GetUnitSizeParam2(); EtVector3 vCapsule1, vCapsule2; int nSumSize = 0; if( nSizeX < nSizeZ ) { vCapsule1.x = vCapsule2.x = vCapsule1.y = vCapsule2.y = 0.0f; vCapsule1.z = (float)(nSizeZ - nSizeX); vCapsule2.z = -vCapsule1.z; nSumSize += nSizeX; } else { vCapsule1.z = vCapsule2.z = vCapsule1.y = vCapsule2.y = 0.0f; vCapsule1.x = (float)(nSizeX - nSizeZ); vCapsule2.x = -vCapsule1.x; nSumSize += nSizeZ; } EtMatrix matWorld = *hActor1->GetMatEx(); EtVec3TransformCoord( &vCapsule1, &vCapsule1, &matWorld ); EtVec3TransformCoord( &vCapsule2, &vCapsule2, &matWorld ); EtVector2 vLine1, vLine2; vLine1 = EtVec3toVec2( vCapsule1 ); vLine2 = EtVec3toVec2( vCapsule2 ); // Ÿ°ÙÀÇ ¿ùµå»ó ĸ½¶¿µ¿ª ±¸Çϰí(Á÷¼±) int nTargetSizeX = hActor2->GetUnitSizeParam1(); int nTargetSizeZ = hActor2->GetUnitSizeParam2(); EtVector3 vTargetCapsule1, vTargetCapsule2; if( nTargetSizeX < nTargetSizeZ ) { vTargetCapsule1.x = vTargetCapsule2.x = vTargetCapsule1.y = vTargetCapsule2.y = 0.0f; vTargetCapsule1.z = (float)(nTargetSizeZ - nTargetSizeX); vTargetCapsule2.z = -vTargetCapsule1.z; nSumSize += nTargetSizeX; } else { vTargetCapsule1.z = vTargetCapsule2.z = vTargetCapsule1.y = vTargetCapsule2.y = 0.0f; vTargetCapsule1.x = (float)(nTargetSizeX - nTargetSizeZ); vTargetCapsule2.x = -vTargetCapsule1.x; nSumSize += nTargetSizeZ; } EtMatrix matTargetWorld = *hActor2->GetMatEx(); EtVec3TransformCoord( &vTargetCapsule1, &vTargetCapsule1, &matTargetWorld ); EtVec3TransformCoord( &vTargetCapsule2, &vTargetCapsule2, &matTargetWorld ); EtVector2 vTargetLine1, vTargetLine2; vTargetLine1 = EtVec3toVec2( vTargetCapsule1 ); vTargetLine2 = EtVec3toVec2( vTargetCapsule2 ); if( hActor1 == hActor2 ) return false; // Á÷¼±°ú Á÷¼± °Å¸®¸¦ ±¸ÇÑ ÈÄ EtVector2 vPressDir; float fLength = DistLine2DToLine2D( vLine1, vLine2, vTargetLine1, vTargetLine2, vPressDir ); if( fLength > 0.0f ) { // ±³Â÷ÇÏÁö ¾Ê´Â´Ù¸é, PressDirÀÌ Á¦´ë·Î µé¾îÀÖÀ» °ÍÀÌ´Ù. // ±×¸®°í À̶© ÀϹÝÀûÀÎ Á¡°ú Á÷¼±ÀÇ °Å¸®±â ¶§¹®¿¡ SumSize¿Í ºñ±³ÆÇ´ÜÀ» ¼öÇàÇÑ´Ù. if( fLength > (float)nSumSize ) return false; Dir = vPressDir; Dist = (float)( nSumSize - fLength ); } else { // ±³Â÷Çϸé // ù¹øÂ° ¼±ºÐ°ú µÎ¹øÂ° ¼±ºÐÀÇ ¾ç ³¡Á¡À» °¡Áö°í °Å¸®¸¦ Àé ÈÄ EtVector2 vDir1, vDir2; float fDist1 = DistPointToLine2D( vTargetLine1, vLine1, vLine2, vDir1 ); float fDist2 = DistPointToLine2D( vTargetLine2, vLine1, vLine2, vDir2 ); // °Å¸®°¡ ªÀº °ÍÀ» ÀúÀå. ¹æÇâÀº ¹Ý´ë·Î ÀúÀå. if( fDist1 < fDist2 ) { vPressDir = -vDir1; fLength = fDist1; } else { vPressDir = -vDir2; fLength = fDist2; } // ±³Â÷ÇÑ´Ù¸é SumSize¿ÍÀÇ °Å¸®ºñ±³´Â ÇÊ¿ä¾ø´Ù. // ÀÌ¹Ì ±³Â÷µÉÁ¤µµ·Î °ãÃÆ´Ù¸é, ÃּҰŸ®¹ÛÀ¸·Î ¹Ð¾î³»´Â ¹æ¹ý ¿Ü¿£ ¾ø´Ù. Dir = vPressDir; Dist = (float)( nSumSize + fLength ); } return true; } bool CDnActor::CheckPressCapsule2Circle2( DnActorHandle hActor1, DnActorHandle hActor2, EtVector2 &Dir, float &Dist ) { int nSizeX = hActor1->GetUnitSizeParam1(); int nSizeZ = hActor1->GetUnitSizeParam2(); EtVector3 vCapsule1, vCapsule2; int nSumSize; if( nSizeX < nSizeZ ) { vCapsule1.x = vCapsule2.x = vCapsule1.y = vCapsule2.y = 0.0f; vCapsule1.z = (float)(nSizeZ - nSizeX); vCapsule2.z = -vCapsule1.z; nSumSize = nSizeX + hActor2->GetUnitSize(); } else { vCapsule1.z = vCapsule2.z = vCapsule1.y = vCapsule2.y = 0.0f; vCapsule1.x = (float)(nSizeX - nSizeZ); vCapsule2.x = -vCapsule1.x; nSumSize = nSizeZ + hActor2->GetUnitSize(); } EtMatrix matWorld = *hActor1->GetMatEx(); EtVec3TransformCoord( &vCapsule1, &vCapsule1, &matWorld ); EtVec3TransformCoord( &vCapsule2, &vCapsule2, &matWorld ); EtVector2 vLine1, vLine2; vLine1 = EtVec3toVec2( vCapsule1 ); vLine2 = EtVec3toVec2( vCapsule2 ); EtVector2 vTargetPos = EtVec3toVec2( *hActor2->GetPosition() ); EtVector2 vPressDir; float fLength = DistPointToLine2D( vTargetPos, vLine1, vLine2, vPressDir ); if( fLength > (float)nSumSize ) return false; Dir = vPressDir; Dist = (float)( nSumSize - fLength ); return true; } bool CDnActor::bIsObserver() { if( GetGameRoom() && GetGameRoom()->bIsPvPRoom() ) { if( GetTeam() == PvPCommon::Team::Observer ) return true; } return false; } float CDnActor::SquaredDistance( const EtVector3& vPos, const SAABox& BBox, bool bNear ) { float fSQDist = 0.0f; for( int i = 0; i < 3; ++i ) { // y ÃàÀº ¹«½Ã if( 1 == i ) continue; float v = vPos[ i ]; if( bNear ) { if( v < BBox.Min[ i ] ) fSQDist += (BBox.Min[ i ] - v) * (BBox.Min[ i ] - v); if( v > BBox.Max[ i ] ) fSQDist += (v - BBox.Max[ i ]) * (v - BBox.Max[ i ]); } else { if( v > BBox.Min[ i ] ) fSQDist += (BBox.Min[ i ] - v) * (BBox.Min[ i ] - v); if( v < BBox.Max[ i ] ) fSQDist += (v - BBox.Max[ i ]) * (v - BBox.Max[ i ]); } } return fSQDist; } void CDnActor::CmdChangeTeam( int nTeam ) { SetTeam( nTeam ); printf("CDnActor::CmdChangeTeam %d\n",nTeam); char pBuffer[32]; CPacketCompressStream Stream( pBuffer, sizeof(pBuffer) ); Stream.Write( &m_nTeam, sizeof(int) ); Send( eActor::SC_CMDCHANGETEAM, &Stream ); } void CDnActor::OnHitFinish( LOCAL_TIME LocalTime, HitStruct *pStruct ) { if( !pStruct->vSelfVelocity || !pStruct->vSelfResistance ) return; if( GetVelocity() == NULL || GetResistance() == NULL ) return; if( EtVec3LengthSq( pStruct->vSelfVelocity ) == 0.f && EtVec3LengthSq( pStruct->vSelfResistance ) == 0.f ) return; EtVector3 vVelocity = *pStruct->vSelfVelocity; EtVector3 vResistance = *pStruct->vSelfResistance; // y °ªÀÌ ±âÁ¸¿¡ Àִµ¥ ¿©±â¼­ µ¤¾î¾º¿ì¸é ¹®Á¦°¡ »ý±æ¼öÀÖÀ¸¹Ç·Î y ´Â º¸Á¤ÇØÁØ´Ù. if( GetVelocity()->y != 0.f && pStruct->vSelfVelocity->y == 0.f ) { vVelocity.y = GetVelocity()->y; vResistance.y = GetResistance()->y; } CmdForceVelocity( vVelocity, vResistance ); } void CDnActor::CmdForceVelocity( EtVector3 &vVelocity, EtVector3 &vResistance ) { SetVelocity( vVelocity ); SetResistance( vResistance ); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( ( GetVelocity() ) ? GetVelocity() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Write( ( GetResistance() ) ? GetResistance() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Send( eActor::SC_CMDFORCEVELOCITY, &Stream ); } void CDnActor::CmdChatBalloon( LPCWSTR wszMessage ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); int nLength = static_cast(wcslen( wszMessage ) * 2); if( nLength > 120 ) nLength = 120; Stream.Write( &nLength, sizeof(int) ); Stream.Write( wszMessage, nLength ); Send( eActor::SC_CMDCHATBALLOON, &Stream ); } #if defined(PRE_ADD_MULTILANGUAGE) void CDnActor::CmdChatBalloon( int nUIStringIndex ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nUIStringIndex, sizeof(int) ); Send( eActor::SC_CMDCHATBALLOON_AS_INDEX, &Stream ); } #endif //#if defined(PRE_ADD_MULTILANGUAGE) void CDnActor::CmdShowExposureInfo( bool bShow ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &bShow, sizeof(bool) ); Send( eActor::SC_SHOWEXPOSUREINFO, &Stream ); } void CDnActor::CmdForceAddSkill( int nSkillID ) { AddSkill( nSkillID ); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nSkillID, sizeof(int) ); Send( eActor::SC_FORCE_ADD_SKILL, &Stream ); } void CDnActor::CmdForceRemoveSkill( int nSkillId ) { RemoveSkill( nSkillId ); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nSkillId, sizeof(int) ); Send( eActor::SC_FORCE_REMOVE_SKILL, &Stream ); } void CDnActor::OnProjectile( CDnProjectile *pProjectile, ProjectileStruct* pStruct, MatrixEx& LocalCross, int nSignalIndex ) { int iShootActionIndex = GetElementIndex( GetCurrentAction() ); if( -1 != iShootActionIndex ) pProjectile->SetShootActionIndex( iShootActionIndex ); pProjectile->SetSignalArrayIndex( nSignalIndex ); boost::shared_ptr pProjectileStruct = boost::shared_ptr(new ProjectileStruct); #ifdef PRE_FIX_MEMOPT_SIGNALH CopyShallow_ProjectileStruct(*pProjectileStruct, pStruct); #else *pProjectileStruct = *pStruct; #endif pProjectile->SetProjectileSignal( pProjectileStruct ); } void CDnActor::CmdSyncBlow( CDNUserSession* pGameSession ) { for( int i=0 ; iGetParentSkillInfo(); if( !pSkillInfo ) { _DANGER_POINT(); continue; } // #24143 ÆÐ½Ãºê ¹öÇÁ ½ºÅ³ÀÇ »óÅÂÈ¿°úÀÎ °æ¿ì¿£ µ¿±â¸¦ ¸ÂÃßÁö ¾Ê½À´Ï´Ù. // ÆÐ½Ãºê ½ºÅ³Àº Ŭ¶óÀÌ¾ðÆ®°¡ ³­ÀÔÇßÀ» ¶§ ¹Þ°Ô µÇ´Â ´Ù¸¥ À¯ÀúµéÀÇ ½ºÅ³¸®½ºÆ®¸¦ // ÃʱâÈ­ ÇÒ¶§ ÀÚµ¿À¸·Î Àû¿ëµË´Ï´Ù. if( CDnSkill::Passive == pSkillInfo->eSkillType && CDnSkill::Buff == pSkillInfo->eDurationType && CDnSkill::ApplySelf == pSkillInfo->eTargetType ) { continue; } const CPacketCompressStream* pPacket = hBlow->GetPacketStream(); Send( pGameSession, eActor::SC_CMDADDSTATEEFFECT, GetUniqueID(), const_cast(pPacket) ); } } } void CDnActor::OnDie( DnActorHandle hHitter ) { m_fDieDelta = m_fMaxDieDelta; } void CDnActor::UseMP( int iMPDelta ) { int iResult = m_pStateBlow->OnUseMP( iMPDelta ); SetSP( GetSP() + iResult ); RequestHPMPDelta( ElementEnum::ElementEnum_Amount, iResult, UINT_MAX, true ); } void CDnActor::RequestDamageFromStateBlow( DnBlowHandle hFromBlow, int iDamage, CDnDamageBase::SHitParam* pHitParam/* = NULL*/ ) { // ¹«Àû »óÅÂÈ¿°¡ °É·ÁÀÖÀ¸¸é ¹«½Ã. if( hFromBlow && false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_099 ) ) { // ÇÏÀÌ·£´õ »óÅÂÈ¿°ú°¡ ÀÖ´Â °æ¿ì Á×Áö ¾Ê¾Æ¾ß ÇÑ´Ù. float fDamage = (float)iDamage; if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_143 ) ) { // IsAppliedThisStateBlow() ÇÔ¼ö¿¡¼± true °¡ ¸®ÅϵÇÁö¸¸ Áö¼Ó½Ã°£ÀÌ ´Ù µÈ // »óÅÂÈ¿°ú´Â GatherAppliedStateBlowByBlowIndex() ¿¡¼­ ¾ò¾î¿ÍÁöÁö ¾ÊÀ¸¹Ç·Î ¸®½ºÆ®°¡ ºñ¾îÀÖÀ» ¼ö µµ ÀÖ´Ù. DNVector( DnBlowHandle ) vlhHighLanderBlow; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_143, vlhHighLanderBlow ); if( 0 < (int)vlhHighLanderBlow.size() ) { CDnHighlanderBlow* pHighlanderBlow = static_cast(vlhHighLanderBlow.front().GetPointer()); fDamage += pHighlanderBlow->CalcDamage( fDamage ); } } CDnSkill::SkillInfo* pParentSkillInfo = const_cast(hFromBlow->GetParentSkillInfo()); DWORD dwHitterUniqueID = 0; ElementEnum eElement = ElementEnum::ElementEnum_Amount; if( pParentSkillInfo ) { dwHitterUniqueID = pParentSkillInfo->hSkillUser ? pParentSkillInfo->hSkillUser->GetUniqueID() : -1; eElement = pParentSkillInfo->eSkillElement; } if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_243 ) ) { float fAbsorbDamage = 0.f; int nAbsorbSP = 0; DNVector( DnBlowHandle ) vlhManaShieldBlow; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_243, vlhManaShieldBlow ); for( DWORD n=0; n(vlhManaShieldBlow[n].GetPointer()); pManShieldBlow->CalcManaShield( fDamage , fAbsorbDamage , nAbsorbSP ); } if( nAbsorbSP > GetSP() ) { fAbsorbDamage -= (fAbsorbDamage * (nAbsorbSP - GetSP()) / nAbsorbSP); nAbsorbSP = GetSP(); } if( fAbsorbDamage > fDamage ) fAbsorbDamage = fDamage; fDamage -= fAbsorbDamage; SetSP( GetSP() -nAbsorbSP ); RequestHPMPDelta( ElementEnum::ElementEnum_Amount, -nAbsorbSP, UINT_MAX, true , true ); } #if defined(PRE_FIX_59347) //ÆÄÃ÷ ¸ó½ºÅÍ µ¥¹ÌÁö º¸Á¤?À» À§Çؼ­ #ifdef PRE_FIX_67656 ApplyPartsDamage(fDamage, pParentSkillInfo->hSkillUser); #else if (GetApplyPartsDamage() == true) ApplyPartsDamage(fDamage, pParentSkillInfo->hSkillUser); #endif //¼Ó¼º Ç¥½Ã if (pHitParam) eElement = pHitParam->HasElement; #endif // PRE_FIX_59347 SetHP( GetHP()-(INT64)fDamage ); #ifdef PRE_FIX_77172 if( hFromBlow->GetBlowIndex() == STATE_BLOW::BLOW_042 ) RequestHPMPDelta( eElement, -(INT64)fDamage, dwHitterUniqueID, false, true, pHitParam, true ); else RequestHPMPDelta( eElement, -(INT64)fDamage, dwHitterUniqueID, false, true, pHitParam ); #else // PRE_FIX_77172 RequestHPMPDelta( eElement, -(INT64)fDamage, dwHitterUniqueID, false, true, pHitParam ); #endif // PRE_FIX_77172 #ifdef PRE_ADD_EXPORT_DPS_INFORMATION if( CDnDPSReporter::IsActive() && pParentSkillInfo && pParentSkillInfo->hSkillUser && pParentSkillInfo->hSkillUser->IsPlayerActor() ) { CDnPlayerActor* pPlayerActor = static_cast( pParentSkillInfo->hSkillUser.GetPointer()); if(CDnDPSReporter::GetInstance().IsEnabledUser( pPlayerActor->GetCharacterDBID() )) { CDnDPSReporter::GetInstance().StartReport(); DNVector(DnActorHandle) hVecList; ScanActor( GetRoom(), *GetActorHandle()->GetPosition() , 500.f , hVecList ); CDnDPSReporter::GetInstance().ApplyAreaMonsterCount( (int)hVecList.size() ); CDnDPSReporter::GetInstance().ApplyDotDamageData( (int)fDamage , GetActorHandle() , hFromBlow ); CDnDPSReporter::GetInstance().EndReport(); } } #endif } } void CDnActor::CmdFreezingPrisonDurablity(int nStateBlowID, float fDuabilityRate, bool bShowGauge) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nStateBlowID, sizeof(nStateBlowID) ); Stream.Write( &fDuabilityRate, sizeof(fDuabilityRate) ); Stream.Write( &bShowGauge, sizeof(bShowGauge) ); Send( eActor::SC_FREEZINGPRISON_DURABILITY, &Stream ); } void CDnActor::SendRemoveStateEffectFromID( int nID ) { char acBuffer[ 32 ]; CPacketCompressStream Stream( acBuffer, sizeof(acBuffer) ); Stream.Write( &nID, sizeof(nID) ); Send( eActor::SC_CMDREMOVESTATEEFFECTFROMID, &Stream ); } void CDnActor::RemoveResetStateBlow() { // [2010/12/15 semozz] // ÀÌ ÇÔ¼ö È£ÃâÈÄ¿¡ »õ·Î¿î »óÅ ȿ°úµé·Î ´ëüµÇ¾î¾ß Çϱ⶧¹®¿¡ // ¿©±â¼­´Â ¹Ù·Î »óÅ ȿ°úµéÀ» Á¦°Å ÇØ¾ßÇÑ´Ù. std::map::iterator iter = m_vlStateBlowIDToRemove.begin(); for (; iter != m_vlStateBlowIDToRemove.end(); ++iter) { //Áï½Ã »óÅÂÈ¿°ú Á¦°Å Çϰí m_pStateBlow->RemoveImediatlyStateEffectFromID(iter->second); //Ŭ¶óÀÌ¾ðÆ®·Î »óÅÂÈ¿°ú Á¦°Å ÆÐŶ º¸³¿. SendRemoveStateEffectFromID(iter->second); } m_vlStateBlowIDToRemove.clear(); } void CDnActor::ForceKnockBack(DnActorHandle hHitter, CDnDamageBase::SHitParam& HitParam) { m_HitParam = HitParam; int nSeed = CRandom::Seed(GetRoom()); _srand( GetRoom(), nSeed ); CDnWeapon::HitTypeEnum HitType = CDnWeapon::Normal; ////////////////////////////////////////////////////////////////////////// // °æÁ÷ ½Ã°£ °è»ê float fStiffResult = 0.f; if( GetStiffResistance() > 0 ) fStiffResult = ( hHitter->GetStiff() * m_HitParam.fStiffProb ) / GetStiffResistance(); fStiffResult *= CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffRevision ); if( fStiffResult <= 0.f ) fStiffResult = 0.05f; else if( fStiffResult > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax ) ) fStiffResult = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax ); m_fStiffDelta = s_fMaxStiffTime * fStiffResult; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // ´Ù¿îµô·¹ÀÌ ·£´ý°ª ¼³Á¤ if( !IsDown() ) { m_fLastDownRatio = 1.f; } float fTemp = ( 3.f * ( 1.f - GetDownDelayProb() ) ) * m_fLastDownRatio; int nTemp = (int)( fTemp * DOWN_DELAY_RANDOM_RANGE * 100.f ); if( nTemp == 0 ) m_fDownDelta = fTemp; else m_fDownDelta = fTemp - DOWN_DELAY_RANDOM_RANGE + ( _rand(GetRoom())%( nTemp * 2 ) / 100.f ); if( m_fDownDelta >= 3.f ) m_fDownDelta = 3.f; if( m_fDownDelta <= 0.1f ) m_fDownDelta = 0.01f; ////////////////////////////////////////////////////////////////////////// m_HitParam.HitType = HitType; // µ¥¹ÌÁö °è»ê switch( HitType ) { case CDnWeapon::Normal: case CDnWeapon::Critical: case CDnWeapon::Stun: case CDnWeapon::CriticalRes: { // ¹«°Ô¿¡ µû¶ó °¡¼Óµµ ÁÙ¿©ÁØ´Ù. if( GetWeight() > 0.f ) m_HitParam.vVelocity.y /= GetWeight(); if( GetWeight() > 1.f ) { float fTemp = m_HitParam.vVelocity.z; float fTest = CalcMovement( fTemp, 1.f, FLT_MAX, FLT_MIN, m_HitParam.vResistance.z ); if( m_HitParam.vVelocity.z * fTest > 0.f ) { m_HitParam.vVelocity.x /= powf( 1.1f, GetWeight() ); m_HitParam.vVelocity.z /= powf( 1.1f, GetWeight() ); } } bool bSuccessNormalDamage = true; int nSuperAmmorTime = 0; m_HitParam.bSuccessNormalDamage = bSuccessNormalDamage; m_HitParam.nSuperAmmorDelay = nSuperAmmorTime; memset( m_nSkillSuperAmmorValue, 0, sizeof(m_nSkillSuperAmmorValue) ); OnBreakSkillSuperAmmor( m_HitParam ); if( bSuccessNormalDamage ) { CheckDamageVelocity( hHitter ); // ¸Â¾ÒÀ»¶§ ¸®¼ÂÇÒ°Íµé ¸®¼Â MAMovementBase *pMovement = GetMovement(); if( pMovement ) { pMovement->ResetMove(); pMovement->ResetLook(); } if( !m_HitParam.szActionName.empty() ) { SetActionQueue( m_HitParam.szActionName.c_str(), 0, 3.f, 0.f, false ); } } } break; } INT64 nDamage = 0; RequestDamage(hHitter, nSeed, nDamage); } void CDnActor::RemoveNonAvailableStateBlow() { if (NULL == m_pStateBlow) return; CDNGameRoom* pGameRoom = static_cast(GetRoom()); CDNUserSession *pUserSession = pGameRoom ? pGameRoom->GetUserSession(GetSessionID()) : NULL; if (!pUserSession) return; const TMapInfo* pMapData = g_pDataManager->GetMapInfo( pUserSession->GetMapIndex() ); if (!pMapData) return; //¿ùµå ¸ÊÀÏ °æ¿ì´Â ½ºÅµ if (GlobalEnum::MAP_WORLDMAP == pMapData->MapType) return; // ÇöÀç À¯Àú°¡ ¼ÓÇÑ ¸ÊÀÇ AllowTypeÀ» ¾ò¾î ¿Â´Ù.. int nAllowMapType = pMapData->nAllowMapType; int nSize = m_pStateBlow->GetNumStateBlow(); for ( int i = 0 ; i < nSize ; i++ ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i); if( hBlow && STATE_BLOW::STATE_END != hBlow->GetBlowState() ) { //»óÅÂÈ¿°úÁß ¾ÆÀÌÅÛ ½ºÅ³¿¡ ÀÇÇÑ »óÅÂÈ¿°úÀÎÁö È®ÀÎÇØ¼­ //»ç¿ëµÈ ¾Æ¾ÆÅÛ ID¸¦ ¾ò¾î ¿Â´Ù. const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo(); if (pSkillInfo && pSkillInfo->bIsItemSkill) { int nItemID = pSkillInfo->nItemID; const TItemData* pItemData = g_pDataManager->GetItemData(nItemID); if (pItemData) { //ÇöÀç ¸ÊÀÇ AllowMapType°ú ¾ÆÀÌÅÛÀÇ AllowMapType ¼³Á¤ÀÌ ´Ù¸£´Ù¸é if ((nAllowMapType & pItemData->nAllowMapType) == 0) { CmdRemoveStateEffectFromID(hBlow->GetBlowID()); } } } } } } void CDnActor::RemovedActivatedStateBlow( bool bIgnoreItemSkill ) { if (NULL == m_pStateBlow) return; CDNGameRoom* pGameRoom = static_cast(GetRoom()); CDNUserSession *pUserSession = pGameRoom ? pGameRoom->GetUserSession(GetSessionID()) : NULL; if (!pUserSession) return; int nSize = m_pStateBlow->GetNumStateBlow(); for ( int i = 0 ; i < nSize ; i++ ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i); if( hBlow && STATE_BLOW::STATE_END != hBlow->GetBlowState() ) { const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo(); if( bIgnoreItemSkill == true && pSkillInfo && pSkillInfo->bIsItemSkill ) continue; if ( hBlow->IsFromSourceItem() ) continue; if( hBlow->IsEternity() ) continue; if ( !bIsPassiveSkill( hBlow ) ) { CmdRemoveStateEffectFromID(hBlow->GetBlowID()); } } } } void CDnActor::FindSkillBySkillType(CDnSkill::SkillTypeEnum eSkillType, DNVector(DnSkillHandle)& vlSkillList) { #ifndef PRE_FIX_SKILLLIST for( DWORD i=0; iGetSkillType()) vlSkillList.push_back(hSkill); } #else DWORD dwNumSkill = GetSkillCount(); for( DWORD i = 0; i < dwNumSkill; ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); if( !hSkill ) continue; if( eSkillType == hSkill->GetSkillType() ) vlSkillList.push_back( hSkill ); } #endif // #ifndef PRE_FIX_SKILLLIST } void CDnActor::OnLoopAction( float fFrame, float fPrevFrame ) { /* if( m_nActionIndex == -1 || m_nVecAniIndexList[m_nActionIndex] == -1 ) return; MAActorRenderBase *pRenderBase = static_cast(this); if( !pRenderBase ) return; ActionElementStruct *pStruct = GetElement( m_nActionIndex ); EtVector3 vDist; pRenderBase->CalcAniDistance( m_nVecAniIndexList[m_nActionIndex], min( (float)pStruct->dwLength, fFrame ), fPrevFrame, vDist ); pRenderBase->AddAniDistance( vDist ); */ } void CDnActor::CmdUpdateStateBlow(int nBlowID) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); DWORD dwUniqueID = GetUniqueID(); Stream.Write( &dwUniqueID, sizeof(dwUniqueID) ); Stream.Write( &nBlowID, sizeof(nBlowID) ); Send( eActor::SC_CMDUPDATESTATEBLOW, &Stream ); } void CDnActor::CmdFinishAuraSkill(DWORD nSkillID) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); DWORD dwUniqueID = GetUniqueID(); Stream.Write( &dwUniqueID, sizeof(dwUniqueID) ); Stream.Write( &nSkillID, sizeof(nSkillID) ); Send( eActor::SC_FINISH_AURASKILL, &Stream ); } bool CDnActor::IsImmuned(STATE_BLOW::emBLOW_INDEX blowIndex) { CDnStateBlow *pStateBlow = GetStateBlow(); if (!pStateBlow) return false; return pStateBlow->IsImmuned(blowIndex); } void CDnActor::SetAction( const char *szActionName, float fFrame, float fBlendFrame, bool bLoop /* = false */ ) { CDnActionBase::SetAction( CheckChangeActionBlow( szActionName ), fFrame, fBlendFrame, bLoop ); //µ¿ÀÛ ¹Ù²ð¶§ HitLimitCountÁ¤º¸ ÃʱâÈ­ m_HitLimitCountInfoList.clear(); } const char *CDnActor::CheckChangeActionBlow( const char *szActionName ) { const char *szResultActionName = szActionName; // Move ¾×¼Çµµ ¹Ù²î¾î¾ßÇÒ ¶§°¡ ÀÖÀ¸¹Ç·Î ¾î¿ ¼ö ¾øÀÌ SetAction ÇÔ¼öµµ º¯°æ... ¤Ð¤Ð // 129¹ø ¾×¼Ç À̸§ ´ëü »óÅÂÈ¿°ú /////////////////////////////////////////////////////////////////// if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_129 ) ) { DNVector(DnBlowHandle) vlhChangeActionSetBlow; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_129, vlhChangeActionSetBlow ); // ¾×¼Ç ¼Â º¯°æ »óÅÂÈ¿°ú´Â ¿©·¯°³ ÀÖÀ» ¼ö ÀÖ´Ù. int iNumBlow = (int)vlhChangeActionSetBlow.size(); for( int i = 0; i < iNumBlow; ++i ) { if( !vlhChangeActionSetBlow[i] ) continue; CDnChangeActionSetBlow* pChangeActionSetBlow = static_cast( vlhChangeActionSetBlow.at(i).GetPointer() ); if( STATE_BLOW::STATE_END != pChangeActionSetBlow->GetBlowState() ) { CDnChangeActionStrProcessor* pProcessor = pChangeActionSetBlow->GetChangeActionStrProcessor(); if( pProcessor ) { // °ÔÀÓ¼­¹ö ´ýÇÁ È®Àοë. string strNowActionName( szResultActionName ); const char* pChangeActionName = pProcessor->GetChangeActionName( strNowActionName ); if( pChangeActionName ) szResultActionName = pChangeActionName; } } } } // 121¹ø ½ºÅÄµå ¾×¼Ç º¯°æ »óÅÂÈ¿°ú°¡ ÀÖ´Â °æ¿ì. ÇØ´ç ¾×¼ÇÀ¸·Î º¯°æÇØ ÁÜ. /////////////////////////// if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_121 ) ) { if( 0 == strcmp(szResultActionName, "Stand") ) { DNVector(DnBlowHandle) vlhChangeStandActionBlow; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_121, vlhChangeStandActionBlow ); if( false == vlhChangeStandActionBlow.empty() ) { _ASSERT( 1 == vlhChangeStandActionBlow.size() ); if( STATE_BLOW::STATE_END != vlhChangeStandActionBlow.front()->GetBlowState() ) szResultActionName = vlhChangeStandActionBlow.front()->GetValue(); } } } return szResultActionName; } void CDnActor::ForceBeginStateBlow(DnBlowHandle hBlow) { if (hBlow) { hBlow->OnBegin( CDnActionBase::m_LocalTime, 0.0f ); OnBeginStateBlow( hBlow ); // °ð¹Ù·Î end ·Î ¼ÂÆÃÇÏ´Â blow µµ Àֱ⠶§¹®¿¡ üũ. if( STATE_BLOW::STATE_END != hBlow->GetBlowState() ) hBlow->SetState( STATE_BLOW::STATE_DURATION ); } } bool CDnActor::CanUsePrefixSkill() { bool isCanUse = false; // ÆòŸÀ̰ųª ½ºÅ³¿¡ Á¢µÎ¾î ½ºÅ³ ¹ßµ¿ Ç÷¡±×°¡ ¼³Á¤ µÇ¾î ÀÖÀ¸¸é ¹ßµ¿µÊ. [2011/01/31 semozz] // [2011/02/11 semozz] // Á¢µÎ¾î ½ºÅ³ ¹ßµ¿ Ç÷¡±× üũ±â´É Á¦°Å // [2011/03/14 semozz] // ÇØÅ·½ºÅÙ½º·ù ½ºÅ³Àº ChangeStandAction»óÅ ȿ°ú°¡ Àû¿ë µÇ¾î À־ m_hProcessSkillÀÌ ¾øÁö¸¸ ½ºÅ³ »ç¿ë »óÅÂÀÌ´Ù. // ChangeStandAction»óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é ÆòŸ°¡ ¾Æ´Ï´Ù..¶ó°í ÀÏ´ÜÀº ÆÇ´ÜÇÑ´Ù.. // Á¢µÎ¾î »óÅÂÈ¿°ú ¹«½ÃÇÏ´Â »óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é Àû¿ë ¾ÈµÊ [2011/03/23 semozz] isCanUse = (false == IsProcessSkill() && //ÆòŸ !IsAppliedThisStateBlow(STATE_BLOW::BLOW_121) && !IsAppliedThisStateBlow(STATE_BLOW::BLOW_129) && //ÇØÅ·½ºÅÙ½º·ù !IsAppliedThisStateBlow(STATE_BLOW::BLOW_183) //Á¢µÎ¾î ¹«½Ã /* || IsPrefixTriggerSkill()*/); return isCanUse; } void CDnActor::AddStateBlowSignal(DnBlowHandle hBlow) { if (m_pStateBlowSignalProcessor && hBlow) m_pStateBlowSignalProcessor->AddBlow(hBlow); } void CDnActor::RemoveStateBlowSignal(DnBlowHandle hBlow) { if (m_pStateBlowSignalProcessor && hBlow) m_pStateBlowSignalProcessor->RemoveBlow(hBlow); } void CDnActor::ReserveStealMagicBuff(DnActorHandle hActor, CDnSkill::SkillInfo *pSkillInfo, int nDurationTime, STATE_BLOW::emBLOW_INDEX blowIndex, const char* szValue) { StateBlowInfo newBlowInfo; newBlowInfo.blowIndex = blowIndex; newBlowInfo.strValue = szValue ? szValue : ""; STEAL_MAGIC_BUFF_INFO_LIST::iterator findIter = m_StealMagicBuffAddList.find(hActor); if (findIter != m_StealMagicBuffAddList.end()) { findIter->second.stateBlowList.push_back(newBlowInfo); } else { StealMagicBuffInfo newInfo; newInfo.nDurationTime = nDurationTime; if (pSkillInfo) newInfo.skillInfo = *pSkillInfo; newInfo.stateBlowList.push_back(newBlowInfo); m_StealMagicBuffAddList.insert(STEAL_MAGIC_BUFF_INFO_LIST::value_type(hActor, newInfo)); } } void CDnActor::UpdateStealMagicBuff() { //±âÁ¸¿¡ Àû¿ëµÈ ½ºÆ¿¸ÅÁ÷¿¡ÀÇÇÑ »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é Á¦°ÅÇϰí.. if (!m_StealMagicBuffList.empty()) { //Áö¿öÁö´Â »óÅÂÈ¿°úÁß ½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇÑ »óÅÂÈ¿°ú°¡ Áö¿öÁú¶§ ¸®½ºÆ®¿¡ ´ã¾Æ ³õÀº »óÅÂÈ¿°ú¸¦ Á¦°Å ÇÑ´Ù. STEAL_MAGIC_BUFF_LIST::iterator firstIter = m_StealMagicBuffList.begin(); if (firstIter != m_StealMagicBuffList.end()) { std::list::iterator iter = firstIter->second.begin(); for (; iter != firstIter->second.end(); ) { int nBlowID = (*iter); std::map::iterator findIter = m_RemovedStealMagicStateBlowIDList.find(nBlowID); if (findIter != m_RemovedStealMagicStateBlowIDList.end()) { iter = firstIter->second.erase(iter); continue; } ++iter; } } } m_RemovedStealMagicStateBlowIDList.clear(); //½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇÑ »óÅÂÈ¿°ú ¿¹¾àµÈ°Ô ¾ø´Ù¸é °Ç³Ê¶Ù°í... if (m_StealMagicBuffAddList.empty()) return; //±âÁ¸¿¡ Àû¿ëµÈ ½ºÆ¿¸ÅÁ÷¿¡ÀÇÇÑ »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é Á¦°ÅÇϰí.. if (!m_StealMagicBuffList.empty()) { //¾ÆÁ÷ Àû¿ë µÇ¾î ÀÖ´Â »óÅÂÈ¿°ú Á¦°Å ÇÑ´Ù.. STEAL_MAGIC_BUFF_LIST::iterator firstIter = m_StealMagicBuffList.begin(); if (firstIter != m_StealMagicBuffList.end()) { std::list::iterator iter = firstIter->second.begin(); std::list::iterator endIter = firstIter->second.end(); for (; iter != endIter; ++iter) { int nBlowID = (*iter); //Áï½Ã »óÅÂÈ¿°ú Á¦°Å Çϰí m_pStateBlow->RemoveImediatlyStateEffectFromID(nBlowID); //Ŭ¶óÀÌ¾ðÆ®·Î »óÅÂÈ¿°ú Á¦°Å ÆÐŶ º¸³¿. SendRemoveStateEffectFromID(nBlowID); } firstIter->second.clear(); } m_StealMagicBuffList.clear(); } //¿¹¾àµÈ ½ºÆ¿¸ÅÁ÷ »óÅÂÈ¿°ú Àû¿ë //·£´ýÇÏ°Ô Çϳª °ñ¶ó ³»ÀÚ.. int nCount = (int)m_StealMagicBuffAddList.size(); int nSelectIndex = rand() % nCount; STEAL_MAGIC_BUFF_INFO_LIST::iterator selectedIter = m_StealMagicBuffAddList.begin(); for (int i = 0; i < nSelectIndex; ++i) ++selectedIter; if (selectedIter != m_StealMagicBuffAddList.end()) { StealMagicBuffInfo &buffInfo = selectedIter->second; STATE_BLOW_INFO_LIST::iterator iter = selectedIter->second.stateBlowList.begin(); STATE_BLOW_INFO_LIST::iterator endIter = selectedIter->second.stateBlowList.end(); for (; iter != endIter; ++iter) { int nBlowID = CmdAddStateEffect(&buffInfo.skillInfo, iter->blowIndex, buffInfo.nDurationTime, iter->strValue.c_str(), false, false); AddStealMagicStateBlow(buffInfo.skillInfo.iSkillID, nBlowID); } } m_StealMagicBuffAddList.clear(); } void CDnActor::AddStealMagicStateBlow(int nSkillID, int nBlowID) { STEAL_MAGIC_BUFF_LIST::iterator findIter = m_StealMagicBuffList.find(nSkillID); if (findIter != m_StealMagicBuffList.end()) { findIter->second.push_back(nBlowID); } else { std::list blowIDList; blowIDList.push_back(nBlowID); m_StealMagicBuffList.insert(STEAL_MAGIC_BUFF_LIST::value_type(nSkillID, blowIDList)); } } void CDnActor::RemoveStealMagicStateBlow(int nDeletedBlowID) { //½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇØ Ãß°¡µÈ »óÅÂÈ¿°ú Á¤º¸°¡ ÀÖ´Ù¸é if (!m_StealMagicBuffList.empty()) { //Áö±ÝÀº ÇÑ ¾×ÅÍ¿¡¼­¸¸ ½ºÆ¿¸ÅÁ÷À» Çϱ⶧¹®¿¡ begin¿¡ Àִ°͸¸ È®ÀÎ.. STEAL_MAGIC_BUFF_LIST::iterator firstIter = m_StealMagicBuffList.begin(); if (firstIter != m_StealMagicBuffList.end()) { std::list::iterator iter = firstIter->second.begin(); std::list::iterator endIter = firstIter->second.end(); for (; iter != firstIter->second.end(); ) { // Áö±Ý Á¦°ÅµÇ´Â »óÅÂÈ¿°úÀÇ BlowID¿Í °°Àº ³à¼®À» ¹ß°ß ÇÏ¸é ¸®½ºÆ®¿¡¼­ Á¦°Å ÇÑ´Ù. if (nDeletedBlowID == (*iter)) { m_RemovedStealMagicStateBlowIDList.insert(std::map::value_type(nDeletedBlowID, nDeletedBlowID)); break; } ++iter; } } } } void CDnActor::OnEndStateBlow( DnBlowHandle hBlow ) { //»óÅÂÈ¿°ú Á¦°Å µÉ¶§ ½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇÑ »óÅÂÈ¿°úÀÌ¸é ¸®½ºÆ®¿¡¼­ Á¦°Å Çϱâ À§ÇÑ ÄÚµå if (!hBlow) return; int nDeletedBlowID = hBlow->GetBlowID(); RemoveStealMagicStateBlow(nDeletedBlowID); } #ifdef PRE_ADD_MONSTER_CATCH bool CDnActor::CatchCalcSuperArmor( DnActorHandle hCatcherActor, int iSuperArmorDamage ) { bool bResult = false; // ½´ÆÛ¾Æ¸Ó µ¥¹ÌÁö¸¦ Àû¿ëÇϰí 0 ÀÌÇϸé ÀâÈû. // µ¥¹ÌÁö Àû¿ëÇÏ°í ½´ÆÛ¾Æ¸Ó°¡ ³²¾ÆÀÖ´Ù¸é ÇÁ·¹ÀÓ ´À¸®°Ô ÇÏ°í ÆÐ½º. ÇöÀç ½´ÆÛ¾Æ¸Ó´Â 0¸¸ »ç¿ëÇÔ. m_nSkillSuperAmmorValue[ 0 ] -= iSuperArmorDamage; if( m_nSkillSuperAmmorValue[ 0 ] < 0 ) { bResult = true; } else { // ¿ì¼± ÇÁ·¹ÀÓ ´À·ÁÁö´Â °Ç »«´Ù. //// ½´ÆÛ ¾Æ¸Ó·Î ¹öÆÀ. //int iSuperArmorTime = m_nSkillSuperAmmorTime; //int iDelay = (int)( iSuperArmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) ); //if( iDelay > 0 ) //{ // SetPlaySpeed( (DWORD)( iSuperArmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) ), 0.03f ); //} } return bResult; } #endif // #ifdef PRE_ADD_MONSTER_CATCH bool CDnActor::CheckCollisionHitCondition(const EtVector3& vObjPos, const MatrixEx& objCross, EtVector3 &vTargetPos, float angleAllow) { EtVector3 vDir = vTargetPos - vObjPos; vDir.y = 0.f; EtVec3Normalize(&vDir, &vDir); EtVector3 vZVec = objCross.m_vZAxis; float fDeg = EtToDegree(acos(EtVec3Dot(&vZVec, &vDir))); if (fDeg > angleAllow) return false; return true; } DnMonsterActorHandle CDnActor::FindOldSummonMonster(const SummonMonsterStruct* pSummonMonsterStruct) { DnMonsterActorHandle hSelectedSummon; LOCAL_TIME tempTime = 0x7FFFFFFFFFFFFFFF; if( 0 < pSummonMonsterStruct->nGroupID ) { if( 0 < m_mapSummonMonsterByGroup.count( pSummonMonsterStruct->nGroupID ) ) { std::list& listSummonedGroupMonster = m_mapSummonMonsterByGroup[ pSummonMonsterStruct->nGroupID ]; for( std::list::iterator itor=listSummonedGroupMonster.begin(); itor!=listSummonedGroupMonster.end(); ++itor) { DnMonsterActorHandle hMonster = *itor; //GroupÀÌ ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì´Â MonsterID¸¦ ºñ±³ ÇÏÁö ¾Ê°í ±×·ì³»¿¡ ÀÖ´Â ¼Òȯ ¸ó½ºÅÍÁß¿¡¼­ ¼Òȯ ½Ã°£ÀÌ Á¦ÀÏ ¿À·¡µÈ ³à¼®À» ¼±Åà Çϵµ·Ï ÇÑ´Ù. if (!hMonster) continue; LOCAL_TIME requestSummonTime = hMonster->GetRequestSummonTime(); if( requestSummonTime < tempTime) { hSelectedSummon = hMonster; tempTime = requestSummonTime; } } } } else { for( std::list::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end(); ++itor) { DnMonsterActorHandle hMonster = *itor; if (!hMonster || hMonster->GetMonsterClassID() != pSummonMonsterStruct->MonsterID) continue; LOCAL_TIME requestSummonTime = hMonster->GetRequestSummonTime(); if( requestSummonTime < tempTime) { hSelectedSummon = hMonster; tempTime = requestSummonTime; } } } return hSelectedSummon; } void CDnActor::RequestActionChange(int nActionIndex) { BYTE pBuffer[ 16 ]; CPacketCompressStream Stream( pBuffer, 16 ); Stream.Write( &nActionIndex, sizeof(int) ); Send( eActor::SC_ACTION_CHANGE, &Stream ); } const std::list& CDnActor::GetSummonedMonsterList( void ) { for( std::list::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end() ; ) { if( !(*itor) ) { itor = m_listSummonMonster.erase( itor ); } else { ++itor; } } return m_listSummonMonster; } const std::map >& CDnActor::GetGroupingSummonedMonsterList( void ) { map >::iterator iter = m_mapSummonMonsterByGroup.begin(); for( iter; iter != m_mapSummonMonsterByGroup.end(); ++iter ) { list& listSummonedMonsters = iter->second; list::iterator iterList = listSummonedMonsters.begin(); for( iterList; iterList != listSummonedMonsters.end(); ) { if( !(*iterList) ) { iterList = listSummonedMonsters.erase( iterList ); } else { ++iterList; } } } return m_mapSummonMonsterByGroup; } void CDnActor::SendChainAttackProjectile(DnActorHandle hRootAttacker, DWORD dwPrevAttackerActorUniqueID, int iActionIndex, int iProjectileSignalArrayIndex, DnActorHandle hActorToAttack, int iSkillID) { if (!hRootAttacker || !hActorToAttack) return; BYTE pBuffer[ 256 ]; CPacketCompressStream Stream( pBuffer, 256 ); // DWORD dwRootAttackerID = hRootAttacker->GetUniqueID(); DWORD dwActorToAttackID = hActorToAttack->GetUniqueID(); Stream.Write(&dwRootAttackerID, sizeof(DWORD)); Stream.Write(&dwPrevAttackerActorUniqueID, sizeof(DWORD)); Stream.Write(&dwActorToAttackID, sizeof(DWORD)); Stream.Write(&iActionIndex, sizeof(int)); Stream.Write(&iProjectileSignalArrayIndex, sizeof(int)); Stream.Write(&iSkillID, sizeof(int)); Send( eActor::SC_CHAINATTACK_PROJECTILE, &Stream ); } void CDnActor::RemoveStateEffectByHitSignal(HitStruct* pHitStruct) { if (NULL == pHitStruct) return; //RemoveStateIndex±â´É ¸·À½ ¿äûÀ¸·Î ÀÎÇØ RemoveStateIndex´Â ¹«½Ã Çϵµ·Ï ¼öÁ¤ÇÔ. #if defined(PRE_FIX_51988) if (pHitStruct->szRemoveStateIndexList == NULL) return; #else if (pHitStruct->RemoveStateIndex == 0 && pHitStruct->szRemoveStateIndexList == NULL) return; #endif // PRE_FIX_51988 #if defined(PRE_FIX_51988) std::string str = pHitStruct->szRemoveStateIndexList ? pHitStruct->szRemoveStateIndexList : ""; #else std::string str = FormatA("%d;%s", pHitStruct->RemoveStateIndex, pHitStruct->szRemoveStateIndexList ? pHitStruct->szRemoveStateIndexList : ""); #endif // PRE_FIX_51988 std::vector tokens; std::string delimiters = ";"; //1. »óÅÂÈ¿°ú À妽º ¸®½ºÆ®¿Í Àû¿ë ·¹º§ ±¸ºÐ TokenizeA(str, tokens, delimiters); for (int i = 0; i < (int)tokens.size(); ++i) { STATE_BLOW::emBLOW_INDEX eBlowIndex = (STATE_BLOW::emBLOW_INDEX)(atoi(tokens[i].c_str())); if (eBlowIndex == STATE_BLOW::emBLOW_INDEX::BLOW_NONE) continue; //ÆÐŶ º¸³»°í... SendRemoveStateEffect(eBlowIndex); //¿©±â¼­´Â Á÷Á¢ ¹Ù·Î Áö¿î´Ù... m_pStateBlow->RemoveImediatlyStateEffectByBlowIndex(eBlowIndex); } } bool CDnActor::ProcessIgnoreHitSignal() { bool bIgnoreHitSignal = false; DnBlowHandle hIgnoreHitSignalBlow; if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_228)) { DNVector(DnBlowHandle) vecBlowList; GatherAppliedStateBlowByBlowIndex(STATE_BLOW::BLOW_228, vecBlowList); for (int i = 0; i < (int)vecBlowList.size(); ++i) { DnBlowHandle hBlow = vecBlowList[i]; if (hBlow && hBlow->CanBegin()) { bIgnoreHitSignal = true; hIgnoreHitSignalBlow = hBlow; break; } } } //È÷Æ® ½Ã±×³Î ¹«½Ã°¡ ¼³Á¤ÀÌ µÇ¸é ÇØ´ç »óÅÂÈ¿°ú ÀÌÆåÆ® Ç¥½Ã¿ë ÆÐŶ ³¯¸®°í ´õÀÌ»ó µ¥¹ÌÁö ó¸® ¾ÈÇϵµ·Ï ÇÑ´Ù. if (hIgnoreHitSignalBlow && bIgnoreHitSignal == true) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); DWORD dwUniqueID = GetUniqueID(); STATE_BLOW::emBLOW_INDEX stateBlowIndex = hIgnoreHitSignalBlow->GetBlowIndex(); bool bShowEffect = true; Stream.Write( &dwUniqueID, sizeof(dwUniqueID) ); Stream.Write( &stateBlowIndex, sizeof(stateBlowIndex)); Stream.Write( &bShowEffect, sizeof(bShowEffect)); Send(eActor::SC_SHOW_STATE_EFFECT, &Stream); return true; } return false; } bool CDnActor::ProcessIgnoreGravitySignal() { bool bIgnoreGravitySignal = false; if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_273 ) ) { DNVector(DnBlowHandle) vecBlowList; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_273, vecBlowList ); for( int i=0; i<(int)vecBlowList.size(); ++i ) { DnBlowHandle hBlow = vecBlowList[i]; if( hBlow && hBlow->CanBegin() ) { bIgnoreGravitySignal = true; break; } } } return bIgnoreGravitySignal; } void CDnActor::AddSkillStateEffect(DnSkillHandle hSkill) { m_ApplySkillStateEffectList.push_back(hSkill); } void CDnActor::ApplySkillStateEffect() { if (m_ApplySkillStateEffectList.empty()) return; std::vector::iterator iter = m_ApplySkillStateEffectList.begin(); for (; iter != m_ApplySkillStateEffectList.end(); ++iter) { DnSkillHandle hSkill = *(iter); if (hSkill) { DWORD stateCount = hSkill->GetStateEffectCount(); CDnStateBlow *pStateBlow = GetStateBlow(); const CDnSkill::SkillInfo* skillInfo = hSkill->GetInfo(); if (pStateBlow) { for (DWORD dwIndex = 0; dwIndex < stateCount; ++dwIndex) { CDnSkill::StateEffectStruct *pStateEffect = hSkill->GetStateEffectFromIndex(dwIndex); if (pStateEffect == NULL || pStateEffect->ApplyType != CDnSkill::StateEffectApplyType::ApplySelf) continue; CDnSkill::CanApply eResult = CDnSkill::CanApply::Apply; eResult = pStateBlow->CanApplySkillStateEffect(skillInfo, *pStateEffect); if (CDnSkill::CanApply::Fail != eResult) { RemoveResetStateBlow(); int nBlowID = CmdAddStateEffect( skillInfo, (STATE_BLOW::emBLOW_INDEX)pStateEffect->nID, pStateEffect->nDurationTime, pStateEffect->szValue.c_str(), false, false ); //Áö¼Ó ½Ã°£ÀÌ ¾ø´Â »óÅÂÈ¿°úÀÎ °æ¿ì ½ºÅ³¿¡ µî·Ï. if (-1 != nBlowID && pStateEffect->nDurationTime == -1) { hSkill->AddSignalApplyNoPacketStateEffectHandle(nBlowID); } } } } } } m_ApplySkillStateEffectList.clear(); } void CDnActor::SendProbInvincibleSuccess( void ) { BYTE pBuffer[ 4 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 4 ); Send( eActor::SC_PROBINVINCIBLE_SUCCESS, &Stream ); } EtVector3 CDnActor::FindAutoTargetPos() { EtVector3 vTargetPosition = *GetPosition(); if( !m_FindAutoTargetName.empty()) { int nBoneIndex = GetBoneIndex( m_FindAutoTargetName.c_str() ); if( nBoneIndex != -1 ) { EtMatrix boneMatrix = GetBoneMatrix(m_FindAutoTargetName.c_str()); vTargetPosition = *(EtVector3*)&boneMatrix._41; } } return vTargetPosition; } void CDnActor::ApplyStateEffectSignalProcess( const S_NO_PACKET_SELF_STATEBLOW &StateBlowInfo, ApplyStateEffectStruct* pStruct ) { // StateBlowÀÇ »ç¿ë ¿©ºÎ È®ÀÎ ¸ÕÀú [2010/11/11 semozz] if (false == StateBlowInfo.bUsed) { CDnSkill::CanApply eResult = CDnSkill::CanApply::Apply; // [2010/11/11 semozz] // ¿©±â µî·ÏµÇ¾î ÀÖ´Â ½ºÅ³ÀÇ StateBlowµµ »ç¿ë °¡´ÉÇÑÁö È®ÀÎ ÈÄ CmdAddStateEffect¸¦ È£Ãâ ÇØ¾ß ÇÑ´Ù. // CDnSkillÀÇ OnBegin¿¡¼­ üũ ½ÃÁ¡¿¡¼­´Â »ç¿ë °¡´ÉÀÌÁö¸¸, ¿©±â È£Ãâ Àü¿¡ ´Ù¸¥ StateBlow°¡ µî·Ï µÇ¾î ÀÖÀ» ¼ö ÀÖ´Ù. // #20008ÀÇ ÈúÀ» µ¿½Ã¿¡ »ç¿ë½Ã ÀÌ·± ¹®Á¦Á¡ÀÌ ¹ß»ý. eResult = m_pStateBlow->CanApplySkillStateEffect(&StateBlowInfo.ParentSkillInfo, StateBlowInfo.StateEffect); if( CDnSkill::CanApply::Fail != eResult ) { // [2010/12/08 semozz] // ½ºÅ³ »ç¿ë ½ÃÁ¡ÀÇ CanApplySkillStateEffectÇÔ¼ö¿¡¼­ ¸®¼Â ½Ãų »óÅÂµé ¸®½ºÆ®¿¡ ´ã¾Æ ³õÀº°ÍµéÀ» // ¿©±â¼­ Á¦°Å ÇÑ´Ù. RemoveResetStateBlow(); // Note Çѱâ: ½ºÅ³ÀÌ ¹ßµ¿µÉ ½Ã¿¡ Àڽſ¡°Ô ½ºÅ³ ¾×¼Ç ½Ã°£ µ¿¾È Áï½Ã °É¸®´Â »óÅÂÈ¿°ú´Â // ÇØÁ¦ ½ÃÁ¡À» ½ºÅ³ °´Ã¼°¡ ¾Ë°í ÀÖÀ¸¹Ç·Î ½ºÅ³ °´Ã¼ÂÊÀÇ nopacket »óÅÂÈ¿°ú. ¸®½ºÆ®¿¡ ³Ö¾îÁØ´Ù. // nopacket »óÅÂÈ¿°ú´Â Ŭ¶óÀÌ¾ðÆ®¿¡¼­µµ ½ºÅ³ÀÌ ½ÇÇàµÇ¸é ¾Ë¾Æ¼­ Ãß°¡ÇÏ°í »©ÁØ´Ù. // ±×³É Àڽſ¡°Ô °Å´Â ¹öÇÁ °Å´Â Áö¼Ó½Ã°£ÀÌ ÀÖ´Â »óÅÂÈ¿°ú´Â Áö¼Ó½Ã°£ÀÌ Á¤ÇØÁ® ÀÖÀ¸¹Ç·Î ½Ã°£ ´Ù µÇ¸é // ¾Ë¾Æ¼­ Á¦°ÅµÇ¹Ç·Î ±âÁ¸ ½Ã½ºÅÛÀ» ±×´ë·Î »ç¿ëÇØ¼­ CmdAddStateEffect ½ÃŲ´Ù. ÆÐŶµµ ¾Ë¾Æ¼­ ½÷ÁÜ. ÀÌ °æ¿ì¿£ Ŭ¶ó¿¡¼­ »óÅÂÈ¿°ú ¹ßµ¿½ÃŰÁö ¾Ê°í // ¼­¹öÀÇ ÆÐŶÀ» ±â´Ù¸°´Ù. if( StateBlowInfo.StateEffect.ApplyType == CDnSkill::ApplySelf && StateBlowInfo.StateEffect.nDurationTime == -1 /*&& // ¹öÇÁ/µð¹öÇÁ/¿À¶ó µîµîµµ µÉ ¼ö Àֱ⠶§¹®¿¡ ÀÌ Á¶°ÇÀº ºüÁý´Ï´Ù. CDnSkill::Instantly == StateBlowInfo.ParentSkillInfo.eDurationType*/ ) { // [2010/12/09 semozz] // »óÅÂÈ¿°ú Ãß°¡ ÆÐŶÀ» º¸³»¾ß ÇÑ´Ù. int iBlowID = CmdAddStateEffect( &StateBlowInfo.ParentSkillInfo, (STATE_BLOW::emBLOW_INDEX)StateBlowInfo.StateEffect.nID, StateBlowInfo.StateEffect.nDurationTime, StateBlowInfo.StateEffect.szValue.c_str() ); if( -1 != iBlowID ) { if( m_hProcessSkill ) { //_ASSERT( m_hProcessSkill && -1 != iBlowID ); // ºí·Ï »óÅÂÈ¿°ú (30¹ø)Àº Áö¼Ó½Ã°£ÀÌ ¾ø´Â ÄÁ¼ÁÀ¸·Î º¯°æµÇ¾úÀ¸¹Ç·Î ¿¹¿Ü·Î ¿©±â¿¡ Ãß°¡½ÃÄÑÁÖÁö ¾Ê´Â´Ù. // Ãß°¡ ½ÃŰ¸é ¾×¼ÇÀÌ ³¡³ª´Â ¼ø°£ °°ÀÌ Á¾·áµÊ. 2010.09.20 if( !((-1 == StateBlowInfo.StateEffect.nDurationTime) && (STATE_BLOW::BLOW_030 == StateBlowInfo.StateEffect.nID)) ) m_hProcessSkill->AddSignalApplyNoPacketStateEffectHandle( iBlowID ); } else if( m_hAuraSkill && CDnSkill::Aura == StateBlowInfo.ParentSkillInfo.eDurationType ) { m_hAuraSkill->AddSignalApplyNoPacketStateEffectHandle( iBlowID ); } #ifdef _DEBUG else _ASSERT( !"»óÅÂÈ¿°ú ¼³Á¤ÇÑ ½Ã±×³Î ŸÀÌ¹Ö Ãß°¡ ½ÇÆÐ!!" ); #endif } } else { // Áö¼Ó½Ã°£ÀÌ ÀÖ´Â self »óÅÂÈ¿°ú int iBlowID = CmdAddStateEffect( &StateBlowInfo.ParentSkillInfo, (STATE_BLOW::emBLOW_INDEX)StateBlowInfo.StateEffect.nID, StateBlowInfo.StateEffect.nDurationTime, StateBlowInfo.StateEffect.szValue.c_str() ); } } // ½ºÅ³ »ç¿ë ³¡³µÀ¸¸é ¸®¼Â¸®½ºÆ® ÃʱâÈ­ [2010/12/09 semozz] InitStateBlowIDToRemove(); // ½ºÅ³ »ç¿ëÀ» ¸øÇصµ »ç¿ëÇÑ°É·Î ÇØ¾ßÇÏ´ÂÁö´Â È®ÀÎ ÇØºÁ¾ß ÇÒµí [2010/11/11 semozz] const_cast(StateBlowInfo).Used(); } else { OutputDebug( "[Error!!] »óÅÂÈ¿°ú Àû¿ë ½Ã±×³Î¿¡¼­ ÀÌ¹Ì »ç¿ëÇÑ »óÅÂÈ¿°ú À妽º(%d) »ç¿ë!!\n", pStruct->StateEffectIndex ); _ASSERT( !"»óÅÂÈ¿°ú Àû¿ë ½Ã±×³Î¿¡¼­ ÀÌ¹Ì »ç¿ëÇÑ »óÅÂÈ¿°ú À妽º »ç¿ë!!" ); } } #if defined(PRE_FIX_51048) void CDnActor::RemoveDebufAction(LOCAL_TIME LocalTime, float fDelta) { //Freezing if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_041 ) ) { DNVector(DnBlowHandle) vlBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_041, vlBlows ); int nBlowCount = (int)vlBlows.size(); for (int i = 0; i < nBlowCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow) hBlow->RemoveDebufAction(LocalTime, fDelta); } } //Frostbite if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_144 ) ) { DNVector(DnBlowHandle) vlBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_144, vlBlows ); int nBlowCount = (int)vlBlows.size(); for (int i = 0; i < nBlowCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow) hBlow->RemoveDebufAction(LocalTime, fDelta); } } //ElectricShock if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_043 ) ) { DNVector(DnBlowHandle) vlBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_043, vlBlows ); int nBlowCount = (int)vlBlows.size(); for (int i = 0; i < nBlowCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow) hBlow->RemoveDebufAction(LocalTime, fDelta); } } //Escape if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_218 ) ) { DNVector(DnBlowHandle) vlBlows; GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_218, vlBlows ); int nBlowCount = (int)vlBlows.size(); for (int i = 0; i < nBlowCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow) hBlow->RemoveDebufAction(LocalTime, fDelta); } } } #endif // PRE_FIX_51048 void CDnActor::SetState(ActorStateEnum State) { #if defined(PRE_FIX_59939) //¸Å ÇÁ·¹ÀÓ SetState°¡ È£Ãâ µÇÁö¸¸ ÀúÁÖ»óÅÂÈ¿°ú(244)¿¡¼­ ÀÚü ÄðŸÀÓ Á¦¾îÇϱ⿡ ±×³É È£Ãâ Çϵµ·Ï ÇÑ´Ù... // __super::SetState(State); bool isAttackState = IsAttack(); if (isAttackState) OnAttackChange(); #else bool isPreAttackState = IsAttack(); __super::SetState(State); bool isNewAttackState = IsAttack(); if (isPreAttackState == false && isNewAttackState == true) OnAttackChange(); #endif // PRE_FIX_59939 } void CDnActor::OnAttackChange() { if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_244)) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_244, vlBlows ); int nBlowCount = (int)vlBlows.size(); for (int i = 0; i < nBlowCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow) { CDnCurseBlow* pCurseBlow = dynamic_cast(hBlow.GetPointer()); if (pCurseBlow) pCurseBlow->OnAttackChange(); } } } } int CDnActor::ExceptionHitList(DNVector(DnActorHandle) &hVecList, MatrixEx& Cross, DnActorHandle hHiterActor, HitStruct* pStruct) { std::map hOwnerActorList; //²ÀµÎ°¢½Ã »óÅÂÈ¿°ú¸¦ °¡Áö°í ÀÖ´Â ÁÖÀξ×ÅÍ Èĺ¸? ¸®½ºÆ® std::map eraseActorList; //Á¦°Å µÇ¾î¾ß ÇÒ ¾×ÅÍ ¸®½ºÆ® std::vector hSummonActorList; //¼ÒȯµÈ ¸ó½ºÅÍ ¾×ÅÍ ¸®½ºÆ® DNVector(DnActorHandle) hNewVecList; //»õ·Î¿î ¾×ÅÍ ¸®½ºÆ® int nWeaponLength = 0; bool bOnDamageCalled = false; if (hHiterActor) { if( pStruct->bIncludeWeaponLength && hHiterActor->GetWeapon() ) nWeaponLength = hHiterActor->GetWeapon()->GetWeaponLength(); } MatrixEx CrossTemp = Cross; // ½ºÄÉÀÏµÈ ¸ó½ºÅÍÀÇ °æ¿ì È÷Æ® ½Ã±×³ÎÀÇ Áß½ÉÃàÀÌ Ç×»ó ¾×ÅÍÀÇ ¿øÁ¡ À§Ä¡°¡ ¸Â´Â °ÍÀº ¾Æ´Ï±â ¶§¹®¿¡ // ¿ÀÇÁ¼Â¿¡µµ Á¤È®ÇÏ°Ô ½ºÄÉÀÏ °ªÀ» Àû¿ë½ÃÄÑ Áà¾ß ÇÑ´Ù.(#18971) EtVector3 vScale = EtVector3(1.0f, 1.0f, 1.0f); if (hHiterActor) vScale = *hHiterActor->GetScale(); EtVector3 vOffset = *pStruct->vOffset * vScale.y; CrossTemp.MoveLocalZAxis( vOffset.z ); CrossTemp.MoveLocalXAxis( vOffset.x ); CrossTemp.MoveLocalYAxis( vOffset.y ); // ƯÁ¤ º»°ú ¸µÅ©µÈ »óŶó¸é.. if( hHiterActor && pStruct->szLinkBoneName && strlen(pStruct->szLinkBoneName) > 0 ) { int nBoneIndex = hHiterActor->GetBoneIndex( pStruct->szLinkBoneName ); if( -1 != nBoneIndex ) { EtMatrix matBoneWorld = hHiterActor->GetBoneMatrix( pStruct->szLinkBoneName ); EtMatrixMultiply( (EtMatrix*)&CrossTemp, (EtMatrix*)&CrossTemp, &matBoneWorld ); } } // ¸ó½ºÅÍ´Â ½ºÄÉÀÏ¿¡µû¶ó º¸Á¤ÇØÁà¾ßÇÑ´Ù. float fDistanceMax = pStruct->fDistanceMax * vScale.y; float fDistanceMin = pStruct->fDistanceMin * vScale.y; float fHeightMax = pStruct->fHeightMax * vScale.y; /////////////////////////////////////////////// EtVector3 vPos = CrossTemp.m_vPosition; float fDistance = max( fDistanceMax, fHeightMax - pStruct->fHeightMin ) + nWeaponLength; float fXZDistanceSQ = fDistanceMax + nWeaponLength; float fXZDistanceMinSQ = fDistanceMin; // Min Àº Weapon ±æÀÌ ¿µÇâ¾È¹Þ½À´Ï´Ù. fXZDistanceSQ *= fXZDistanceSQ; fXZDistanceMinSQ *= fXZDistanceMinSQ; EtVector3 vDir; EtVector3 vZVec = Cross.m_vZAxis; if( pStruct->fCenterAngle != 0.f ) { EtMatrix matRotate; EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) ); EtVec3TransformNormal( &vZVec, &vZVec, &matRotate ); } SAABox Box; float fDot = 0.0f; #if defined(PRE_FIX_59680) int nMyTeamID = -1; if (hHiterActor) { nMyTeamID = hHiterActor->GetTeam(); if (hHiterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149)) nMyTeamID = hHiterActor->GetOriginalTeam(); } #endif // PRE_FIX_59680 int nListCount = (int)hVecList.size(); for (int i = 0; i < nListCount; ++i) { DnActorHandle hActor = hVecList[i]; if (!hActor) continue; switch( hActor->GetHitCheckType() ) { case HitCheckTypeEnum::BoundingBox: { vDir = *hActor->GetPosition() - vPos; vDir.y = 0.f; hActor->GetBoundingBox( Box ); if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue; if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue; EtVec3Normalize( &vDir, &vDir ); fDot = EtVec3Dot( &vZVec, &vDir ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue; if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) continue; if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) continue; } break; case HitCheckTypeEnum::Collision: { SCollisionCapsule Capsule; SCollisionResponse CollisionResult; DNVector(SCollisionResponse) vCollisionResult; // Capsule.Segment.vOrigin = vPos; float fHeight = fHeightMax - pStruct->fHeightMin; Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) ); Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f ); Capsule.fRadius = ( fDistanceMax + nWeaponLength ); //int nParentBoneIndex = -1; EtVector3 vDestPos; if( hActor->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false ) continue; } } //²ÀµÎ°¢½Ã »óÅÂÈ¿°ú°¡ ÀÖ´Â ÁÖÀξ×ÅÍ Èĺ¸ ¸®½ºÆ®¸¦ ¸¸µç´Ù.. if (hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_247)) { hOwnerActorList.insert(std::make_pair(hActor->GetUniqueID(), hActor)); } //²ÀµÎ°¢½Ã·Î ¼ÒȯµÈ ¸ó½ºÅÍ ¸®½ºÆ®¸¦ ¸¸µç´Ù.. else if (hActor->IsMonsterActor()) { CDnMonsterActor* pMonsterActor = static_cast(hActor.GetPointer()); if (pMonsterActor && pMonsterActor->IsSummonedMonster() && pMonsterActor->IsPuppetSummonMonster()) { #if defined(PRE_FIX_59680) //·¼¸¯¿ÀºêÈú ½ºÅ³ÀÇ °æ¿ì ·¼¸¯Àº °°Àº ÆÀÀ¸·Î ¼³Á¤À̵Ê. //·¼¸¯ÀÇ Hit½Ã±×³Î 󸮽à ¼­¸Õ ÆÛÆêÀÌ ¸®½ºÆ® Ãß°¡°¡ µÇ°í, ¾Æ·¡¿¡¼­ ÁÖÀÎ ¾×ÅͰ¡ Á¦¿Ü µÇ¾î¼­ ÈúÀÌ Á¤»ó ó¸® µÇÁö ¾Ê´Â ¹®Á¦°¡ ¹ß»ýÇÔ. //°°Àº ÆÀÀÇ ¼­¸ÕÆÛÆêÀº ÀÌ ¸®½ºÆ®¿¡ Á¦¿Ü µÇ¾î¾ßÇÑ´Ù. int nTargetTeam = hActor->GetTeam(); if (hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149)) nTargetTeam = hActor->GetOriginalTeam(); //¹ß»çü¿¡¼­ Hiter¾×ÅͰ¡ ¾øÀ» ¼ö ÀÖ´Ù. PropÀÎ °æ¿ì(Hiter¾×ÅͰ¡ ¾ø´Â °æ¿ì´Â Ãß°¡) if (hHiterActor) { //¼­¸Õ ÆÛÆêÀÌ ´Ù¸¥ ÆÀÀÎ °æ¿ì ¼­¸Õ¾×ÅÍ ¸®½ºÆ®¿¡ Ãß°¡ Çϰí //°°Àº ÆÀÀÎ °æ¿ì Áö¿ï ¸®½ºÆ®¿¡ ¼­¸ÓÆÛÆê ¾×Å͸¦ Ãß°¡Çؼ­ ÃÖÁ¾ ¸®½ºÆ®¿¡ Áö¿ö Áöµµ·Ï ÇÑ´Ù. if (nMyTeamID != nTargetTeam) hSummonActorList.push_back(pMonsterActor); else eraseActorList.insert(std::make_pair(hActor->GetUniqueID(), hActor)); } else hSummonActorList.push_back(pMonsterActor); #else hSummonActorList.push_back(pMonsterActor); #endif // PRE_FIX_59680 } } } //¼Òȯ ¸ó½ºÅÍ ¾×ÅͰ¡ ÀÖ´Â °æ¿ì //¼Òȯ ¸ó½ºÅÍ ¾×ÅÍÀÇ ÁÖÀÎ ¾×ÅͰ¡ Á¸Àç ÇÏ´Â Áö È®ÀÎ ÇØ¼­, ÁÖÀÎ ¾×ÅͰ¡ Á¸Àç Çϸé //Áö¿ï¸®½ºÆ®¿¡ ÁÖÀÎ ¾×Å͸¦ Ãß°¡ ÇØ ³õ´Â´Ù. int nSummonActorList = (int)hSummonActorList.size(); for (int iIndex = 0; iIndex < nSummonActorList; ++iIndex) { CDnMonsterActor* pSummonMonsterActor = hSummonActorList[iIndex]; //¼Òȯ¾×ÅÍÀÇ ÁÖÀÎ ¾×Å͸¦ È®ÀÎ ÇÑ´Ù. DnActorHandle hOwnerActor = pSummonMonsterActor->GetSummonerPlayerActor(); DWORD dwOwnerUniqueID = hOwnerActor ? hOwnerActor->GetUniqueID() : -1; if (dwOwnerUniqueID == -1) continue; //ÁÖÀÎÈĺ¸ ¾×ÅÍ ¸®½ºÆ®¿¡¼­ ¾×Å͸¦ ã´Â´Ù. std::map::iterator findIter = hOwnerActorList.find(dwOwnerUniqueID); if (findIter != hOwnerActorList.end()) { //»èÁ¦ ¾×ÅÍ ¸®½ºÆ®¿¡ Ãß°¡ ÇÑ´Ù. eraseActorList.insert(std::make_pair(dwOwnerUniqueID, hOwnerActor)); } } nListCount = (int)hVecList.size(); for (int i = 0; i < nListCount; ++i) { DnActorHandle hActor = hVecList[i]; if (!hActor) continue; //¿ø·¡ ¾×ÅÍ ¸®½ºÆ®¸¦ µ¹¸é¼­, Áö¿ö¾ß ÇÒ ¾×ÅÍ ¸®½ºÆ®¿¡ ãÁö ¸ø ÇÏ¸é »õ·Î¿î ¸®½ºÆ®¿¡ Ãß°¡ ÇÑ´Ù. DWORD dwOwnerUniqueID = hActor->GetUniqueID(); std::map::iterator findIter = eraseActorList.find(dwOwnerUniqueID); if (findIter == eraseActorList.end()) hNewVecList.push_back(hActor); } std::swap(hVecList, hNewVecList); return (int)hVecList.size(); } //½ºÄµµÈ ¾×ÅÍ ¸®½ºÆ®Áß Hit¿µ¿ª¿¡ ÀÖ´Â ³à¼®µé¸¸ ¸®½ºÆ®¸¦ ¸¸µç´Ù. void CDnActor::CheckHitAreaActorList(DNVector(DnActorHandle)& hVecList, MatrixEx& Cross, DnActorHandle hHiterActor, HitStruct* pStruct, int nCheckType, float fScanLength, EtVector3& vPrePos) { DNVector(DnActorHandle) hNewVecList; //»õ·Î¿î ¾×ÅÍ ¸®½ºÆ® int nWeaponLength = 0; bool bOnDamageCalled = false; if (hHiterActor) { if( pStruct->bIncludeWeaponLength && hHiterActor->GetWeapon() ) nWeaponLength = hHiterActor->GetWeapon()->GetWeaponLength(); } MatrixEx CrossTemp = Cross; // ½ºÄÉÀÏµÈ ¸ó½ºÅÍÀÇ °æ¿ì È÷Æ® ½Ã±×³ÎÀÇ Áß½ÉÃàÀÌ Ç×»ó ¾×ÅÍÀÇ ¿øÁ¡ À§Ä¡°¡ ¸Â´Â °ÍÀº ¾Æ´Ï±â ¶§¹®¿¡ // ¿ÀÇÁ¼Â¿¡µµ Á¤È®ÇÏ°Ô ½ºÄÉÀÏ °ªÀ» Àû¿ë½ÃÄÑ Áà¾ß ÇÑ´Ù.(#18971) EtVector3 vScale = EtVector3(1.0f, 1.0f, 1.0f); if (hHiterActor) vScale = *hHiterActor->GetScale(); EtVector3 vOffset = *pStruct->vOffset * vScale.y; CrossTemp.MoveLocalZAxis( vOffset.z ); CrossTemp.MoveLocalXAxis( vOffset.x ); CrossTemp.MoveLocalYAxis( vOffset.y ); // ƯÁ¤ º»°ú ¸µÅ©µÈ »óŶó¸é.. if( pStruct->szLinkBoneName && strlen(pStruct->szLinkBoneName) > 0 ) { int nBoneIndex = hHiterActor->GetBoneIndex( pStruct->szLinkBoneName ); if( -1 != nBoneIndex ) { EtMatrix matBoneWorld = hHiterActor->GetBoneMatrix( pStruct->szLinkBoneName ); EtMatrixMultiply( (EtMatrix*)&CrossTemp, (EtMatrix*)&CrossTemp, &matBoneWorld ); } } // ¸ó½ºÅÍ´Â ½ºÄÉÀÏ¿¡µû¶ó º¸Á¤ÇØÁà¾ßÇÑ´Ù. float fDistanceMax = pStruct->fDistanceMax * vScale.y; float fDistanceMin = pStruct->fDistanceMin * vScale.y; float fHeightMax = pStruct->fHeightMax * vScale.y; /////////////////////////////////////////////// EtVector3 vPos = CrossTemp.m_vPosition; float fDistance = max( fDistanceMax, fHeightMax - pStruct->fHeightMin ) + nWeaponLength; float fXZDistanceSQ = fDistanceMax + nWeaponLength; float fXZDistanceMinSQ = fDistanceMin; // Min Àº Weapon ±æÀÌ ¿µÇâ¾È¹Þ½À´Ï´Ù. fXZDistanceSQ *= fXZDistanceSQ; fXZDistanceMinSQ *= fXZDistanceMinSQ; EtVector3 vDir; EtVector3 vZVec = Cross.m_vZAxis; if( pStruct->fCenterAngle != 0.f ) { EtMatrix matRotate; EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) ); EtVec3TransformNormal( &vZVec, &vZVec, &matRotate ); } SAABox Box; float fDot = 0.0f; int nListCount = (int)hVecList.size(); for (int i = 0; i < nListCount; ++i) { DnActorHandle hActor = hVecList[i]; if (!hActor) continue; if( !hActor->GetObjectHandle() ) continue; switch( hActor->GetHitCheckType() ) { case HitCheckTypeEnum::BoundingBox: { switch(nCheckType) { case 0: //CDnActorÀÇ OnSignal¿¡ Àִ üũ ¹æ½Ä... { vDir = *hActor->GetPosition() - vPos; vDir.y = 0.f; hActor->GetBoundingBox( Box ); if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue; if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue; EtVec3Normalize( &vDir, &vDir ); fDot = EtVec3Dot( &vZVec, &vDir ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue; if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) continue; if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) continue; } break; case 1: //ProjectileÀÇ Ã¹¹øÂ° üũ ¹æ½Ä. { float fPropContactDistance = FLT_MAX; float fNowFrameActorContactDistanceSQ = FLT_MAX; vDir = *hActor->GetPosition() - vPos; vDir.y = 0.f; hActor->GetBoundingBox( Box ); if( CDnActor::SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue; if( CDnActor::SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue; EtVec3Normalize( &vDir, &vDir ); fDot = EtVec3Dot( &vZVec, &vDir ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue; if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) continue; if( Box.Min.y > vPos.y + pStruct->fHeightMax && Box.Max.y > vPos.y + pStruct->fHeightMax ) continue; fNowFrameActorContactDistanceSQ = EtVec3LengthSq( &EtVector3( vPos - vPrePos ) ); if( fNowFrameActorContactDistanceSQ > fPropContactDistance ) continue; } break; case 2: //ProjectileÀÇ µÎ¹øÂ° üũ ¹æ½Ä { bool bResult = false; float fPropContactDistance = FLT_MAX; float fNowFrameActorContactDistanceSQ = FLT_MAX; SCollisionResponse Response; DNVector(SCollisionResponse) vResponse; float fThickness = max( fabs( pStruct->fHeightMin ), fabs( pStruct->fHeightMax ) ); SSegment Segment; Segment.vOrigin = vPrePos; Segment.vDirection = Cross.m_vZAxis * fScanLength; SCollisionCapsule Capsule; Capsule.Segment = Segment; Capsule.fRadius = fThickness; if( fThickness == 0.f ) bResult = hActor->GetObjectHandle()->FindSegmentCollision( Segment, Response ); else bResult = hActor->GetObjectHandle()->FindCapsuleCollision( Capsule, Response ); fNowFrameActorContactDistanceSQ = EtVec3LengthSq( &EtVector3( *hActor->GetPosition() - vPrePos ) ); if( fNowFrameActorContactDistanceSQ > fPropContactDistance ) continue; if (bResult == false) continue; } break; } } break; case HitCheckTypeEnum::Collision: { switch(nCheckType) { case 0://CDnActorÀÇ OnSignal üũ ¹æ½Ä.. { SCollisionCapsule Capsule; SCollisionResponse CollisionResult; DNVector(SCollisionResponse) vCollisionResult; // Capsule.Segment.vOrigin = vPos; float fHeight = fHeightMax - pStruct->fHeightMin; Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) ); Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f ); Capsule.fRadius = ( fDistanceMax + nWeaponLength ); //int nParentBoneIndex = -1; EtVector3 vDestPos; if( hActor->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false ) continue; } break; case 1://ProjectileÀÇ Ã¹¹øÂ° üũ ¹æ½Ä.. { SCollisionCapsule Capsule; SCollisionResponse CollisionResult; DNVector(SCollisionResponse) vCollisionResult; // Capsule.Segment.vOrigin = vPos; float fHeight = pStruct->fHeightMax - pStruct->fHeightMin; Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) ); Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f ); Capsule.fRadius = pStruct->fDistanceMax; //int nParentBoneIndex = -1; EtVector3 vDestPos; if( hActor->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false ) continue; } break; case 2://ProjectileÀÇ µÎ¹øÂ° üũ ¹æ½Ä.. { float fPropContactDistance = FLT_MAX; float fNowFrameActorContactDistanceSQ = FLT_MAX; bool bResult = false; float fThickness = max( fabs( pStruct->fHeightMin ), fabs( pStruct->fHeightMax ) ); SSegment Segment; Segment.vOrigin = vPrePos; Segment.vDirection = Cross.m_vZAxis * fScanLength; SCollisionCapsule Capsule; Capsule.Segment = Segment; Capsule.fRadius = fThickness; SCollisionResponse Response; DNVector(SCollisionResponse) vResponse; int nParentBoneIndex = -1; EtVector3 vDestPos; if( fThickness == 0.f ) bResult = hActor->GetObjectHandle()->FindSegmentCollision( Segment, Response, &vResponse ); else bResult = hActor->GetObjectHandle()->FindCapsuleCollision( Capsule, Response, &vResponse ); if (bResult) { fNowFrameActorContactDistanceSQ = EtVec3LengthSq( &EtVector3( Segment.vDirection * Response.fContactTime ) ); if( fNowFrameActorContactDistanceSQ > fPropContactDistance ) continue; } else continue; } break; } } } hNewVecList.push_back(hActor); } std::swap(hVecList, hNewVecList); } int CDnActor::ExceptionHitList2(DNVector(DnActorHandle) &hVecList, MatrixEx& Cross, DnActorHandle hHiterActor, HitStruct* pStruct, DNVector(DnActorHandle)& hAddStateEffectActorList, int nCheckType, float fScanLength, EtVector3& vPrePos) { //È÷Æ® ¿µ¿ª¿¡ ÀÖ´Â ¾×Å͵鸸 ¸®½ºÆ®¿¡ ´ã´Â´Ù... CDnActor::CheckHitAreaActorList(hVecList, Cross, hHiterActor, pStruct, nCheckType, fScanLength, vPrePos); int nMyTeamID = -1; if (hHiterActor) { nMyTeamID = hHiterActor->GetTeam(); if (hHiterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149)) nMyTeamID = hHiterActor->GetOriginalTeam(); } struct _PuppetNOwnerInfo { DWORD dwOwnerID; CDnMonsterActor* pPuppetMonster; DnActorHandle hPuppetActor; DnActorHandle hOwnerActor; }; std::map PuppetnOnwerInfoList; DNVector(DnActorHandle) hNewVecList; //»õ·Î¿î ¾×ÅÍ ¸®½ºÆ® EtVector3 vPos = *hHiterActor->GetPosition(); int nListCount = (int)hVecList.size(); for (int i = 0; i < nListCount; ++i) { DnActorHandle hActor = hVecList[i]; if (!hActor) continue; bool bSeperated = false; //²ÀµÎ°¢½Ã »óÅÂÈ¿°ú°¡ ÀÖ´Â ÁÖÀξ×ÅÍ Èĺ¸ ¸®½ºÆ®¸¦ ¸¸µç´Ù.. if (hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_247)) { bSeperated = true; DWORD dwOwnerUniqueID = hActor->GetUniqueID(); std::map::iterator findIter = PuppetnOnwerInfoList.find(dwOwnerUniqueID); if (findIter == PuppetnOnwerInfoList.end()) { _PuppetNOwnerInfo _info; _info.dwOwnerID = dwOwnerUniqueID; _info.hOwnerActor = hActor; PuppetnOnwerInfoList.insert(std::make_pair(dwOwnerUniqueID, _info)); } else { _PuppetNOwnerInfo& _info = findIter->second; _info.hOwnerActor = hActor; } } //²ÀµÎ°¢½Ã·Î ¼ÒȯµÈ ¸ó½ºÅÍ ¸®½ºÆ®¸¦ ¸¸µç´Ù.. else if (hActor->IsMonsterActor()) { CDnMonsterActor* pMonsterActor = static_cast(hActor.GetPointer()); if (pMonsterActor && pMonsterActor->IsSummonedMonster() && pMonsterActor->IsPuppetSummonMonster()) { bSeperated = true; DnActorHandle hOwnerActor = pMonsterActor->GetSummonerPlayerActor(); DWORD dwOwnerUniqueID = hOwnerActor ? hOwnerActor->GetUniqueID() : -1; std::map::iterator findIter = PuppetnOnwerInfoList.find(dwOwnerUniqueID); if (findIter == PuppetnOnwerInfoList.end()) { _PuppetNOwnerInfo _info; _info.dwOwnerID = dwOwnerUniqueID; _info.hPuppetActor = hActor; _info.pPuppetMonster = pMonsterActor; PuppetnOnwerInfoList.insert(std::make_pair(dwOwnerUniqueID, _info)); } else { _PuppetNOwnerInfo& _info = findIter->second; _info.hPuppetActor = hActor; _info.pPuppetMonster = pMonsterActor; } } } //ÁÖÀÎ ¾×ÅÍ/ ¼Òȯ ¾×ÅÍ ¸®½ºÆ®¿¡ Æ÷ÇÔµÇÁö ¾Ê´Â ³à¼®µéÀº »õ·Î¿î ¸®½ºÆ®¿¡ ¹Ì¸® ´ã¾Æ ³õ´Â´Ù. if (bSeperated == false) hNewVecList.push_back(hActor); } std::map::iterator iter = PuppetnOnwerInfoList.begin(); std::map::iterator endIter = PuppetnOnwerInfoList.end(); for (; iter != endIter; ++iter) { _PuppetNOwnerInfo& _info = iter->second; if (_info.hOwnerActor && _info.hPuppetActor) { /* //Á¦ÀÏ °¡±î¿î ¾×Å͸¦ Ãß°¡ ÇÑ´Ù. //ÁÖÀÎ ¾×ÅͰ¡ Á¦¿Ü µÇ´Â °æ¿ì Á¦¿ÜµÈ ¾×ÅÍ ¸®½ºÆ®¿¡ Ãß°¡ ÇØ ³õ´Â´Ù.(»óÅÂÈ¿°ú Ãß°¡¸¦ À§ÇØ) EtVector3 vOwnerDiff = (*_info.hOwnerActor->GetPosition()) - vPos; EtVector3 vPuppetDiff = (*_info.hPuppetActor->GetPosition()) - vPos; float fOwnerLength = EtVec3LengthSq(&vOwnerDiff); float fPuppetLength = EtVec3LengthSq(&vPuppetDiff); */ int nTargetTeam = _info.hOwnerActor->GetTeam(); if (_info.hOwnerActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149)) nTargetTeam = _info.hOwnerActor->GetOriginalTeam(); /* //°°Àº ÆÀÀÎ °æ¿ì °Å¸®¿¡ »ó°ü¾øÀÌ ÁÖÀÎ ¾×Å͸¦ Ãß°¡ //ÁÖÀÎ ¾×ÅÍ °Å¸®°¡ ´õ ¸Ö´Ù¸é ¼Òȯ ¾×Å͸¦ ¸®½ºÆ®¿¡ Ãß°¡ Çϰí, Á¦¿ÜµÈ ¾×ÅÍ ¸®½ºÆ®¿¡ ÁÖÀÎ ¾×Å͸¦ Ãß°¡ if (nMyTeamID != nTargetTeam && fOwnerLength > fPuppetLength) */ //°Å¸® »ó°ü ¾øÀÌ °°Àº È÷Æ® ¹üÀ§¿¡ ÀÖÀ¸¸é ¼Òȯ ¾×Å͸¦ È÷Æ® ¸®½ºÆ®¿¡ Ãß°¡ ÇÑ´Ù. if (hHiterActor && nMyTeamID != nTargetTeam) { hNewVecList.push_back(_info.hPuppetActor); hAddStateEffectActorList.push_back(_info.hOwnerActor); } else { hNewVecList.push_back(_info.hOwnerActor); } } //¼Òȯ ¾×ÅÍ/ÁÖÀÎ ¾×ÅÍ ½ÖÀÌ ¾Æ´Ñ °æ¿ì(µÎ ¾×ÅÍÁß Çϳª¸¸ Àִ°æ¿ì) ¸®½ºÆ®¿¡ Ãß°¡ else { DnActorHandle hActor = _info.hOwnerActor ? _info.hOwnerActor : _info.hPuppetActor; if (hActor) hNewVecList.push_back(hActor); } } std::swap(hVecList, hNewVecList); return (int)hVecList.size(); } void CDnActor::ScanActorByStateIndex(DNVector(DnActorHandle) &Veclist, STATE_BLOW::emBLOW_INDEX blowIndex) { DNVector(DnActorHandle) scanActorList; ScanActor(GetRoom(), *GetPosition(), FLT_MAX, scanActorList); int nListCount = (int)scanActorList.size(); for (int i = 0; i < nListCount; ++i) { DnActorHandle hActor = scanActorList[i]; if (hActor && hActor->IsDie() == false) { DNVector(DnBlowHandle) blowList; if (hActor->IsAppliedThisStateBlow(blowIndex)) hActor->GetStateBlow()->GetStateBlowFromBlowIndex(blowIndex, blowList); int nBlowCount = (int)blowList.size(); for (int j = 0; j < nBlowCount; ++j) { DnBlowHandle hBlow = blowList[j]; if (hBlow && hBlow->IsEnd() == false) { //ÇØ´ç ¾×ÅÍÀÇ ³«ÀÎ »óÅÂÈ¿°úÀÇ ½ºÅ³ ½ÃÀüÀÚ°¡ ÀÚ½ÅÀÎ °æ¿ì ¸®½ºÆ®¿¡ ´ã´Â´Ù. CDnSkill::SkillInfo *pSkillInfo = const_cast(hBlow->GetParentSkillInfo()); DnActorHandle hSkillActor = GetMySmartPtr(); if (IsMonsterActor()) { CDnMonsterActor* pMonsterActor = static_cast(hSkillActor.GetPointer()); if (pMonsterActor) hSkillActor = pMonsterActor->GetSummonerPlayerActor(); } if (pSkillInfo && pSkillInfo->hSkillUser == hSkillActor) Veclist.push_back(hActor); } } } } } // Signal Rotate. void CDnActor::SetRotate( DWORD dwTime, float fStart, float fEnd, EtVector3 & vPos, bool bLeft ) { m_bRotate = true; m_dwRotateStartTime = CDnActionBase::m_LocalTime; m_dwRotateTime = dwTime; m_fStartSpeed = fStart; m_fEndSpeed = fEnd; m_vRotAxis = vPos; m_bRotLeft = bLeft; } // Rotate. void CDnActor::ProcessRotate( LOCAL_TIME LocalTime, float fDelta ) { if( !m_bRotate ) return; if( (LocalTime - m_dwRotateStartTime) > m_dwRotateTime ) { m_bRotate = false; return; } if( m_dwRotateStartTime == 0 ) m_dwRotateStartTime = LocalTime; // ¼Óµµ( ȸÀü°¢·® ) if( m_fStartSpeed == m_fEndSpeed ) { m_fSpeedRot = m_fStartSpeed; } else { /*float frame = pObject->GetCurFrame(); float w = ( frame - m_pSignal->GetStartFrame() ) / ( m_pSignal->GetEndFrame() - m_pSignal->GetStartFrame() ); m_fSpeedRot = m_fStartSpeed + ( ( m_fEndSpeed - m_fStartSpeed ) * w ); */ m_fSpeedRot = m_fStartSpeed; } // ¹æÇâ. if( m_bRotLeft ) m_fSpeedRot = -m_fSpeedRot; m_fSpeedRot *= fDelta; //// ȸÀüÃàÁÂÇ¥À̵¿. m_Cross.MoveLocalXAxis( m_vRotAxis.x ); m_Cross.MoveLocalYAxis( m_vRotAxis.y ); m_Cross.MoveLocalZAxis( m_vRotAxis.z ); // ȸÀü. m_Cross.RotateYaw( (-m_fSpeedRot) ); } #if defined(PRE_FIX_61382) //²ÀµÎ°¢½Ã ¸ó½ºÅÍÀÏ °æ¿ì ÁÖÀÎ ¾×ÅÍ ¹Ýȯ. DnActorHandle CDnActor::GetOwnerActorHandle(DnActorHandle hActor) { DnActorHandle hOwnerActor = hActor; if (hActor && hActor->IsMonsterActor()) { CDnMonsterActor* pMonsterActor = static_cast(hActor.GetPointer()); if (pMonsterActor && pMonsterActor->IsPuppetSummonMonster()) hOwnerActor = pMonsterActor->GetSummonerPlayerActor(); } return hOwnerActor; } #endif // PRE_FIX_61382 #if defined(PRE_ADD_65808) void CDnActor::AddSummonMonsterGlyphInfo(int monsterID, int glyphID) { std::map>::iterator findIter = m_SummonMonsterGlyphInfo.find(monsterID); if (findIter != m_SummonMonsterGlyphInfo.end()) { findIter->second.push_back(glyphID); } else { std::list glyphIDList; glyphIDList.push_back(glyphID); m_SummonMonsterGlyphInfo.insert(std::make_pair(monsterID, glyphIDList)); } } void CDnActor::AddSummonMonsterGlyphStateEffectID(int monsterID, int glyphID, DWORD dwMonsterUniqueID, int stateEffectID) { std::map>>::iterator findIter = m_SummonMonsterGlyphStateEffectIDs.find(monsterID); //ÇØ´ç ¸ó½ºÅÍ Á¤º¸°¡ ¾ø´Ù¸é if (findIter == m_SummonMonsterGlyphStateEffectIDs.end()) { //»õ·Î¿î glyphID, stateEffectIDList¸¦ ¸¸µé¾î µî·ÏÇÑ´Ù. std::map> newList; std::list<_StateEffectInfo> stateEffectList; _StateEffectInfo info; info.nStateEffectID = stateEffectID; info.dwUniqueID = dwMonsterUniqueID; stateEffectList.push_back(info); newList.insert(std::make_pair(glyphID, stateEffectList)); m_SummonMonsterGlyphStateEffectIDs.insert(std::make_pair(monsterID, newList)); } else { std::map>& oldList = findIter->second; std::map>::iterator iter = oldList.find(glyphID); if (iter != oldList.end()) { //ÀÌ¹Ì glyphID°¡ µî·Ï µÇ¾î ÀÖÀ¸¸é ±âÁ¸ ¸®½ºÆ®¿¡ stateEffectID¸¦ µî·ÏÇÑ´Ù. _StateEffectInfo info; info.nStateEffectID = stateEffectID; info.dwUniqueID = dwMonsterUniqueID; iter->second.push_back(info); } else { //¸ó½ºÅÍ´Â µî·Ï µÇ¾î Àִµ¥, glyphID°¡ µî·Ï µÇ¾î ÀÖÁö ¾ÊÀ¸¸é.. //»óÅÂÈ¿°ú ¸®½ºÆ® ¸¸µé°í, std::list<_StateEffectInfo> stateEffectList; _StateEffectInfo info; info.nStateEffectID = stateEffectID; info.dwUniqueID = dwMonsterUniqueID; stateEffectList.push_back(info); //glyphID¿¡ »óÅÂÈ¿°ú ¸®½ºÆ®¸¦ µî·Ï ÇÑ´Ù. oldList.insert(std::make_pair(glyphID, stateEffectList)); } } } void CDnActor::RemoveSummonMonsterGlyphInfo(int monsterID, int glyphID) { std::map>::iterator findIter = m_SummonMonsterGlyphInfo.find(monsterID); if (findIter != m_SummonMonsterGlyphInfo.end()) { std::list& oldList = findIter->second; std::list::iterator iter = oldList.begin(); std::list::iterator endIter = oldList.end(); int nGlyphID = 0; for (; iter != endIter; ++iter) { nGlyphID = (*iter); if (nGlyphID == glyphID) { oldList.erase(iter); break; } } } //¼Òȯ¸ó½ºÅÍÁß¿¡ monsterID¿¡ ÇØ´çÇÏ´Â ¸ó½ºÅ͵éÀ» ã´Â´Ù.. std::list monsterActorList; FindSummonMonster(monsterID, monsterActorList); std::list::iterator iter = monsterActorList.begin(); std::list::iterator endIter = monsterActorList.end(); for (; iter != endIter; ++iter) { DnMonsterActorHandle hMonsterActor = (*iter); //¸ó½ºÅÍ ¾×ÅÍ ¸®½ºÆ®¸¦ ¼øÈ¸ Çϴµ¿¾È Á¤º¸°¡ Áö¿ö Áö¸é ¾ÈµÈ´Ù.. RemoveSummonMonsterStateEffectByGlyph(hMonsterActor, monsterID, glyphID); } //½ÇÁ¦ Á¤º¸´Â ¿©±â¼­ Á¦°Å µÇµµ·Ï ÇÑ´Ù. RemoveSummonMonsterGlyphStateEffects(monsterID); } void CDnActor::RemoveSummonMonsterStateEffectByGlyph(DnMonsterActorHandle hMonsterActor, int monsterID, int glyphID) { std::map>>::iterator findIter = m_SummonMonsterGlyphStateEffectIDs.find(monsterID); if (findIter != m_SummonMonsterGlyphStateEffectIDs.end()) { std::map>& oldList = findIter->second; std::map>::iterator glyphIter = oldList.find(glyphID); if (glyphIter != oldList.end()) { std::list<_StateEffectInfo>& stateEffectIDList = glyphIter->second; if (stateEffectIDList.empty() == false) { std::list<_StateEffectInfo>::iterator iter = stateEffectIDList.begin(); std::list<_StateEffectInfo>::iterator endIter = stateEffectIDList.end(); for (; iter != endIter; ++iter) { _StateEffectInfo& info = (*iter); if (hMonsterActor && hMonsterActor->GetUniqueID() == info.dwUniqueID) hMonsterActor->CmdRemoveStateEffectFromID(info.nStateEffectID); } } } } } //½ÇÁ¦ ¸ó½ºÅͰ¡ Á×¾úÀ»¶§ PlayerActor::OnDieSummonMonsterÇÔ¼ö¿¡¼­ È£Ãâ µÊ. //¸ó½ºÅͰ¡ Á¦°Å µÉ ¿¹Á¤À̹ǷΠ»óÅÂÈ¿°ú¸¦ ã¾Æ ÀÏÀÏÀÌ Áö¿ï ÇÊ¿ä´Â ¾øÀ»µí.. //¼³Á¤µÈ Á¤º¸¸¸ Á¦°Å.. void CDnActor::RemoveSummonMonsterGlyphStateEffects(int monsterID) { std::map>>::iterator findIter = m_SummonMonsterGlyphStateEffectIDs.find(monsterID); if (findIter != m_SummonMonsterGlyphStateEffectIDs.end()) { m_SummonMonsterGlyphStateEffectIDs.erase(findIter); } } bool CDnActor::GetSummonMonsterGlyphInfo(int monsterID, std::list& glyphIDs) { std::map>::iterator findIter = m_SummonMonsterGlyphInfo.find(monsterID); if (findIter != m_SummonMonsterGlyphInfo.end()) { std::list& oldList = findIter->second; std::list::iterator iter = oldList.begin(); std::list::iterator endIter = oldList.end(); int nGlyphID = 0; for (; iter != endIter; ++iter) { nGlyphID = (*iter); glyphIDs.push_back(nGlyphID); } return true; } return false; } void CDnActor::FindSummonMonster(int monsterID, std::list& monsterActorList) { std::map >::iterator iter = m_mapSummonMonsterByGroup.begin(); std::map >::iterator endIter = m_mapSummonMonsterByGroup.end(); for (; iter != endIter; ++iter) { std::list::iterator monsterIter = iter->second.begin(); std::list::iterator monsterEndIter = iter->second.end(); for (; monsterIter != monsterEndIter; ++monsterIter) { DnMonsterActorHandle hMonster = *monsterIter; if (!hMonster) continue; if (hMonster->GetMonsterClassID() == monsterID) { monsterActorList.push_back(hMonster); } } } { for( std::list::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end(); ++itor) { DnMonsterActorHandle hMonster = *itor; if (!hMonster || hMonster->GetMonsterClassID() != monsterID) continue; monsterActorList.push_back(hMonster); } } } #endif // PRE_ADD_65808 #if defined(PRE_FIX_68898) void CDnActor::SetSkipEndAction(bool isSkipEndAction) { if (IsProcessSkill() && m_hProcessSkill) { CDnPartialPlayProcessor* pPartialPlayProcess = static_cast(m_hProcessSkill->GetProcessor( IDnSkillProcessor::PARTIAL_PLAY_ANI )); if (pPartialPlayProcess) pPartialPlayProcess->SetSkipEndAction(isSkipEndAction); } } #endif // PRE_FIX_68898 void CDnActor::ResetDamageRemainTime() { m_mapLastDamageTime.clear(); m_nLastDamageHitterActionIndex = 0; } LOCAL_TIME CDnActor::GetDamageRemainTime( DWORD dwActorUniqueID ) { map::iterator iter = m_mapLastDamageTime.find( dwActorUniqueID ); if( m_mapLastDamageTime.end() != iter ) return iter->second; else return 0; } void CDnActor::SetDamageRemainTime( DWORD dwActorUniqueID, LOCAL_TIME LastDamageTime, int nCurrentActionIndex ) { m_mapLastDamageTime[ dwActorUniqueID ] = LastDamageTime; m_nLastDamageHitterActionIndex = nCurrentActionIndex; } void CDnActor::SetLastDamageHitUniqueID( DWORD dwActorUniqueID, int iLastHitUniqueID ) { m_mapLastHitUniqueID[ dwActorUniqueID ] = iLastHitUniqueID; } int CDnActor::GetLastDamageHitUniqueID( DWORD dwActorUniqueID ) { if( m_mapLastHitUniqueID.end() != m_mapLastHitUniqueID.find( dwActorUniqueID ) ) return m_mapLastHitUniqueID[ dwActorUniqueID ]; else return -1; };