#include "StdAfx.h" #include "DnPlayerActor.h" #include "EtMatrixEx.h" #include "DnWorld.h" #include "MAMovementBase.h" #include "DnWeapon.h" #include "DnProjectile.h" #include "DnGameTask.h" #include "TaskManager.h" #include "DnPartyTask.h" #include "DnSkill.h" #include "PerfCheck.h" #include "DnDropItem.h" #include "GameSendPacket.h" #include "DnMonsterActor.h" #include "DnStateBlow.h" #include "MAAiScript.h" #include "DnBlow.h" #include "DnItemTask.h" #include "DNLogConnection.h" #include "DNGameDataManager.h" #include "ScoreSystem.h" #include "DNMissionSystem.h" #include "DNDBConnectionManager.h" #include "DnPlayerSpeedHackChecker.h" #include "DnPlayerDoNotEnterChecker.h" #include "DnPlayerPickupChecker.h" #include "DnPlayerSkillChecker.h" #include "DnPlayerActionChecker.h" #include "DnPlayAniProcess.h" #include "DNPvPPlayerAggroSystem.h" #include "DNMonsterAggroSystem.h" #include "DnChangeActionSetBlow.h" #include "DnChangeActionStrProcessor.h" #include "DNDBConnection.h" #include "DnChangeStandActionBlow.h" #include "DnActionSpecificInfo.h" #include "MasterRewardSystem.h" #if defined( PRE_ADD_SECONDARY_SKILL ) #include "SecondarySkillRepositoryServer.h" #endif // #if defined( PRE_ADD_SECONDARY_SKILL ) #include "DnCannonMonsterActor.h" #include "DNPvPGameRoom.h" #include "DnApplySEWhenTargetNormalHitProcessor.h" #include "DnBubbleSystem.h" #include "DnObserverEventMessage.h" #include "DnBlockBlow.h" #include "DnParryBlow.h" #include "DnCooltimeParryBlow.h" #include "PvPZombieMode.h" #include "DNGameServerScriptAPI.h" #include "DnOrderMySummonedMonsterBlow.h" #include "IDnSkillUsableChecker.h" #include "DnTransformBlow.h" #include "DnBasicBlow.h" #include "DnCreateBlow.h" #ifdef PRE_ADD_EXPORT_DPS_INFORMATION #include "DnDPSReporter.h" #endif #if defined(PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP) #include "DnSkillTask.h" #endif // PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) #include "TotalLevelSkillSystem.h" #endif // PRE_ADD_TOTAL_LEVEL_SKILL #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif float CDnPlayerActor::s_fRecoverySPTime = 5.f; CDnPlayerActor::CDnPlayerActor( CMultiRoom *pRoom, int nClassID ) : CDnActor( pRoom, nClassID ) { m_pSession = NULL; CDnPlayerState::Initialize( m_nClassID ); CDnActionBase::Initialize( this ); MACP::Initialize( this ); m_cMovePushKeyFlag = 0; m_bBattleMode = true; m_nWorldLevel = 0; m_nComboDelay = 0; m_nComboCount = 0; m_nTotalComboCount = 0; m_fRecoverySPDelta = 0.f; m_bCompleteCutScene = false; m_bCheckCompleteCutScene = false; m_bSkipCutScene = false; m_bGhost = false; m_uiStateBlowProcessAfterBit = 0; m_afLastEquipItemSkillDelayTime = 0.0f; m_afLastEquipItemSkillRemainTime = 0.0f; m_dwSyncDatumTick = 0; m_dwSyncDatumSendTick = 0; m_nVoiceChannelID = 0; m_pPlayerSpeedHackChecker = new CDnPlayerSpeedHackChecker( this ); m_pPlayerDoNotEnterChecker = new CDnPlayerDoNotEnterChecker( this ); m_pPlayerPickupChecker = new CDnPlayerPickupChecker( this ); m_pPlayerSkillChecker = new CDnPlayerSkillChecker( this ); m_pPlayerActionChecker = new CDnPlayerActionChecker( this ); memset( m_bCashSelfDeleteWeapon, 0, sizeof(m_bCashSelfDeleteWeapon) ); memset( m_bWeaponViewOrder, 0, sizeof(m_bWeaponViewOrder) ); m_iNowMaxProjectileCount = 0; m_iReservedProjectileCount = 0; m_LastEscapeTime = 0; m_dwLastBasicShootActionTime = 0; m_dwLastBasicShootCoolTime = 0; m_dwLastChargeShootTime = 0; m_bCheckProjectileSignalTerm = true; m_bUpdatedProjectileInfoFromCmdAction = false; m_fFrameSpeed = 1.0f; m_bPlayerCannonMode = false; m_nSwapSingleSkinActorID = -1; m_nMonsterMutationTableID = -1; m_hSwapOriginalHandle.Identity(); m_pSwapOriginalAction = NULL; m_nDeathCount = 0; m_pBubbleSystem = new BubbleSystem::CDnBubbleSystem; this->RegisterObserver( m_pBubbleSystem ); m_bTempSkillAdded = false; m_iTempChangedJob = 0; m_nInvalidPlayerCheckCounter = 0; m_bForceEnableRideByTrigger = true; m_nVehicleEffectIndex = 0; m_bVehicleMode = false; m_vecEventEffectList.clear(); for( int i=0; i( m_hCannonMonsterActor.GetPointer() )->OnMasterPlayerActorDie(); } //¹®Àå ½ºÅ³È¿°ú ¸®¼Â DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TGLYPHSKILL ); if( pSox ) { for( int itr = 0; itr < CDnGlyph::GlyphSlotEnum_Amount; ++itr ) { if( m_hGlyph[itr] ) { if( CDnGlyph::PassiveSkill == pSox->GetFieldFromLablePtr( m_hGlyph[itr]->GetClassID(), "_GlyphType" )->GetInteger() ) { int nSkillID = pSox->GetFieldFromLablePtr( m_hGlyph[itr]->GetClassID(), "_SkillID" )->GetInteger(); DnSkillHandle hSkill = FindSkill( nSkillID ); if( hSkill ) hSkill->DelGlyphStateEffect( m_hGlyph[itr]->GetClassID() ); } } } } // ¿À¶ó ½ºÅ³ Á¤¸®. ´Ù¸¥ ¹öÇÁ·ù¿Í´Â ´Ù¸£°Ô ¿À¶ó´Â ½ÃÀüÇß´ø ij¸¯ÅͰ¡ Á×À¸¸é ´Ù¸¥ ij¸¯ÅÍ¿¡°Ô Àû¿ëµÇ´ø °ÍµéÀÌ Ç®·Á¾ß ÇÑ´Ù. // ¿À¶ó½ºÅ³, Åä±Û½ºÅ³ÀÌ ÄÑÁ® ÀÖ´Ù¸é ²¨ÁØ´Ù. if( IsEnabledToggleSkill() ) OnSkillToggle( m_hToggleSkill, false ); if( IsEnabledAuraSkill() ) OnSkillAura( m_hAuraSkill, false ); for( int i=0; i<2; i++ ) SAFE_RELEASE_SPTR( m_hCashWeapon[i] ); SAFE_RELEASE_SPTR( m_hSwapOriginalHandle ); SAFE_DELETE( m_pSwapOriginalAction ); SAFE_DELETE( m_pPlayerSkillChecker ); SAFE_DELETE( m_pPlayerActionChecker ); SAFE_DELETE( m_pPlayerDoNotEnterChecker ) ; SAFE_DELETE( m_pPlayerPickupChecker ); SAFE_DELETE( m_pPlayerSpeedHackChecker ); SAFE_DELETE( m_pBubbleSystem ); #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) SAFE_DELETE(m_pTotalLevelSkillSystem); #endif // PRE_ADD_TOTAL_LEVEL_SKILL } MAMovementBase* CDnPlayerActor::CreateMovement() { MAMovementBase* pMovement = new IBoostPoolMAWalkMovement(); return pMovement; } bool CDnPlayerActor::Initialize() { bool bResult = CDnActor::Initialize(); m_hObject->SetCollisionGroup( COLLISION_GROUP_DYNAMIC( 1 ) ); m_hObject->SetTargetCollisionGroup( COLLISION_GROUP_STATIC( 1 ) | COLLISION_GROUP_DYNAMIC( 2 ) | COLLISION_GROUP_DYNAMIC( 3 ) ); _ASSERT( m_pAggroSystem == NULL ); if( GetGameRoom()->bIsPvPRoom() ) { m_pAggroSystem = new CDNPvPPlayerAggroSystem( GetActorHandle() ); _ASSERT( m_pAggroSystem != NULL ); } m_mapTumbleHelper.insert( make_pair(GetElementIndex("Tumble_Front"), GetElementIndex("Move_Front")) ); m_mapTumbleHelper.insert( make_pair(GetElementIndex("Tumble_Back"), GetElementIndex("Move_Back")) ); m_mapTumbleHelper.insert( make_pair(GetElementIndex("Tumble_Left"), GetElementIndex("Move_Left")) ); m_mapTumbleHelper.insert( make_pair(GetElementIndex("Tumble_Right"), GetElementIndex("Move_Right")) ); // ¼Ò¼­¸®½º Â÷Áö ¹Ì»çÀϵµ ¾×¼ÇÅø°ú ¾×¼Ç½Ã½ºÅÛ¸¸ °®°í ±¸ÇöµÇ¾îÀÖÁö ¾Ê°í Ŭ¶ó¿¡¼­ ó¸®ÇÏ´Â ºÎºÐÀÌ ÀÖÀ¸¹Ç·Î ¼­¹öµµ ¸ÂÃçÁÙ ¼ö ¹Û¿¡ ¾ø´Ù. // ½Ã½ºÅÛ°ú´Â ¾à°£ ´Ù¸£°Ô µ¹¾Æ°¡¹Ç·Î ¸¶Âù°¡Áö·Î ¾×¼ÇÀ» À̾îÁÖ°í ¾×¼ÇÀÇ ÄðŸÀÓÀº Â÷Áö½Ã°£À¸·Î ¼³Á¤µÇ¾îÀÖ´Â 1.5ÃÊ·Î ÇÑ´Ù. // ´ëÇ¥·Î Move_Front ·Î¸¸ ¼ÂÆÃÇϵµ·Ï ÇØµµ µÈ´Ù. Ç٠üũ¿¡¼­ ¿¹¿Ü·Î È®ÀεDZ⸸ ÇÏ¸é µÈ´Ù.. m_mapTumbleHelper.insert( make_pair(GetElementIndex("ChargeShoot_Stand"), GetElementIndex("Charge_Front")) ); m_pBubbleSystem->Initialize( GetActorHandle() ); m_mapIcyFractionHitted.clear(); #ifdef PRE_FIX_GAMESERVER_PERFOMANCE m_FrameSkipCallSkillProcess.SetFramePerSec( 10.0f ); #endif // #ifdef PRE_FIX_GAMESERVER_PERFOMANCE #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) m_pTotalLevelSkillSystem = new CDnTotalLevelSkillSystem(GetMySmartPtr()); #endif // PRE_ADD_TOTAL_LEVEL_SKILL return bResult; } void CDnPlayerActor::Process( LOCAL_TIME LocalTime, float fDelta ) { EtVector3 vPrevPos = m_Cross.m_vPosition; CDnActor::Process( LocalTime, fDelta ); PROFILE_TIME_TEST_BLOCK_START( "CDnPlayerActor::Process" ); m_pBubbleSystem->Process( LocalTime, fDelta ); for( int i=0; i<2; i++ ) { if( m_hCashWeapon[i] ) m_hCashWeapon[i]->Process( LocalTime, fDelta ); } MAPartsBody::PreProcess( LocalTime, fDelta ); if( 0 < GetCantXZMoveSEReferenceCount() ) m_vAniDistance.x = m_vAniDistance.z = 0.0f; #ifdef PRE_ADD_MONSTER_CATCH if(!IsVehicleMode() && !m_hCatcherMonster ) #else if(!IsVehicleMode()) #endif // #ifdef PRE_ADD_MONSTER_CATCH m_pMovement->Process( LocalTime, fDelta ); MAPartsBody::Process( m_Cross, LocalTime, fDelta ); ProcessCombo( LocalTime, fDelta ); ProcessRecoverySP( LocalTime, fDelta ); m_pPlayerDoNotEnterChecker->Process( LocalTime, fDelta ); m_pPlayerSpeedHackChecker->Process( LocalTime, fDelta ); m_pPlayerPickupChecker->Process( LocalTime, fDelta ); m_pPlayerSkillChecker->Process( LocalTime, fDelta ); m_pPlayerActionChecker->Process( LocalTime, fDelta ); ProcessCompanion( LocalTime, fDelta ); ProcessNonLocalShootModeAction(); if(m_bRefreshTransformMode) RefreshTransformMode(); #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) if (m_pTotalLevelSkillSystem) m_pTotalLevelSkillSystem->Process(LocalTime, fDelta); #endif // PRE_ADD_TOTAL_LEVEL_SKILL PROFILE_TIME_TEST_BLOCK_END(); } void CDnPlayerActor::CmdPickupItem( PickupItemStruct* pStruct, DnDropItemHandle hDropItem/*=CDnDropItem::Identity()*/ ) { #if defined(_CH) if (m_pSession->GetFCMState() != FCMSTATE_NONE){ // 3½Ã°£ ÀÌ»ó °ÔÀÓÇÏ¸é ¾ÆÀÌÅÛ Áޱ⠸øÇÔ 090624 // m_pSession->SendPickUp(ERROR_FCMSTATE, -1, NULL, 0); return; } #endif // ¿ÉÁ®¹ö´Â PickUp ¸øÇÔ if( GetActorHandle() && GetActorHandle()->bIsObserver() ) return; // ¿î¿µÀÚ³­ÀÔµµ PickUp ¸øÇÔ if( m_pSession && m_pSession->bIsGMTrace() ) return; if( !CDnDropItem::IsActive(GetRoom()) ) return; DnDropItemHandle hResult; if( hDropItem ) hResult = hDropItem; else { _DANGER_POINT(); return; } if( hResult ) { if (hResult->IsReversionItem() && hResult->IsReversionLocked() == false) { DnActorHandle hBeneficiery; if (hResult->GetOwnerUniqueID() != -1) { hBeneficiery = CDnActor::FindActorFromUniqueID( GetRoom(), hResult->GetOwnerUniqueID() ); if (hBeneficiery) CDnItemTask::GetInstance(GetRoom()).PickUpItem( hBeneficiery, hResult, ITEMLOOTRULE_NONE ); return; } CDnItemTask::GetInstance(GetRoom()).PickUpItem( GetMySmartPtr(), hResult, ITEMLOOTRULE_NONE ); return; } if( hResult->GetOwnerUniqueID() != -1 ) { DnActorHandle hOwner = CDnActor::FindActorFromUniqueID( GetRoom(), hResult->GetOwnerUniqueID() ); if( hOwner ) { CDnItemTask::GetInstance(GetRoom()).PickUpItem( hOwner, hResult, ITEMLOOTRULE_NONE ); } return; } else { eItemRank Rank = CDnItem::GetItemRank( hResult->GetItemID() ); eItemTypeEnum Type = CDnItem::GetItemType( hResult->GetItemID() ); TPARTYITEMLOOTRULE LootType = ITEMLOOTRULE_NONE; TITEMRANK LootRank = m_pRoom->GetPartyItemLootRank(); switch( Type ) { case ITEMTYPE_INSTANT: LootType = ITEMLOOTRULE_NONE; break; default: if (LootRank == ITEMRANK_NONE ) LootType = m_pRoom->GetPartyItemLootRule(); else LootType = ( Rank >= LootRank ) ? ITEMLOOTRULE_RANDOM : m_pRoom->GetPartyItemLootRule(); break; } // µ·Àϰæ¿ìµµ ±×³É ³ë¸»·Î ȹµæÇÕ´Ï´Ù. if( hDropItem->GetItemID() == 0 ) LootType = ITEMLOOTRULE_NONE; TItemData *pItemData = g_pDataManager->GetItemData(hDropItem->GetItemID()); if (pItemData) { if (pItemData->cReversion == ITEMREVERSION_BELONG) LootType = ITEMLOOTRULE_NONE; } // ±¸¿ï¸ðµå¿¡¼­´Â °­Á¦·Î LootType ¼³Á¤ if( GetRoom() && static_cast(GetRoom())->bIsZombieMode() ) LootType = ITEMLOOTRULE_NONE; switch( LootType ) { case ITEMLOOTRULE_NONE: case ITEMLOOTRULE_OWNER: CDnItemTask::GetInstance(GetRoom()).PickUpItem( GetMySmartPtr(), hResult, LootType ); break; case ITEMLOOTRULE_RANDOM: { int nLiveCount = CDnPartyTask::GetInstance(GetRoom()).GetPartyUserCount(CDNGameRoom::ePICKUPITEM); if( nLiveCount == 0 ) return; int nResultOffset = _rand(GetRoom())%nLiveCount; int nOffset = 0; DnActorHandle hResultActor; int nPartyCount = CDnPartyTask::GetInstance(GetRoom()).GetUserCount(); for( int i=0; ibIsGMTrace() ) continue; #if defined _CH if (pSession->GetFCMState() != FCMSTATE_NONE) continue; #endif DnActorHandle hActor = pSession->GetActorHandle(); if( !hActor || hActor->IsDie() ) continue; if( nOffset == nResultOffset ) { hResultActor = hActor; break; } nOffset++; } if( hResultActor ) CDnItemTask::GetInstance(GetRoom()).PickUpItem( hResultActor, hResult, LootType ); } break; case ITEMLOOTRULE_LEADER: { int nPartyCount = CDnPartyTask::GetInstance(GetRoom()).GetUserCount(); DnActorHandle hResultActor; for( int i=0; ibLeader ) { hResultActor = ( pPartyStruct->pSession ) ? pPartyStruct->pSession->GetActorHandle() : CDnActor::Identity(); } } if( hResultActor ) CDnItemTask::GetInstance(GetRoom()).PickUpItem( hResultActor, hResult, LootType ); } break; case ITEMLOOTRULE_INORDER: { CDNUserSession *pSession = CDnPartyTask::GetInstance(GetRoom()).GetUserData(m_pRoom->GetCurrentItemLooterIdx()); if (pSession) { DnActorHandle hActor = pSession->GetActorHandle(); CDnItemTask::GetInstance(GetRoom()).PickUpItem( hActor, hResult, LootType ); } } break; } } } } void CDnPlayerActor::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex ) { switch( Type ) { case STE_Hit: { } break; case STE_Jump: { JumpStruct *pStruct = (JumpStruct *)pPtr; EtVector2 vVec( 0.f, 0.f ); if( 0 == GetCantXZMoveSEReferenceCount() ) { if( !pStruct->bIgnoreJumpDir ) { if( m_cMovePushKeyFlag & 0x01 ) vVec.x -= 1.f; if( m_cMovePushKeyFlag & 0x02 ) vVec.x += 1.f; if( m_cMovePushKeyFlag & 0x04 ) vVec.y += 1.f; if( m_cMovePushKeyFlag & 0x08 ) vVec.y -= 1.f; EtVec2Normalize( &vVec, &vVec ); } } // Á¡ÇÁ µ¿±âÈ­ [2010/11/09 semozz] // Á¡ÇÁÁß Àç Á¡ÇÁ°¡ µÉ¶§ ±âÁ¸ Velocity°ªÀ» ¸®¼ÂÇØ¾ß Çϴ°æ¿ì // Ŭ¶óÀÌ¾ðÆ®¿Í °°ÀÌ ¸®¼ÂÀÌ µÇ¾î¾ß Á¡ÇÁ½Ã°£ µ¿±âÈ­°¡ ¸Â¾ÆÁø´Ù. if( pStruct->bResetPrevVelocity ) { SetVelocityY( 0.f ); SetResistanceY( 0.f ); } Jump( pStruct->fJumpVelocity, vVec ); SetResistanceY( pStruct->fJumpResistance ); } return; case STE_CustomAction: { CustomActionStruct *pStruct = (CustomActionStruct *)pPtr; ResetCustomAction(); SetCustomAction( pStruct->szChangeAction, (float)pStruct->nChangeActionFrame ); } return; case STE_PickupItem: { } return; case STE_RebirthAnyPlayer: { // [2011/02/11 semozz] // ¾¾µå·¡°ï¸Ê¿¡¼­´Â ÆÄƼ ºÎȰ ¹æÁö.. CMultiRoom *pRoom = GetRoom(); if (!pRoom) break; eDragonNestType _dragonNestType = CDnWorld::GetInstance(pRoom).GetDragonNestType(); RebirthAnyPlayerStruct *pStruct = (RebirthAnyPlayerStruct*)pPtr; CDNUserSession *pSession = NULL; float fMinDist = FLT_MAX; for( DWORD i=0; ipSession ) continue; if( pParty->pSession == m_pSession ) continue; if( pParty->pSession->GetState() != SESSION_STATE_GAME_PLAY) continue; DnActorHandle hActor = pParty->pSession->GetActorHandle(); if( !hActor ) continue; CDnPlayerActor *pPlayer = (CDnPlayerActor *)hActor.GetPointer(); if( !pPlayer->IsDie() || !pPlayer->IsGhost() ) continue; if( pParty->nUsableRebirthCoin == 0 ) continue; EtVector3 vVec = *GetPosition() - *hActor->GetPosition(); float fDist = EtVec3LengthSq( &vVec ); if( fDist < fMinDist ) { fMinDist = fDist; pSession = pParty->pSession; } } if( !pSession || fMinDist > (float)( pStruct->nRadius * pStruct->nRadius ) ) break; if( m_pSession->GetStatusData()->wCashRebirthCoin <= 0 ) { GetUserSession()->SendRebirthCoin(ERROR_ITEM_REBIRTH_CASHCOIN_SHORT_FAIL, m_pPartyData->nUsableRebirthCoin, _REBIRTH_SELF, GetUserSession()->GetSessionID()); break; } CDnItemTask::GetInstance(GetRoom()).RequestRebirthCoinUseAnyPlayer( m_pSession, pSession ); UpdateRebirthPlayer(); } break; case STE_CancelChangeStandActionSE: { CDnChangeStandActionBlow::ReleaseStandChangeSkill( GetActorHandle(), false ); } break; case STE_CancelChangeStandEndActionSE: { CancelChangeStandEndActionSEStruct* pStruct = (CancelChangeStandEndActionSEStruct*)pPtr; CDnChangeStandActionBlow::ReleaseStandChangeSkill( GetActorHandle(), false, pStruct->szEndAction ); } break; case STE_TriggerEvent: { TriggerEventStruct *pStruct = (TriggerEventStruct *)pPtr; CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventArea", -1 ); CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "ActorHandle", GetSessionID() ); CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventID", pStruct->nEventID ); CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnActor::TriggerEvent", LocalTime, 0.f ); } break; case STE_ShootCannon: { ShootCannonStruct* pStruct = (ShootCannonStruct*)pPtr; if( IsCannonMode() ) { // Ŭ¶óÀÌ¾ðÆ®¿¡¼­ CS_CANNONROTATESYNC ÆÐŶÀ¸·Î º¸³»ÁØ TargetPosition À¸·Î ¹ß»çü¸¦ ¼ÂÆÃÇÑ´Ù. m_hCannonMonsterActor->UseSkill( pStruct->CannonMonsterSkillID ); } } break; // #29925 ÀÌ ½Ã±×³Î¿¡ ÁöÁ¤µÈ »óÅÂÈ¿°ú°¡ ¾øÀ¸¸é ÁöÁ¤µÈ ¾×¼ÇÀ» ½ÇÇà. case STE_ChangeActionSECheck: { ChangeActionSECheckStruct* pStruct = (ChangeActionSECheckStruct*)pPtr; if( false == IsAppliedThisStateBlow( (STATE_BLOW::emBLOW_INDEX)pStruct->nStateEffectID ) ) { SetActionQueue( pStruct->szChangeAction ); } } break; /* // Note: ÆÐŶº¸´Ù ½Ã±×³ÎÀÌ ´Ê°Ô 󸮵Ǿî Ŭ¶ó¿¡¼­ ¹ßµ¿µÈ ¾×¼Ç Áß ½ºÅ³ÀÌ ¾ÃÈ÷´Â °æ¿ì°¡ ÀÖÀ¸¹Ç·Î // Ŭ¶óÂÊ¿¡¼­ ÆÐŶÀ¸·Î º¸³»µµ·Ï ¼öÁ¤ÇÕ´Ï´Ù.. case STE_CanUseSkill: { CanUseSkillStruct* pStruct = (CanUseSkillStruct*)pPtr; m_bUseSignalSkillCheck = (pStruct->bUseSignalSkillCheck ? TRUE : FALSE); SetSignalSkillCheck( pStruct->CheckType, m_bUseSignalSkillCheck ); } break; */ case STE_OrderMySummonedMonster: { OrderMySummonedMonsterStruct* pStruct = (OrderMySummonedMonsterStruct*)pPtr; OrderUseSkillToMySummonedMonster(pStruct); } break; } CDnActor::OnSignal( Type, pPtr, LocalTime, SignalStartTime, SignalEndTime, nSignalIndex ); } void CDnPlayerActor::OnDrop( float fCurVelocity ) { if( IsAir() ) { if( !IsHit() ) { ////////////////////////////////////////////////////////////////////////// // #32977 - ž ½ºÇÇ´× ½ºÅ³À» ½ÃÀÛ ÇØ³õÀº »óÅ¿¡¼­ ž ½ºÇÇ´× ¾×¼ÇÀÇ ½Ã±×³ÎÀÌ Ã³¸® µÇ±âÀü // OnDropÀÌ È£Ã⠵Ǹé ž ½ºÇǴ׿¡ ÀÖ´Â STE_Jump°¡ 󸮰¡ µÇÁö ¾Ê¾Æ¼­ µ¿ÀÛÀÌ À̾îÁöÁö ¾Ê°Ô µÈ´Ù. // ±×·¡¼­ ÀÏ´Ü.. // ÇöÀç FrameÀÌ 0À̰í, STE_Jump½Ã±×³ÎÀÌ 0ÇÁ·¹ÀÓ¿¡ ÀÖÀ¸¸é _Landingµ¿ÀÛÀ¸·Î º¯°æÀ» ¸·°í // ÇöÀç µ¿ÀÛÀ» °è¼Ó À¯Áö Çϵµ·Ï ÇÑ´Ù. ////////////////////////////////////////////////////////////////////////// float fCurrentFrame = CDnActionBase::GetCurFrame(); float fPrevFrame = CDnActionBase::m_fPrevFrame; ActionElementStruct *pStruct = GetElement(GetCurrentAction()); if (pStruct) { bool hasJumpSignal = false; CEtActionSignal *pSignal = NULL; for (int i = 0; i < (int)pStruct->pVecSignalList.size(); ++i) { pSignal = pStruct->pVecSignalList[i]; if (pSignal && pSignal->GetSignalIndex() == STE_Jump) { hasJumpSignal = true; break; } } if (hasJumpSignal) { //STE_Jump°¡ ÀÖ°í, actionQueue°¡ ÀÖÀ¸¸é ½ºÅµ..(ÀÚµ¿À¸·Î ´ÙÀ½ ¾×¼ÇÀ¸·Î ¹Ù²î°ÚÁö?..) if (false == m_szActionQueue.empty()) { return; } //ÇöÀç ¾×¼ÇÀÌ STE_Jump¸¦ °¡Áö°í ÀÖ°í, 0ÇÁ·¹ÀÓÀ̸é STE_Jump È£ÃâµÉ ¼ö ÀÖµµ·Ï.. else if (false == m_szAction.empty() && fPrevFrame == 0.0f) { return; } } } ////////////////////////////////////////////////////////////////////////// char szStr[64]; sprintf_s( szStr, "%s_Landing", GetCurrentAction() ); if( IsExistAction( szStr ) ) { SetActionQueue( szStr, 0, 2.f, 0.f, true, false ); // ½ºÅ³ »ç¿ëÁßÀ϶© üÀÎ¾×¼Ç ¼ÂÆÃÇØÁØ´Ù. if( m_hProcessSkill ) { m_hProcessSkill->AddUseActionName( szStr ); m_hProcessSkill->OnChainInput( szStr ); } } else {// ¸¸¾à¿¡ ¾øÀ»°æ¿ì¿¡ Çϴÿ¡¼­ º´½ÅÁþÇϱ¸À־ ³Ö¾î³ñ´Ï´Ù. ÀÏ´ÜÀº ¸¶Ãç¼­ ³Ö¾îÁִ°ÅÀÓ if( GetVelocity()->y != 0.f ) SetActionQueue( "Stand", 0, 0.f, 0.f, true, false ); } SetMovable( false ); } else { std::string szAction; float fBlendFrame = 2.f; // ¶³¾îÁö´Â ¼Óµµ°¡ 10ÀÌ»óÀ̸é bigBounce·Î Çѹø ´õ ¶ç¾îÁØ´Ù. if( fCurVelocity < -6.f && m_HitParam.vVelocity.y != 0.f && abs(m_HitParam.vVelocity.y) > 0.1f ) { if( m_HitParam.vVelocity.y > 0.f ) { m_HitParam.vVelocity.y *= 0.6f; SetVelocityY( m_HitParam.vVelocity.y ); } else { // °¡¼Óµµ°¡ óÀ½ºÎÅÍ ¹Ù´ÚÀ¸·Î ÇâÇØÀÖ´Â °æ¿ì¿¡´Â µÚÁý¾îÁà¾ßÇÑ´Ù. m_HitParam.vVelocity.y *= -0.6f; if( m_HitParam.vResistance.y > 0.f ) m_HitParam.vResistance.y *= -1.f; SetVelocityY( m_HitParam.vVelocity.y ); if( m_HitParam.vVelocity.y > 0 && m_HitParam.vResistance.y <= 0 ) SetResistanceY( -15.0f ); else SetResistanceY( m_HitParam.vResistance.y ); } szAction = "Hit_AirBounce"; } else { szAction = "Down_SmallBounce"; fBlendFrame = 0.f; } SetActionQueue( szAction.c_str(), 0, fBlendFrame, 0.f, true, false ); } } } void CDnPlayerActor::OnStop( EtVector3 &vPosition ) { if( IsProcessSkill() ) return; CmdStop( "Stand" ); } void CDnPlayerActor::OnFall( float fCurVelocity ) { // #31056 Move À̰í Air ÀÌ¸é °øÁß¿¡¼­ À̵¿ÇÏ´Â ¾×¼ÇÀ̹ǷΠFall ó¸® ÇÏÁö ¾Ê´Â´Ù. (³ôÀº °÷¿¡¼­ ¶³¾îÁú ¶§ ž½ºÇÇ´× »ç¿ë) if( !(IsMove() && IsAir()) && (IsStay() || IsMove()) && ! IsFloorCollision() ) { // ¿òÁ÷¿©Áö´Â °¢µµµµ Ã¼Å©ÇØ¼­ °è´ÜµîÀ» ³»·Á¿Ã¶§ ¶³¾îÁ®º¸ÀÌ´Â°Í º¸Á¤Çغ¸¾Æ¿ä. EtVector3 vDir = *GetPosition() - *GetPrevPosition(); EtVec3Normalize( &vDir, &vDir ); float fDot = EtVec3Dot( &EtVector3( 0.f, 1.f, 0.f ), &vDir ); float fAngle = EtToDegree( EtAcos( fDot ) ); if( fCurVelocity < -5.f && fAngle > 155.f ) { ActionElementStruct *pStruct = GetElement( "Jump" ); if( pStruct ) { SetActionQueue( "Jump", 0, 6.f, (float)pStruct->dwLength / 2.f ); } } } } void CDnPlayerActor::OnDamage( CDnDamageBase *pHitter, SHitParam &HitParam, HitStruct *pHitStruct ) { #if defined( PRE_ADD_SECONDARY_SKILL ) if( GetUserSession() && GetUserSession()->GetSecondarySkillRepository() ) static_cast(GetUserSession()->GetSecondarySkillRepository())->CancelManufacture(); #endif // #if defined( PRE_ADD_SECONDARY_SKILL ) if( IsCannonMode() ) { HitParam.szActionName.clear(); HitParam.vViewVec = *GetLookDir(); HitParam.vResistance = EtVector3( 0.0f, 0.0f, 0.0f ); HitParam.vVelocity = EtVector3( 0.0f, 0.0f, 0.0f ); } int nSeed = CRandom::Seed(GetRoom()); _srand( GetRoom(), nSeed ); INT64 nTemp = GetHP(); CDnActor::OnDamage( pHitter, HitParam, pHitStruct ); INT64 nDamage = nTemp - GetHP(); INT64 biKillerCharDBID = 0; if( GetGameRoom() ) { DnActorHandle hHitter = pHitter ? pHitter->GetActorHandle() : CDnActor::Identity(); GetGameRoom()->OnDamage( GetActorHandle(), hHitter, nDamage ); if( GetGameRoom()->GetGameTask() ) GetGameRoom()->GetGameTask()->OnDamage( GetActorHandle(), hHitter, nDamage ); if (IsDie() && hHitter && hHitter->IsPlayerActor()){ CDnPlayerActor *pPlayer = (CDnPlayerActor *)hHitter.GetPointer(); biKillerCharDBID = pPlayer->GetUserSession()->GetCharacterDBID(); } } if( m_HitParam.bSuccessNormalDamage ) { m_nComboDelay = 0; m_nComboCount = 0; } UpdateAttackedCPPoint( pHitter, m_HitParam.HitType ); ResetCustomAction(); RequestDamage( pHitter, nSeed, nDamage ); switch( pHitter->GetDamageObjectType() ) { case DamageObjectTypeEnum::Actor: { DnActorHandle hActor = pHitter->GetActorHandle(); if( m_pAggroSystem ) m_pAggroSystem->OnDamageAggro( hActor, HitParam, (int)nDamage ); } break; } } void CDnPlayerActor::CmdMove( EtVector3 &vPos, const char *szActionName, int nLoopCount, float fBlendFrame ) { MovePos( vPos, false ); // #31940 ÆÐ¸µÀº »óÅÂÈ¿°ú°¡ µ¹¸é¼­ ÆÐ¸µ¾×¼ÇÀ» ³ª°¡°Ô ÇÏ´Â °ÍÀ̹ǷΠ¿òÁ÷À̸鼭 ÇÇ°ÝµÇ¾î ÆÐ¸µÀÌ ³ª¿Ã °æ¿ì // Ŭ¶ó¿¡¼­ °è¼Ó ¹æÇâ۸¦ ´©¸£°í À־ À̵¿ ÆÐŶÀÌ ¿À´Â°æ¿ì CS_CMDMOVE ÆÐŶÀÌ ¿Í¼­ ¿©±â¼­ Move_ ½Ã¸®Áî·Î ·Î ¾×¼ÇÀÌ ¹Ù²î¹Ç·Î ¿¹¿Üó¸®. if( m_szAction == "Skill_Parrying" || m_szActionQueue == "Skill_Parrying" ) return; SetActionQueue( szActionName, nLoopCount, fBlendFrame ); } void CDnPlayerActor::CmdStop( const char *szActionName, int nLoopCount, float fBlendFrame, float fStartFrame ) { MAMovementBase *pMovement = GetMovement(); if( !pMovement ) return; pMovement->ResetMove(); // #31940 ÆÐ¸µÀº »óÅÂÈ¿°ú°¡ µ¹¸é¼­ ÆÐ¸µ¾×¼ÇÀ» ³ª°¡°Ô ÇÏ´Â °ÍÀ̹ǷΠ¿òÁ÷À̸鼭 ÇÇ°ÝµÇ¾î ÆÐ¸µÀÌ ³ª¿Ã °æ¿ì // °ð¹Ù·Î ij¸¯ÅͰ¡ ¸ØÃ߸鼭 CS_CMDSTOP ÆÐŶÀÌ ¿Í¼­ ¿©±â¼­ Stand ·Î ¾×¼ÇÀÌ ¹Ù²î¹Ç·Î ¿¹¿Üó¸®. if( m_szAction == "Skill_Parrying" || m_szActionQueue == "Skill_Parrying" ) return; SetActionQueue( szActionName, nLoopCount, fBlendFrame, fStartFrame ); } void CDnPlayerActor::CmdPassiveSkillAction( int nSkillID, const char *szActionName, int nLoopCount /*= 0*/, float fBlendFrame /*= 3.f*/, float fStartFrame /*= 0.0f*/, bool bChargeKey /*= false*/, bool bCheckOverlapAction /*= true */, bool bOnlyCheck/* = false*/ ) { // Note: ÇൿºÒ°¡ÀÎ °æ¿ì ÆÐ½Ãºê ½ºÅ³ ³ª°¥ ¼ö ¾øÀ½. // SetAction() ÇÔ¼ö¿¡¼­ ¾×¼ÇÀÌ ¸·È÷±â ¶§¹®¿¡ ¾îÂ÷ÇÇ ¾È³ª°¡Áö¸¸ ½ºÅ³ »ç¿ëÀ¸·Î ÄðŸÀÓÀÌ µ¹¾Æ°¡¹Ç·Î ½Ã±×³Î 󸮸¦ ¸·´Â´Ù. if( GetCantActionSEReferenceCount() > 0 ) return; if( false == bOnlyCheck ) { DnSkillHandle hSkill = FindSkill( nSkillID ); if( !hSkill ) return; // Note: ¹ßÂ÷±â °°Àº °æ¿ì °°Àº ½ºÅ³ÀÌ ¹ßµ¿ Áß¿¡ ³¡ ºÎºÐ¿¡ ¶Ç ¹ßµ¿ µÇµµ·Ï ¾×¼ÇÅø¿¡ ¼³Á¤µÇ¾îÀ־ // °°Àº ½ºÅ³ÀÏÁö¸®µµ ²÷±â°í ³ª°¡µµ·Ï ÇÕ´Ï´Ù. if( m_hProcessSkill /*&& m_hProcessSkill != hSkill*/ ) { if( false == (IsEnabledAuraSkill() && m_hProcessSkill->IsAuraOn()) ) { m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.f ); } m_hProcessSkill.Identity(); } // ¼­¹öÂÊ¿¡¼­µµ ´©¸£°í Àִ Ű±â ‹š¹®¿¡ ¾×¼Ç ¹Ù²î±â Àü¿£ ½ºÅ³ÀÌ °è¼Ó ½ÇÇàµÇ´Â °ÍÀ¸·Î ó¸®. if( bChargeKey ) { hSkill->SetPassiveSkillLength( -1.0f ); } else { // ÆÐ½Ãºê ½ºÅ³ ¾×¼Ç¿¡ next ¾×¼Ç±îÁö ÀÖ´Â °æ¿ì °¨¾È. // next ¾×¼ÇÀº Ŭ¶óÀ̾ðÆ®ÂÊ¿¡¼­µµ Çϳª¸¸ ±âÁØ Àâ°í Àֱ⠶§¹®¿¡ ¼­¹ö¿¡¼­µµ Çϳª¸¸ ±âÁØ Àâ´Â´Ù. DWORD dwActionLength = 0; ActionElementStruct* pElement = GetElement( szActionName ); if( pElement ) { if( pElement->dwLength <= (DWORD)fStartFrame ) fStartFrame = pElement->dwLength*1.f; dwActionLength = pElement->dwLength - (DWORD)fStartFrame; } else { fStartFrame = 0.0f; } // #25042 Stand ¾×¼ÇÀÌ next ¾×¼ÇÀÎ °æ¿ì ÆÐ½Ãºê ½ºÅ³ÀÇ ¾×¼ÇÀÌ ¾Æ´Ï¹Ç·Î ½Ã°£À» Æ÷ÇÔ½ÃŰÁö ¾Ê´Â´Ù. if( pElement->szNextActionName != "Stand" && 0 == strstr( pElement->szNextActionName.c_str(), "_Landing") ) { ActionElementStruct* pNextElement = GetElement( pElement->szNextActionName.c_str() ); if( pNextElement ) dwActionLength += pNextElement->dwLength; } hSkill->SetPassiveSkillLength( (float)dwActionLength / s_fDefaultFps ); // Active TypeÀÇ ½ºÅ³(À̱۽º µð¼¾Æ®) °°Àº °æ¿ì Passive TypeÀ¸·Î ½ºÅ³À» »ç¿ë ÇÒ °æ¿ìµµ ÀÖ´Ù. // ÃßÈÄ¿¡ _CheckActionWithProcessPassiveActionSkill ¿¡¼­ ActionLength°¡ ÁøÇà ÁßÀÎÁö üũÇÏ°Ô µÇ¸é // Passive Type ÀÏ °æ¿ì ChaningPassiveSkillÀ» true·Î ¸¸µå´Âµ¥ Active TypeÀÌ¶ó¼­ false ÀÌ´Ù. // ±×·¡¼­ ¿©±â¼­ ChaningPassiveKillÀ» true·Î ¸¸µé¾î ÁØ´Ù. if( hSkill->GetSkillType() == CDnSkill::Active ) // Active À϶§¸¸ ¼³Á¤ÇØ ÁÝ´Ï´Ù. hSkill->SetChaningPassiveSkill( true ); } // ¾×Ƽºê ½ºÅ³ÀÌ InputHasPassiveSkill ·Î ÆÐŶÀÌ ¿ÓÀ» °æ¿ì UsableCheck ¸¦ ¹«½ÃÇØ¾ß ÇÑ´Ù. if( CDnSkill::Active == hSkill->GetSkillType() ) { m_bUseSignalSkillCheck = true; for( int i = 0; i < 3; ++i ) SetSignalSkillCheck( i, true ); } #ifdef PRE_FIX_GAMESERVER_PERFOMANCE // ¼­¹öÀÇ ÄðŸÀÓ ¿ÀÂ÷¸¦ °¨¾ÈÇØ¼­ 0.5ÃÊÀÇ ¿©À¯¸¦ µÎ°í ÀÖÁö¸¸, // Á¸À̵¿ÇÒ¶§³ª ±âŸ 0.5ÃÊ ÀÌ»ó Ŭ¶óÀÌ¾ðÆ®¿Í ¹ú¾îÁö´Â ´Ù¸¥ »õ·Î¿î °æ¿ìµéÀÌ »ý±æ ¼ö ÀÖÀ¸¹Ç·Î // ÃÖÁ¾ ½ºÅ³ »ç¿ëÇÑ Å¸ÀÓ ½ºÅÆÇÁ¸¦ Âï¾îµÎ¾î µ¥ÀÌÅÍ¿¡ ÁöÁ¤µÈ ½ºÅ³ÀÇ ÄðŸÀÓº¸Å¸ °£°ÝÀÌ Å©´Ù¸é // ¼­¹öÀÇ ½ºÅ³ °´Ã¼¿¡ ÀúÀåµÇ¾îÀÖ´Â ÄðŸÀÓÀ» ÃʱâÈ­ ½ÃÄÑÁÖµµ·Ï ÇÑ´Ù. (#19737) hSkill->UpdateSkillCoolTimeExactly(); #endif // #ifdef PRE_FIX_GAMESERVER_PERFOMANCE CDnSkill::UsingResult eResult = CanExecuteSkill( hSkill ); if( eResult == CDnSkill::UsingResult::Success ) { // m_nLastUsedSkill = hSkill->GetClassID(); // ExecuteSkill( hSkill, CDnActionBase::m_LocalTime, 0.f ); hSkill->FromInputHasPassive(); SetActionQueue( szActionName, nLoopCount, fBlendFrame, fStartFrame, bCheckOverlapAction ); } else { ((CDnPlayerSkillChecker*)m_pPlayerSkillChecker)->OnInvalidUseSkill( nSkillID, eResult ); } // ¾×Ƽºê ½ºÅ³ÀÌ InputHasPassiveSkill ·Î ÆÐŶÀÌ ¿ÓÀ» °æ¿ì UsableCheck ¸¦ ¹«½ÃÇÑ °Í ´Ù½Ã º¹±¸. if( CDnSkill::Active == hSkill->GetSkillType() ) { m_bUseSignalSkillCheck = false; for( int i = 0; i < 3; ++i ) SetSignalSkillCheck( i, false ); } // Ç÷¹À̾ »ç¿ëÇÏ´Â ÆÐ½Ãºê/Áï½Ã ½ºÅ³À» À§ÇØ ¾×¼Ç À̸§ ±âÀÔÇØ ÁÜ. hSkill->SetPassiveSkillActionName( szActionName ); } else SetActionQueue( szActionName, nLoopCount, fBlendFrame, fStartFrame, bCheckOverlapAction ); m_fDownDelta = 0.f; } // ÀÌÂÊ ÆÐŶ¿¡¼­ ±¸Á¶Ã¼°¡ º¯°æµÉ °æ¿ì PvP ³­ÀԽà Äڵ嵵 ¼öÁ¤ÀÌ ÇÊ¿äÇÏ´Ï Àú¿¡°Ô(±è¹ä) ¾Ë·ÁÁÖ¼¼¿ä. int CDnPlayerActor::CmdAddStateEffect( const CDnSkill::SkillInfo* pParentSkill, 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( pParentSkill ) g_Log.Log(LogType::_ERROR, L"[CDnActor::CmdAddStateEffect] SkillID:%d, STATE_BLOW:%d\r\n", pParentSkill->iSkillID, emBlowIndex ); else g_Log.Log(LogType::_ERROR, L"[CDnActor::CmdAddStateEffect] STATE_BLOW:%d\r\n", emBlowIndex); return -1; } int iID = CDnActor::CmdAddStateEffect( pParentSkill, emBlowIndex, nDurationTime, szParam, bOnPlayerInit, bCheckCanBegin , bEternity ); if( -1 == iID ) return -1; DnBlowHandle hAddedBlow = m_pStateBlow->GetStateBlowFromID( iID ); const CPacketCompressStream* pPacket = hAddedBlow->GetPacketStream( szParam, bOnPlayerInit ); Send( eActor::SC_CMDADDSTATEEFFECT, const_cast(pPacket) ); if( GetGameRoom() ) GetGameRoom()->OnCmdAddStateEffect( hAddedBlow->GetParentSkillInfo() ); CheckAndRegisterObserverStateBlow( hAddedBlow ); return iID; } void CDnPlayerActor::CmdRemoveStateEffect( STATE_BLOW::emBLOW_INDEX emBlowIndex, bool bRemoveFromServerToo /*= true */ ) { if( m_pStateBlow->IsApplied( emBlowIndex ) ) { if( bRemoveFromServerToo ) CDnActor::CmdRemoveStateEffect( emBlowIndex ); SendRemoveStateEffect( emBlowIndex ); } } void CDnPlayerActor::SendRemoveStateEffect( STATE_BLOW::emBLOW_INDEX emBlowIndex ) { BYTE pBuffer[32]; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &emBlowIndex, sizeof(STATE_BLOW::emBLOW_INDEX) ); Send( eActor::SC_CMDREMOVESTATEEFFECT, &Stream ); } void CDnPlayerActor::SendRemoveStateEffectGraphic( STATE_BLOW::emBLOW_INDEX emBlowIndex ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &emBlowIndex, sizeof(int) ); Send( eActor::SC_BLOW_GRAPHIC_ERASE, &Stream ); } void CDnPlayerActor::CmdToggleBattle( bool bBattleMode ) { if( bBattleMode == true ) { if( !m_hWeapon[0] ) { m_bBattleMode = false; return; } } if( bBattleMode != m_bBattleMode ) { SetBattleMode( bBattleMode ); bool bSkipAction = false; #if defined(PRE_ADD_50907) bool bSkipChangeAction = IsSkipChangeWeaponAction(); if (bSkipChangeAction == true) return; #endif // PRE_ADD_50907 if(m_bShootMode) { if( m_bBattleMode == true ) SetActionQueue( "MOD_PullOut_Weapon" ); else SetActionQueue( "MOD_PutIn_Weapon" ); // ShootMode´Â ÀüÅõ»óÅ¿¡¸¸ »ç¿ëÇϱ⶧¹®¿¡ Normal»óÅ¿¡¼­ ¹«±â¸¦ ²¨³»´Â ÇൿÀº GetchangeShootaction ¿¡¼­ ¼³Á¤ÇÏÁö ¸øÇϱ⶧¹®¿¡ ¿©±â¼­ ³Ö´Â´Ù. bSkipAction = true; } if(!bSkipAction) { if( !IsDie() ) { if( m_bBattleMode == true ) SetActionQueue( "PullOut_Weapon" ); else SetActionQueue( "PutIn_Weapon" ); } } } } void CDnPlayerActor::CmdAddExperience( TExpData &ExpData, int nLogCode, INT64 biFKey ) { int nExp = ExpData.nExperience; int nEventExp = ExpData.nEventExperience; int nPCBangExp = ExpData.nPcBangExperience; int nVIPExp = ExpData.nVIPExperience; int nPromoExp = ExpData.nPromotionExperience; TPlayerCommonLevelTableInfo* pPlayerCommonLevelTableInfo = g_pDataManager->GetPlayerCommonLevelTable(GetLevel()); if( pPlayerCommonLevelTableInfo ) { //¿©±â¼­ 1.5¹è Áõ°¡(Çѱºµ¥¿¡¼­ ÇØÁÖ´Â°Ô °ü¸®°¡ ¿ëÀÌÇÒµí....dyss) nExp = (int)(nExp * pPlayerCommonLevelTableInfo->fAddGainExp); nEventExp = (int)(nEventExp * pPlayerCommonLevelTableInfo->fAddGainExp); nPCBangExp = (int)(nPCBangExp * pPlayerCommonLevelTableInfo->fAddGainExp); nVIPExp = (int)(nVIPExp * pPlayerCommonLevelTableInfo->fAddGainExp); nPromoExp = (int)(nPromoExp * pPlayerCommonLevelTableInfo->fAddGainExp); } #if defined( PRE_USA_FATIGUE ) int iPwrExp = 0; if( nLogCode == DBDNWorldDef::CharacterExpChangeCode::DungeonMonster ) { nLogCode = DBDNWorldDef::CharacterExpChangeCode::Dungeon; if( m_pSession && m_pSession->bIsNoFatigueEnter() == true ) { int iTemp = nExp+ExpData.nItemExperience; nExp = (iTemp*g_pDataManager->GetNoFatigueExpRate())/100; #if defined( _WORK ) char szBuf[MAX_PATH]; sprintf_s( szBuf, "ºÏ¹ÌÇǷεµÀû¿ë Exp%d->%d", iTemp, nExp ); std::cout << szBuf << std::endl; #endif // #if defined( _WORK ) } else { iPwrExp = ((nExp+ExpData.nItemExperience)*(g_pDataManager->GetFatigueExpRate()-g_pDataManager->GetNoFatigueExpRate()))/100; int iTemp = nExp+ExpData.nItemExperience; nExp = (iTemp*g_pDataManager->GetFatigueExpRate())/100; #if defined( _WORK ) char szBuf[MAX_PATH]; sprintf_s( szBuf, "ºÏ¹ÌÇǷεµÀû¿ë Exp%d->%d", iTemp, nExp ); std::cout << szBuf << std::endl; #endif // #if defined( _WORK ) } } #endif // #if defined( PRE_USA_FATIGUE ) #if defined(_CH) if (m_pSession->GetFCMState() == FCMSTATE_HALF){ nExp = ExpData.nExperience / 2; nEventExp = (ExpData.nEventExperience > 0) ? ExpData.nEventExperience / 2 : 0; nPCBangExp = (ExpData.nPcBangExperience > 0) ? ExpData.nPcBangExperience / 2 : 0; nVIPExp = (ExpData.nVIPExperience > 0) ? ExpData.nVIPExperience / 2 : 0; nPromoExp = (ExpData.nPromotionExperience > 0) ? ExpData.nPromotionExperience / 2 : 0; ExpData.nItemExperience = (ExpData.nItemExperience>0) ? ExpData.nItemExperience/2 : 0; ExpData.nGuildExp = (ExpData.nGuildExp>0) ? ExpData.nGuildExp/2 : 0; } else if (m_pSession->GetFCMState() == FCMSTATE_ZERO){ nExp = 0; nEventExp = 0; nPCBangExp = 0; nVIPExp = 0; nPromoExp = 0; ExpData.nItemExperience = 0; ExpData.nGuildExp = 0; } #endif // _CH nExp += ExpData.nItemExperience; nExp += ExpData.nGuildExp; #if defined(PRE_ADD_WEEKLYEVENT) if (CDnWorld::GetInstance(GetRoom()).GetMapType() != EWorldEnum::MapSubTypeNest){ int nThreadID = GetGameRoom()->GetServerID(); float fEventValue = g_pDataManager->GetWeeklyEventValuef(WeeklyEvent::Player, GetClassID(), WeeklyEvent::Event_5, nThreadID); if (fEventValue != 0) nExp += (int)(nExp * fEventValue); } #endif // #if defined(PRE_ADD_WEEKLYEVENT) int nPrevLevel = GetLevel(); int nTotalExp = nExp + nEventExp + nPCBangExp + nVIPExp + nPromoExp; AddExperience( nTotalExp, nLogCode, biFKey ); //_KRÀÌ ¾Æ´Ï¸é pcbangexp´Â Ç×»ó 0ÀÌ´Ù. // ·¹º§¾÷ÀÌ µÇ¹ö¸®¸é ±¸Áö º¸³¾ÇÊ¿ä ¾øÁö ¸»ÀÔ´Ï´Ù. if( GetLevel() == nPrevLevel ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &m_nExperience, sizeof(int) ); Stream.Write( &nExp, sizeof(int) ); Stream.Write( &nEventExp, sizeof(int) ); Stream.Write( &nPCBangExp, sizeof(int) ); #if defined(PRE_ADD_VIP) Stream.Write( &nVIPExp, sizeof(int) ); #endif // #if defined(PRE_ADD_VIP) Stream.Write( &nPromoExp, sizeof(int) ); #if defined( PRE_USA_FATIGUE ) Stream.Write( &iPwrExp, sizeof(int) ); #endif // #if defined( PRE_USA_FATIGUE ) Send( eActor::SC_ADDEXP, GetMySmartPtr(), &Stream ); } } void CDnPlayerActor::CmdAddCoin( INT64 nCoin, int nLogCode, int nFKey, bool bSync ) { INT64 nChangeCoin = nCoin; #if defined( PRE_ADD_TOTAL_LEVEL_SKILL ) if( nLogCode == DBDNWorldDef::CoinChangeCode::PickUp ) { float fIncGoldRate = 0.0f; if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_266)) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex(STATE_BLOW::BLOW_266, vlBlows); { int nCount = (int)vlBlows.size(); for (int i = 0; i < nCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow && hBlow->IsEnd() == false) { fIncGoldRate += hBlow->GetFloatValue(); } } } nChangeCoin += (INT64)(nChangeCoin * fIncGoldRate); if( !m_pSession->CheckMaxCoin(nChangeCoin) ) return; } } #endif #if defined(_CH) if (m_pSession->GetFCMState() == FCMSTATE_HALF){ nChangeCoin = nCoin / 2; } else if (m_pSession->GetFCMState() == FCMSTATE_ZERO){ nChangeCoin = 0; } #endif // _CH #if defined( _GAMESERVER ) if( nLogCode != DBDNWorldDef::CoinChangeCode::PickUp ) g_Log.Log(LogType::_ERROR, m_pSession, L"CmdAddCoin PrevCoin=%I64d ChangeCoin=%I64d PickUpCoint=%I64d LogType=%d\r\n", m_pSession->GetCoin(), nChangeCoin, m_pSession->GetPickUpCoin(), nLogCode); #endif if( nLogCode == DBDNWorldDef::CoinChangeCode::PickUp ) { m_pSession->AddPickUpCoin( nChangeCoin ); #if defined( _WORK ) std::cout << nCoin << " Coin ȹµæ => ÃÑ " << m_pSession->GetPickUpCoin() << " Coin" << std::endl; #endif // #if defined( _WORK ) nLogCode = 0; // DB¿¡ ÀúÀåÇÏÁö ¾Ê±â À§ÇØ ´Ù½Ã ÃʱâÈ­ } // ¿©±â ÁÖÀÇ!! bSync ¶û AddCoin ÀÇ bWarehouse ´Â Ʋ¸®Áö¸¸ ¶µç ÆÐŶ º¸³½´Ù,¾Èº¸³½´Ù Â÷À̱⠶§¹®¿¡ °Á ¾´´Ù.¤»¤»¤»¤» ¿ì¾¾ -> ¹Ù²åÀ½ Send·Î... ¤¾¤¾¤¾ if( m_pSession && m_pSession->GetItem() ){ if (nChangeCoin > 0) m_pSession->AddCoin( nChangeCoin, nLogCode, nFKey, bSync ); else if (nChangeCoin < 0) m_pSession->DelCoin( -nChangeCoin, nLogCode, nFKey, bSync ); } } void CDnPlayerActor::OnDispatchMessage( CDNUserSession *pSession, DWORD dwActorProtocol, BYTE *pPacket ) { switch( dwActorProtocol ) { case eActor::CS_CMDMOVE: { CPacketCompressStream Stream( pPacket, 128 ); int nActionIndex; EtVector3 vPos, vXVec; EtVector2 vZVec, vLook; char cFlag; DWORD dwGap; int nMoveSpeed; Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &cFlag, sizeof(char) ); Stream.Read( &nMoveSpeed, sizeof(int) ); ActionElementStruct *pStruct = GetElement( nActionIndex ); if( pStruct == NULL ) break; m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); m_pPlayerSpeedHackChecker->OnSyncPosition( vPos ); #ifdef PRE_ADD_CHECK_MOVESPEED_HACK m_pPlayerSpeedHackChecker->OnSyncMoveSpeed( nMoveSpeed ); #endif if( CheckSkillAction(pStruct->szName.c_str() ) == true ) { ((CDnPlayerActionChecker*)m_pPlayerActionChecker)->OnInvalidAction(); break; } Look( vLook, false ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); SetPosition( vPos ); // SetMagnetPosition( vPos ); #ifdef _USE_VOICECHAT m_nVoiceRotate = (int)EtToDegree( acos( EtVec2Dot( &EtVector2( 0.f, 1.f ), &vZVec ) ) ); if( vZVec.x > 0.0f ) m_nVoiceRotate = 360 - m_nVoiceRotate; m_nVoiceRotate = (m_nVoiceRotate + 90) % 360; m_pSession->SetVoicePos((int)vPos.x, (int)vPos.y, (int)vPos.z, m_nVoiceRotate); #endif m_cMovePushKeyFlag = cFlag; float fXSpeed = 0.f, fZSpeed = 0.f; if( cFlag & 0x01 ) fXSpeed = -100000.f; if( cFlag & 0x02 ) fXSpeed = 100000.f; if( cFlag & 0x04 ) fZSpeed = 100000.f; if( cFlag & 0x08 ) fZSpeed = -100000.f; vPos += ( vXVec * fXSpeed ); vPos += ( EtVec2toVec3( vZVec ) * fZSpeed ); CmdMove( vPos, pStruct ? pStruct->szName.c_str() : "", -1, 8.f ); } break; case eActor::CS_CMDSTOP: { CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos; DWORD dwGap; bool bReset, bForce; Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &bReset, sizeof(bool) ); Stream.Read( &bForce, sizeof(bool) ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); m_pPlayerSpeedHackChecker->OnSyncPosition( vPos ); /* std::string szActionName = GetCurrentAction(); if( EtVec2Length( &( EtVector2( vPos.x, vPos.z ) - EtVector2( GetPosition()->x, GetPosition()->z ) ) ) > 100.f ) { if( GetState() != ActorStateEnum::Move ) szActionName = "Move_Front"; } CmdMove( vPos, szActionName.c_str(), -1, CDnActionBase::m_fQueueBlendFrame ); */ if( IsProcessSkill() && bForce ) CancelUsingSkill(); SetPosition( vPos ); OnStop( vPos ); #ifdef _USE_VOICECHAT m_pSession->SetVoicePos((int)vPos.x, (int)vPos.y, (int)vPos.z, m_nVoiceRotate); #endif } break; case eActor::CS_CMDACTION: { CPacketCompressStream Stream( pPacket, 128 ); int nActionIndex, nLoopCount; float fBlendFrame; EtVector3 vXVec, vPos; EtVector2 vLook, vZVec; DWORD dwGap; bool bFromStateBlow = false; bool bSkillChain = false; Stream.Read( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &fBlendFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.f ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &m_cMovePushKeyFlag, sizeof(char) ); Stream.Read( &bFromStateBlow, sizeof(bool) ); Stream.Read( &bSkillChain, sizeof(bool) ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); ResetMove(); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); Look( vLook ); SetMagnetPosition( vPos ); ActionElementStruct *pStruct = GetElement( nActionIndex ); if( pStruct == NULL ) break; if( bSkillChain ) { if( false == IsValidSkillChain( GetCurrentActionIndex(), nActionIndex ) ) return; } else { bool bCheckStandAction = CDnChangeStandActionBlow::CheckUsableAction( GetActorHandle(), true, pStruct->szName.c_str() ); if( IsProcessSkill() == true && CheckSkillAction( pStruct->szName.c_str() ) == true || bCheckStandAction == false ) { ActionElementStruct *pCurrentActionElement = GetElement( GetCurrentActionIndex() ); if( pCurrentActionElement ) { bool bCorrectInputAction = false; for( DWORD iSignal = 0; iSignal < pCurrentActionElement->pVecSignalList.size(); ++iSignal ) { CEtActionSignal* pSignal = pCurrentActionElement->pVecSignalList.at( iSignal ); if( STE_Input == pSignal->GetSignalIndex() ) { InputStruct* pInputStruct = (InputStruct*)(pSignal->GetData()); if( strcmp( pInputStruct->szChangeAction, pStruct->szName.c_str() ) == NULL ) { bCorrectInputAction = true; break; } } } if( bCorrectInputAction == false ) { ((CDnPlayerActionChecker*)m_pPlayerActionChecker)->OnInvalidAction(); return; } } } } if( m_pBasicAttackInfo && strstr(pStruct->szName.c_str(), "Attack") ) { DNVector(int) nVecCheckActionList; nVecCheckActionList.push_back( GetCurrentActionIndex() ); if( IsCustomAction() ) nVecCheckActionList.push_back( GetCustomActionIndex() ); // next ¾×¼ÇÀÌ ÀÖ´Â °æ¿ì¿£ 10 ÇÁ·¹ÀÓ Á¤µµÀÇ ¿©À¯¸¦ µÎ°í °ËÁõÇÒ ¸®½ºÆ®¿¡ Ãß°¡ÇØÁØ´Ù. // ¼­¹ö ÇÁ·¹ÀÓÀÌ ´À·Á¼­ next action À¸·Î stand Àâ¾Æ³õ°í ÀÔ·Â ¹Þ°Ô ÇØµµ ¼­¹ö¿¡¼­ // next ¾×¼Ç ¼ÂÆÃÀÌ ¾ÈµÇ¾î¼­ ÇÙÀ¸·Î °£ÁֵǴ °æ¿ì°¡ ÀÖ´Ù. ActionElementStruct* pCurrentActionElement = GetElement( GetCurrentActionIndex() ); if( pCurrentActionElement ) { if( 0 < pCurrentActionElement->szNextActionName.length() ) { // Ŭ¶óÀÌ¾ðÆ®°¡ ¾î¶»°Ô Á¶ÀÛÇÏ´À³Ä¿¡ µû¶ó ¼­¹ö¿ÍÀÇ ÇÁ·¹ÀÓ °ÝÂ÷°¡ Ä¿Áú ¼ö À־ ÀÏ´Ü ÇÁ·¹ÀÓüũ´Â ¼­¹ö¿¡¼­ ÇÒ ¼ö ¾øÀ¸¹Ç·Î »­. //if( pCurrentActionElement->dwLength - (DWORD)CDnActionBase::m_fFrame < 10 ) { int iNextActionIndex = GetElementIndex( pCurrentActionElement->szNextActionName.c_str() ); if( -1 < iNextActionIndex ) nVecCheckActionList.push_back( iNextActionIndex ); } } } // cmdaction À¸·Î ÆòŸ ÆÐŶÀ» ¸¶±¸ º¸³»´Â °æ¿ì, ÀüÀÌµÉ ¼ö ÀÖ´Â ¸ðµç ¾×¼ÇÀ» üũÇÔÀ¸·Î½á ±âº»ÀûÀ¸·Î ¸·Èú ¼ö ÀÖÀ¸¸ç, // ½ÇÁ¦·Î Ÿ°ÝÀÌ µÇ´Â ¾×¼ÇÀÇ ÇÁ·¹ÀÓÀº Á¶±Ý Áö³ª¾ß ³ª¿À¹Ç·Î cmdaction ÆÐŶ¿£ ÀÓÀÇÀÇ ÇÁ·¹ÀÓÀ¸·ÎºÎÅÍ ¾×¼ÇÀ» ½ÃÀÛÇÒ ¼ö ¾ø±â ¶§¹®¿¡ // ÀÌ ¹æ¹ýÀÌ À¯È¿ÇÏ´Ù. ÇÏÁö¸¸ ¹Ù·Î ¾Æ·¡ mixedaction Àº ÀÓÀÇ·Î ¾×¼Ç ½ÃÀÛ ÇÁ·¹ÀÓÀ» Á¤ÇÒ ¼ö ÀÖÀ¸¹Ç·Î ÇØ´ç ºÎºÐÀ» µû·Î ¸·¾Æ¾ß ÇÑ´Ù. bool bValid = false; for( DWORD k=0; k >::const_iterator iter = m_pBasicAttackInfo->mapBasicAttackInfo.find( nVecCheckActionList[k] ); if( iter != m_pBasicAttackInfo->mapBasicAttackInfo.end() ) { const vector& vlInputSignals = iter->second; for( int i = 0; i < (int)vlInputSignals.size(); ++i ) { const CDnActionSpecificInfo::S_BASIC_ATTACK_INPUT_SIGNAL_INFO& InputSignalInfo = vlInputSignals.at( i ); if( strstr( pStruct->szName.c_str(), InputSignalInfo.strChangeActionName.c_str() ) ) { bValid = true; break; } } } } if( !bValid ) { ((CDnPlayerActionChecker*)m_pPlayerActionChecker)->OnInvalidAction(); return; } } // ÀÏ¹Ý ½¸ ¾×¼ÇÀ̶ó¸é ÇöÀç ½ÃÁ¡¿¡ °¡´ÉÇÑ °ÍÀÎÁö ÀÎDz ½Ã±×³Î °£°ÝÀÇ ½Ã°£°ú üũ. if( m_pProjectileCountInfo ) { map::const_iterator iterCooltime = m_pProjectileCountInfo->mapBasicShootActionCoolTime.find( nActionIndex ); if( m_pProjectileCountInfo->mapBasicShootActionCoolTime.end() != iterCooltime ) { DWORD dwTerm = timeGetTime() - m_dwLastBasicShootActionTime; DWORD dwCoolTime = DWORD((float)m_dwLastBasicShootCoolTime/m_fFrameSpeed); if( dwTerm < dwCoolTime ) { // Á¤ÇØÁø ½Ã°£ °£°Ý ÀÌÇÏ·Î ÀÏ¹Ý °ø°Ý ÆÐŶÀÌ ¿ÔÀ½. ÇÙÀÔ´Ï´Ù.. #ifndef _FINAL_BUILD OutputDebug( "CDnPlayerActor-CS_CMDACTION: ¾×¼ÇÅø¿¡¼­ Á¤ÇØÁø ½Ã°£ °£°Ý ÀÌÇÏ·Î ÀÏ¹Ý ½¸ ¾×¼ÇÀÌ ¿ÔÀ½. ÇÙÀ¸·Î ÆÇ´Ü.\n" ); #endif // #ifndef _FINAL_BUILD return; } m_dwLastBasicShootActionTime = timeGetTime(); m_dwLastBasicShootCoolTime = iterCooltime->second; } } if( IsCustomAction() ) ResetCustomAction(); // ½ºÅ³ äÀÎÀÌ ¾Æ´Ñ °æ¿ì¶ó¸é ÇöÀç cmdaction ÆÐŶÀÌ ½ºÅ³¿¡¼­ »ç¿ëµÇ´Â ¾×¼ÇÀÎÁö üũÇÑ´Ù. #26467 // À§¿¡¼­ ½ºÅ³ üÀο¡ ´ëÇÑ ½Ã±×³Î µ¥ÀÌÅÍ °ËÁõÀÌ ´Ù ³¡³ª¾ß ÀÌÂÊÀ¸·Î È帧ÀÌ ¿À±â ¶§¹®¿¡ ¾È½ÉÇϰí È®ÀÎÇÏ¸é µÈ´Ù. if( false == bSkillChain ) _CheckProcessSkillActioncChange( pStruct->szName.c_str() ); CmdAction( pStruct->szName.c_str(), nLoopCount, fBlendFrame, false, false, bSkillChain ); // CS_CMDACTION ÆÐŶÀÌ ¿ÔÀ» ¶§ ¹Ù·Î ¾÷µ¥ÀÌÆ® ÇØÁÖµµ·Ï º¯°æ. _UpdateMaxProjectileCount( nActionIndex ); m_bUpdatedProjectileInfoFromCmdAction = true; // ¼­¹ö³ª Ŭ¶ó µÑ Áß¿¡ »óÅÂÈ¿°úÂÊ¿¡¼­ ¹ß»ý½ÃŲ ¾×¼Ç. if( bFromStateBlow ) m_pStateBlow->OnCmdActionFromPacket( pStruct->szName.c_str() ); // #ifdef _USE_VOICECHAT m_nVoiceRotate = (int)EtToDegree( acos( EtVec2Dot( &EtVector2( 0.f, 1.f ), &vZVec ) ) ); if( vZVec.x > 0.0f ) m_nVoiceRotate = 360 - m_nVoiceRotate; m_nVoiceRotate = (m_nVoiceRotate + 90) % 360; m_pSession->SetVoicePos((int)vPos.x, (int)vPos.y, (int)vPos.z, m_nVoiceRotate); #endif } break; case eActor::CS_CMDMIXEDACTION: { // Note: ¾×Ƽºê ÆÐ½Ãºê ½ºÅ³ »ç¿ë Áß¿¡ ÀÏ¹Ý ¾×¼ÇÀ» ÇÏ°Ô µÈ´Ù¸é Ã¼Å©ÇØ¼­ »ç¿ëÁßÀÎ ½ºÅ³À» Á¾·á ½ÃŲ´Ù. // »óÅÂÈ¿°ú°¡ ³²¾Æ¼­ ÀÏ¹Ý °ø°Ý¿¡µµ ¿µÇâÀ» ¹ÌÄ¡´Â °ÍÀ» ¸·±â À§Çؼ­. if( IsProcessSkill() ) { if( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) && m_hProcessSkill->GetDurationType() == CDnSkill::Instantly ) { m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.f ); m_hProcessSkill.Identity(); } } CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos; int nActionIndex, nMaintenanceBone, nActionBone; float fFrame, fBlendFrame; EtVector3 vLook; DWORD dwGap; Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Read( &nActionBone, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &nMaintenanceBone, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &fFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.f ); Stream.Read( &fBlendFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.f ); Stream.Read( &m_cMovePushKeyFlag, sizeof(char) ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); ActionElementStruct *pStruct = GetElement( nActionIndex ); if( pStruct == NULL ) break; // ±âº»ÀûÀ¸·Î cmdaction À¸·Î ³¯¾Æ¿À´Â Skill_ °ü·Ã ÆÐŶÀº À߸øµÈ °ÍÀÌ´Ù. (½ºÅ³ üÀÎ ÀÔ·ÂÀ» Á¦¿ÜÇϰí) // ÇöÀç µ¹¾Æ°¡´Â ¿¹¿Ü ¾×¼Ç ¸ðÀ½¿¡ ¾ø´Ù¸é ¹«½ÃÇÑ´Ù. if( CheckSkillAction(pStruct->szName.c_str()) == true ) { ((CDnPlayerActionChecker*)m_pPlayerActionChecker)->OnInvalidAction(); break; } bool bCheckStandAction = CDnChangeStandActionBlow::CheckUsableAction( GetActorHandle(), true, pStruct->szName.c_str() ); if( bCheckStandAction == false ) { ((CDnPlayerActionChecker*)m_pPlayerActionChecker)->OnInvalidAction(); return; } // ÀÏ¹Ý ½¸ ¾×¼ÇÀ̶ó¸é ÇöÀç ½ÃÁ¡¿¡ °¡´ÉÇÑ °ÍÀÎÁö ÀÎDz ½Ã±×³Î °£°ÝÀÇ ½Ã°£°ú üũ. // »õ·Î ¾×¼ÇÀ» ÃëÇÏ´Â °æ¿ì(0 ÇÁ·¹ÀÓÀ¸·Î ÆÐŶ ¿Â´Ù.)¿¡¸¸ ±âº» °ø°Ý ¾×¼Ç ÄðŸÀÓÀ» üũÇÑ´Ù. // ¸¸¾à ÇÙÀ» ½è´Ù¸é 0 ÇÁ·¹ÀÓÀ¸·Î º¸³»¸é ¾×¼Ç ÄðŸÀÓ¿¡ °É¸®°í, 0 ÇÁ·¹ÀÓ ÀÌ»óÀ» º¸³½´Ù¸é // ¹ß»çü °¹¼ö³ª ±âŸ ÇÙ°ü·Ã ÀÎÁõ Á¤º¸¸¦ ¾÷µ¥ÀÌÆ®¸¦ ÇØÁÖÁö ¾Êµµ·Ï ÇÑ´Ù. ±× µÚ·Î ½î´Â ¹ß»çü´Â ¹«È¿°¡ µÈ´Ù.. // cmdaction ÂÊÀº ¹«Á¶°Ç 0 ÇÁ·¹ÀÓÀ¸·Î ½ÃÀÛÇϹǷΠMIXEDACTION ¸¸ Ŭ¶ó¿¡¼­ º¸³»ÁÖ´Â ÇÁ·¹ÀÓÀ» üũÇÏ¸é µÈ´Ù. bool bActionCoolTimeChecked = false; if( m_pProjectileCountInfo ) { map::const_iterator iterCooltime = m_pProjectileCountInfo->mapBasicShootActionCoolTime.find( nActionIndex ); if( m_pProjectileCountInfo->mapBasicShootActionCoolTime.end() != iterCooltime ) { if( 0.0f == fFrame ) { DWORD dwTerm = timeGetTime() - m_dwLastBasicShootActionTime; DWORD dwCoolTime = DWORD((float)m_dwLastBasicShootCoolTime/m_fFrameSpeed); if( dwTerm < dwCoolTime ) { // Á¤ÇØÁø ½Ã°£ °£°Ý ÀÌÇÏ·Î ÀÏ¹Ý °ø°Ý ÆÐŶÀÌ ¿ÔÀ½. ÇÙÀÔ´Ï´Ù.. #ifndef _FINAL_BUILD OutputDebug( "CDnPlayerActor-CS_CMDMIXEDACTION: ¾×¼ÇÅø¿¡¼­ Á¤ÇØÁø ½Ã°£ °£°Ý ÀÌÇÏ·Î ÀÏ¹Ý ½¸ ¾×¼ÇÀÌ ¿ÔÀ½. ÇÙÀ¸·Î ÆÇ´Ü.\n" ); #endif // #ifndef _FINAL_BUILD return; } m_dwLastBasicShootActionTime = timeGetTime(); m_dwLastBasicShootCoolTime = iterCooltime->second; bActionCoolTimeChecked = true; } } } if( false == bActionCoolTimeChecked ) { // ÇÁ·¹ÀÓ °ªÀÌ ÀÖ´Â °æ¿ì¿£ ¿ö¸®¾î, Ŭ·¯¸¯µîÀÌ ÆòŸ ÇÑ ¹ø Çϰí À̵¿ÇÒ ¶§ÀÓ. ÀÌ ÆÐŶÀ» ÀÓÀÇÀÇ ÆòŸ¾×¼ÇÀ¸·Î hit ½Ã±×³Î ÀÖ´Â ÇÁ·¹ÀÓÀ¸·Î ¸¶±¸ // º¸³» °è¼Ó hit ÇÏ´Â ÇÙÀÌ ³ª¿Ã ¼ö ÀÖ¾î ¹æ¾îÇÑ´Ù. ¹æ¹ýÀº Áß°£Áß°£ CmdStop À̳ª CmdMove µîÀ¸·Î Stand ¾×¼ÇÀ¸·Î º¯°æÇϸ鼭 MixedAction À» º¸³»¸é // ¼­¹ö·Î¼­´Â °ËÁõÇÒ ¹æ¹ýÀÌ ¾øÀ¸¹Ç·Î ÄðŸÀÓÀ¸·Î üũ¸¦ ÇÑ´Ù.. LOCAL_TIME MixedActionCoolTime = 500; if( CDnActionBase::m_LocalTime - m_MixedActionTimeStamp < MixedActionCoolTime ) { if( CDnActionBase::m_LocalTime - m_MixedActionTimeStamp < 0 ) m_MixedActionTimeStamp = CDnActionBase::m_LocalTime; // ÀÏÁ¤ ½Ã°£ °£°Ý ÀÌ»óÀ¸·Î µé¾î¿À¸é ÇÙÀ¸·Î ÆÇ´Ü. return; } m_MixedActionTimeStamp = CDnActionBase::m_LocalTime; } std::string szAction = pStruct->szName; m_szActionBoneName = GetBoneName(nActionBone); m_szMaintenanceBoneName = GetBoneName(nMaintenanceBone); if( IsCustomAction() ) ResetCustomAction(); SetCustomAction( szAction.c_str(), fFrame ); // MixedAction Àº OnChangeAction() ÇÔ¼ö°¡ È£ÃâÀÌ ¾ÈµÇ¹Ç·Î ¾÷µ¥ÀÌÆ® ÇØÁÖ¾î¾ß ÇÔ. //_UpdateMaxProjectileCount( nActionIndex, true ); // ÇÁ·¹ÀÓ °ªÀÌ 0 ÀÌ ¾Æ´Ï¸é Ç÷¹À̾îÀÇ ¹æÇ⸸ ¹Ù²ãÁÖ´Â °æ¿ì´Ù. if( 0.0f == fFrame ) { _UpdateMaxProjectileCount( nActionIndex ); } } break; case eActor::CS_PROJECTILE: { // next ¾×¼ÇÀÌ ÀÖ°í °ÅÀÇ ³¡ ÇÁ·¹ÀÓ¿¡ ´Ù´Ù¶úÀ» °æ¿ì¿£ ¾×¼ÇÀÌ ¹Ù²î±â Á÷ÀüÀ̹ǷΠŬ¶ó¿¡¼­ // ¾×¼ÇÀ» ¹Ù²ã¼­ ¹ß»çü¸¦ ½î´õ¶óµµ ¼­¹ö´Â ¸øµû¶ó°¬À» ¼ö ÀÖ´Ù. ÇÑ¹ß ¿©À¯¸¦ ÁØ´Ù. // ÇÉÆ÷ÀÎÆ® ¼¦Ã³·³ ºü¸£°Ô loop ¾×¼ÇÀ» ÇàÇÏ´Â °æ¿ì ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù. #ifdef PRE_ADD_LOOP_PROJECTILE ActionElementStruct* pActionElement = GetElement( m_szAction.c_str() ); if( pActionElement && false == pActionElement->szNextActionName.empty() ) { // TODO: Ãß°¡ÀûÀ¸·Î IsCustomAction() À¸·Î mixed ¾Ö´Ï¸ÞÀ̼ÇÀ» Ã¼Å©ÇØ¼­ // Á¤È®ÇÏ°Ô ¹ß»çü ÀÎÁõ Á¤º¸¸¦ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù. Áö±Ý ÀÌ·¸°Ô¸¸ ÇØµÎ¸é µÚ·Î °¡¸é¼­ // È­»ì ½î¸é Move_Back ¸¸ ¾÷µ¥ÀÌÆ® µÇ¾î ¹ß»çü °¹¼ö´Â 0 ÀÌ µÊ. int iNextActionElementIndex = GetElementIndex( pActionElement->szNextActionName.c_str() ); if( GetCurrentActionIndex() == iNextActionElementIndex ) _UpdateMaxProjectileCount( iNextActionElementIndex ); } #endif // #ifdef PRE_ADD_LOOP_PROJECTILE CDnProjectile* pProjectile = CDnProjectile::CreatePlayerProjectileFromClientPacket( GetMySmartPtr(), pPacket ); } break; case eActor::CS_CMDLOOK: { CPacketCompressStream Stream( pPacket, 128 ); EtVector2 vLook, vZVec; EtVector3 vXVec; bool bForce; Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &bForce, sizeof(bool) ); Look( vLook, bForce ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); } break; case eActor::CS_USESKILL: { CPacketCompressStream Stream( pPacket, 128 ); int nSkillTableID = 0; int nEnchantSkillID = 0; // #38294 °ÔÀÓ ¼­¹ö¿¡¼­´Â »ç¿ëÇÒ ÀÏ ¾ø´Ù. ºô¸®Áö ¼­¹ö¿¡¼­ ex ½ºÅ³ »ç¿ë½Ã Á¤º¸¸¦ ¾Ë·ÁÁÖ±â À§ÇÑ ¿ëµµ. BYTE cLevel; EtVector2 vLook, vZVec; EtVector3 vXVec; #ifdef PRE_ADD_POSITION_SYNC_BY_SKILL_USAGE EtVector3 vPos; #endif bool bUseApplySkillItem = false; bool bAutoUseFromServer = false; // °×¼­¹ö¿¡¼± »ç¿ëÇÏÁö ¾Ê´Â µ¥ÀÌÅÍ. Stream.Read( &nSkillTableID, sizeof(int) ); Stream.Read( &cLevel, sizeof(char) ); Stream.Read( &bUseApplySkillItem, sizeof(bool) ); Stream.Read( m_abSignalSkillCheck, sizeof(m_abSignalSkillCheck) ); Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &bAutoUseFromServer, sizeof(bool) ); Stream.Read( &nEnchantSkillID, sizeof(int) ); #ifdef PRE_ADD_POSITION_SYNC_BY_SKILL_USAGE Stream.Read(&vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); SetPosition( vPos ); #endif Look( vLook, true ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); // ¿¬¼ÓÀ¸·Î À̾ ½ºÅ³ÀÌ »ç¿ëµÇ´Â °æ¿ì CanMove °¡ false ÀÎ °æ¿ì°¡ ÀÖÀ» ¼ö Àִµ¥ // ÀÌ·± °æ¿ì¿£ Movable ·Î ½ºÅ³ ¹ßµ¿Á¶°ÇÀ» °É¾î³õÀº °æ¿ì ¾ÃÈú ¼ö Àֱ⠶§¹®¿¡ true ·Î ¹Ù²ãÁÜ. // ÀÌ¹Ì Å¬¶óÀÌ¾ðÆ®¿¡¼± »ç¿ë°¡´É »óÅÂ¶ó¼­ ÆÐŶÀÌ ¿Â »óȲÀÌ´Ù. (Á¤»óÀûÀÎ °æ¿ì¶ó¸é) #14127 if( false == m_bMovable ) m_bMovable = true; //////////////////////////////////////////////////////////////////////////////////////////////////// // Note: °ÔÀÓ¼­¹ö¿¡¼­´Â ApplySkillÀÌ ºÙÀº ¾ÆÀÌÅÛ »ç¿ëÀ» »ç¿ëÇÑ Å¬¶óÂÊ¿¡¼­ º¸³»±â ¶§¹®¿¡ ±× ½ÃÁ¡¿¡ ÀÌ¹Ì Ã³¸®ÇÕ´Ï´Ù.. // ±×·±°í·Î ¿©±â¼± ¹«½Ã. ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®µé¿¡°Ô Àû¿ë½Ã۱â À§ÇÑ Ç÷¡±×ÀÔ´Ï´Ù. if( false == bUseApplySkillItem ) { bool bSkipAirCondition = false; if(CheckSkipAirCondition(nSkillTableID)) { SetSignalSkillCheck(2,true); bSkipAirCondition = true; } // »óŰ¡ AirÀΰæ¿ì¿¡ ´ÙÀ½¾×¼ÇÀÌ GroundMovable Á¶°ÇÀÌ ÀÖ´Ù¸é Ŭ¶ó¿Í ¼­¹öÀÇ °¸À¸·Î ÀÎÇØ Air üũ¿¡ °É·Á¼­ Ãë¼ÒµÇ´Â °æ¿ì°¡ ÀÖ´Ù. m_bUseSignalSkillCheck = (m_abSignalSkillCheck[ 0 ] || m_abSignalSkillCheck[ 1 ] || m_abSignalSkillCheck[ 2 ]); if( m_hProcessSkill ) { // #25154 ¿À¶ó ½ºÅ³Àº ¿À¶ó¸¦ ²°À» ¶§ onend µÈ´Ù. if( false == m_hProcessSkill->IsAuraOn() ) { m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.f ); } else { // #26002 ¿À¶ó ½ºÅ³ÀÌ Á¾·áµÈ °Å¶ó¸é ÀÚ±â Àڽſ¡°Ô Àû¿ëÇÏ´Â »óÅÂÈ¿°ú ¸®½ºÆ®¸¦ ºñ¿ìµµ·Ï ÇÑ´Ù. // ¾È±×·¯¸é ´Ù¸¥ ½ºÅ³À» »ç¿ëÇÒ ¶§ ¿µÇâÀ» ¹ÌÄ¡°Ô µÈ´Ù. // ¿ø·¡ ApplyStateEffect ½Ã±×³ÎÀ» »ç¿ëÇÏ´Â Àǵµ°¡ Áß°£¿¡ Çǰݽà ½ºÅ³ ¾×¼ÇÀÌ ²÷±â¸é Àû¿ëÀÌ ¾ÈµÇ°Ô ÇÏ´Â °ÍÀ̹ǷÎ, // À¯Àú°¡ °ð¹Ù·Î ´Ù¸¥ ½ºÅ³À» »ç¿ëÇØ¼­ ÀÚ±â Àڽſ¡°Ô Àû¿ëÇÏ´Â »óÅÂÈ¿°ú ½Ã±×³ÎÀÌ µ¹±â Àü¿¡ ¾×¼ÇÀÌ ¹Ù²î¸é // ´ç¿¬È÷ »óÅÂÈ¿°ú°¡ Àû¿ë ¾ÈµÇ°Ô µÇ¹Ç·Î ¾×¼Ç µðÀÚÀÎÀ» ÇÒ ¶§ À̺κÐÀÌ °í·ÁµÇ¾î ÀÖ´Ù´Â ÀüÁ¦ ÇÏ¿¡ ÀÌ·¸°Ô ó¸®ÇÑ´Ù. if( IsEnabledAuraSkill() ) ClearSelfStateSignalBlowQueue(); } m_hProcessSkill.Identity(); } if (GetActorHandle() && GetActorHandle()->IsAppliedThisStateBlow(STATE_BLOW::BLOW_345)) //rlkt_mechanicMODE { if (IsExistSkill(nSkillTableID, cLevel) == false) AddSkill(nSkillTableID, cLevel); } if (IsExistSkill(nSkillTableID, cLevel) == false) { ((CDnPlayerSkillChecker*)m_pPlayerSkillChecker)->OnInvalidUseSkill(nSkillTableID, CDnSkill::UsingResult::NoExistSkill); // Hack!!! break; } #if defined( PRE_FIX_CHANGESTAND_HACK ) CDnChangeStandActionBlow::ReleaseStandChangeSkill( GetActorHandle(), true ); #endif CDnSkill::UsingResult eResult = UseSkill( nSkillTableID ); if( eResult != CDnSkill::UsingResult::Success ) { // ÄðŸÀÓ ºÎÁ·À¸·Î ÀÎÇØ ½ºÅ³ »ç¿ë ½ÇÆÐµÇ¸é ÇÙÀ¸·Î ÆÇ´Ü. // ³ª¸ÓÁö´Â Ŭ¶ó¿¡¼­ ½ºÅ³ »ç¿ëÇÏ´Â ¼ø°£ ÀÌ¹Ì ¼­¹ö¿¡¼­ ¸ÂÀº »óÅ·ΠÆÇ´ÜÇÏ¿© Ŭ¶óÀÌ¾ðÆ®·Î °á°ú¸¦ Å뺸. // Ŭ¶óÀÌ¾ðÆ® ÂÊ¿¡¼­´Â ÄðŸÀÓÀ» ¸®¼Â½ÃŲ´Ù. ((CDnPlayerSkillChecker*)m_pPlayerSkillChecker)->OnInvalidUseSkill( nSkillTableID, eResult ); switch( eResult ) { case CDnSkill::FailedByCooltime: break; case CDnSkill::FailedByUsableChecker: { #ifdef PRE_FIX_69469 if( GetProcessSkill() ) CancelUsingSkill(); SetAction( "Stand", 0.f, 3.f ); #endif const char* pCurrentAction = GetCurrentAction(); int iCurrentActionIndex = GetElementIndex( pCurrentAction ); BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream LocalStream( pBuffer, 32 ); LocalStream.Write( &nSkillTableID, sizeof(int) ); LocalStream.Write( &eResult, sizeof(CDnSkill::UsingResult) ); LocalStream.Write( &iCurrentActionIndex, sizeof(int) ); Send( eActor::SC_SKILLUSING_FAILED, &LocalStream ); } break; } } if(bSkipAirCondition) SetSignalSkillCheck(2,false); // ´Ù½Ã ÇØÁ¦ÇØÁØ´Ù. // ¸¸¾à Àåºñ¾ÆÀÌÅÛ ½ºÅ³À̶ó¸é, if( m_hProcessSkill && m_hProcessSkill->IsEquipItemSkill() ) { m_afLastEquipItemSkillDelayTime = m_hProcessSkill->GetDelayTime(); m_afLastEquipItemSkillRemainTime = m_hProcessSkill->GetElapsedDelayTime(); } m_bUseSignalSkillCheck = false; ZeroMemory( m_abSignalSkillCheck, sizeof(m_abSignalSkillCheck) ); } } break; case eActor::CS_VIEWSYNC: { if( GetGameRoom() && GetGameRoom()->GetGameTask() && !GetGameRoom()->GetGameTask()->IsSyncComplete() ) break; CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos, vXVec; EtVector2 vZVec, vLook; DWORD dwGap; Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); Look( vLook, false ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); m_pPlayerSpeedHackChecker->OnSyncPosition( vPos ); SetPosition( vPos ); // SetMagnetPosition( vPos ); } break; case eActor::CS_CMDTOGGLEBATTLE: { CPacketCompressStream Stream( pPacket, 128 ); bool bBattle; Stream.Read( &bBattle, sizeof(bool) ); CmdToggleBattle( bBattle ); } break; case eActor::CS_CMDPASSIVESKILLACTION: { CPacketCompressStream Stream( pPacket, 128 ); int nActionIndex, nLoopCount, nSkillID; BYTE cLevel; float fBlendFrame; float fStartFrame; EtVector3 vXVec, vPos; EtVector2 vLook, vZVec; bool bChargeKey = false; Stream.Read( &nSkillID, sizeof(int)); Stream.Read( &cLevel, sizeof(char) ); Stream.Read( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Stream.Read( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &fBlendFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.f ); Stream.Read( &fStartFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.0f ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); Stream.Read( &m_cMovePushKeyFlag, sizeof(char) ); Stream.Read( &bChargeKey, sizeof(bool) ); bool bOnlyCheck = false; Stream.Read( &bOnlyCheck, sizeof(bool) ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); ResetMove(); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); Look( vLook ); //SetMagnetPosition( vPos ); SetPosition( vPos ); ActionElementStruct *pStruct = GetElement( nActionIndex ); if( pStruct == NULL ) { // Hack!! break; } // ÇÙüũ¸¦ À§ÇØ Ä¿½ºÅÒ ¾×¼Ç Á¤º¸µµ ÇÊ¿äÇϹǷΠ¸î ÁÙ ¾Æ·¡¿¡¼­ Á¤º¸ »©³»°í ¸®¼ÂÇÕ´Ï´Ù. //if( IsCustomAction() ) ResetCustomAction(); // Tumble ·ù ¾×¼ÇÀº ¼­¹ö¿¡¼­ Move ¾×¼Ç ÁßÀÌ ¾Æ´Ï±â ¶§¹®¿¡ ¾Æ·¡ ÇÙüũ¿¡ °É·Á ½ÇÇàÀÌ ¾ÈµÈ´Ù. // Tumble ¾×¼Ç ¿äûÀÌ ¿©±â·Î ¿ÔÀ» ¶§ ¼­¹ö¿¡¼­ Stand ¾×¼Ç »óÅÂÀÎ ÀÌÀ¯´Â ÀÌ ÆÐŶÀÌ ¿À±â Àü¿¡ // CMDSTOP ÆÐŶÀÌ ¸ÕÀú ¿À±â ‹š¹®ÀÌ´Ù. Tumble ·Î ÀüÀÌÇÒ ¼ö ÀÖ´Â ½Ã±×³ÎÀº Move ¾×¼Ç¿¡ Àֱ⠶§¹®¿¡ // ÇÙüũ¿¡ °É¸®°Ô µÈ´Ù. ÇöÀç·Î½ã ¼­¹ö¿¡¼­ ÆÇ´ÜÇÒ ¼ö ¾ø´Â ºÎºÐÀ̹ǷΠTumble ·ù ¾×¼ÇÀº ±×³É Åë°ú½ÃŲ´Ù. // ´Ù¸¸ Ŭ¶ó¿¡¼­ ¿Â skillid ¸¦ ¹ÏÀ» ¼ö ¾øÀ¸¹Ç·Î Tumble ·ù ¾×¼ÇÀÌ ¿ÔÀ» ¶© °ü·ÃµÈ ÆÐ½Ãºê ½ºÅ³ id ·Î ¹Ù²ã¼­ // Èê·Áº¸³»ÁØ´Ù. ±×·¯¸é, ½ºÅ³ÀÇ ÄðŸÀÓÀ̳ª º¸À¯ ¿©ºÎ´Â CmdInputHasPassiveSkill ¿¡¼­µµ Ã¼Å©ÇØ¼­ ÀÓÀÇ·Î »ç¿ëÇÏ´Â °æ¿ì¿£ °É¸®°Ô µÈ´Ù. int iCurrentActionIndex = GetCurrentActionIndex(); vector vlCheckActionIndices; vlCheckActionIndices.push_back( iCurrentActionIndex ); // #23245 ÆÐ¸µ ½Ã¸®Áîµé ó·³ »óÅÂÈ¿°ú¿¡¼­ Á÷Á¢ ¾×¼ÇÀ» Á¶ÀÛÇÏ´Â °æ¿ì ¼­¹öÂÊ¿¡¼­ ¾×¼Ç Å¥¿¡¸¸ ³Ö°í ÇÁ·¹ÀÓ °»½ÅÀÌ // µÇ±â Àü¿¡ Ŭ¶óÀ̾𿡼­ ÀÌ¹Ì ¹Ù²ï ¾×¼Ç¿¡¼­ÀÇ ÆÐ½Ãºê ½ºÅ³ »ç¿ë ¿äûÀÌ ¿À´Â °æ¿ì°¡ ÀÖÀ¸¹Ç·Î queue µÈ ¾×¼Ç±îÁö °¨¾ÈÇÑ´Ù. int iQueuedActionIndex = -1; if( false == m_szActionQueue.empty() ) { iQueuedActionIndex = GetElementIndex( m_szActionQueue.c_str() ); vlCheckActionIndices.push_back( iQueuedActionIndex ); } // mixed action ÁßÀ̶ó¸é ÇØ´ç ¾×¼Ç±îÁö Æ÷ÇÔ. if( IsCustomAction() ) { int iCustomActionIndex = GetCustomActionIndex(); vlCheckActionIndices.push_back( iCustomActionIndex ); ResetCustomAction(); } // ÇöÀç ¾×¼ÇÀÌ cmdstop À¸·Î ÀÎÇØ stand ÀÏ ¶§¸¸ tumblehelper ¸¦ »ç¿ëÇÑ´Ù. bool bNowStand = (0 != strstr( m_szAction.c_str(), "Stand" )); // À̵¿ ÁßÀÎ °æ¿ìµµ ¹æÇâ °ü°è¾øÀÌ ¾î¶² ´ýºí¸µ ¾×¼ÇÀÌ¶óµµ ¼öÇàÇÒ ¼ö ÀÖµµ·Ï Move »óÅ¿¡¼­µµ tunble helper ¸¦ »ç¿ëÇÑ´Ù. // Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ¿·À¸·Î À̵¿ÇÏ´Ù°¡ °ð¹Ù·Î shift+¾Õ ¹æÇâŰ·Î ´Ù¸¥ ¹æÇâÀ¸·Î ´ë½¬Çϵµ·Ï ¿©±â¿¡ ÆÐŶÀÌ ¿À´Â °æ¿ì°¡ À־ °¨¾ÈÇÑ´Ù. // ¾È ±×·¯¸é ÇöÀç ¹æÇâÀ¸·ÎÀÇ move ¾×¼Ç ½Ã±×³Î¿¡ °É¸®Áö ¾Ê¾Æ¼­ ÇÙÀ¸·Î °£ÁÖµÇ¾î »ç¿ëµÇÁö ¾Ê´Â´Ù. bool bNowMove = IsMove(); bool bValid = false; for( int k = 0; k < (int)vlCheckActionIndices.size(); ++k ) { int iCheckActionIndex = vlCheckActionIndices.at( k ); if( bNowStand || bNowMove ) { map::iterator iterTumble = m_mapTumbleHelper.find( nActionIndex ); if( m_mapTumbleHelper.end() != iterTumble ) { // ¾Æ¹« À̵¿ ¾×¼Ç¿¡¼­ Tumble ÀÌ °¡´ÉÇϹǷΠÇöÀç ¾×¼ÇÀ» À̰ɷΠ¼ÂÆÃÇØÁÖ¾î¾ß Tumble ÀÌ Ç٠üũ¿¡¼­ valid ÇÏ°Ô ¶³¾îÁø´Ù. iCheckActionIndex = iterTumble->second; } } if( !m_pPassiveSkillInfo || ( m_pPassiveSkillInfo && m_pPassiveSkillInfo->mapPassiveSkillInfo.empty() ) ) continue; // ¿ì¼± ÆÐŶÀ¸·Î ¿Â ¾×¼ÇÀÌ ÇöÀç ¾×¼Ç¿¡¼­ inputhaspassive ½ºÅ³·Î ÀüÀÌ µÉ ¼ö ÀÖ´ÂÁö È®ÀÎ. map >::const_iterator iter = m_pPassiveSkillInfo->mapPassiveSkillInfo.find( iCheckActionIndex ); if( m_pPassiveSkillInfo->mapPassiveSkillInfo.end() != iter ) { const vector& vlPassiveSkillSignalInfos = iter->second; // ¸ÕÀú ¾×¼ÇÀ̸§ÀÌ Á¤È®È÷ ÀÏÄ¡ÇÏ´Â °ÍÀÌ ÀÖ´Ù¸é ÇØ´ç ½Ã±×³ÎÀÌ ¿ì¼±À̰í, ¹®ÀÚ¿­ Æ÷ÇԵǴ °ÍÀº ±× ´ÙÀ½ ¼øÀ§ÀÌ´Ù. for( int i = 0; i < (int)vlPassiveSkillSignalInfos.size(); ++i ) { const CDnActionSpecificInfo::S_PASSIVESKILL_SIGNAL_INFO& PassiveSkillInfo = vlPassiveSkillSignalInfos.at( i ); if( PassiveSkillInfo.strChangeActionName == pStruct->szName || PassiveSkillInfo.strEXSkillChangeActionName == pStruct->szName ) { // Ŭ¶ó·ÎºÎÅÍ ¿Â ¿äû¿¡ ÀÖ´Â ¾×¼Ç À̸§ÀÌ ÇöÀç ¾×¼Ç¿¡¼­ ÀüÀÌµÉ ¼ö ÀÖ´Â ÆÐ½Ãºê ½ºÅ³ ¾×¼ÇÀÌÁö¸¸ // º¸À¯Çϰí ÀÖ´Â ÆÐ½Ãºê ½ºÅ³ÀÎÁö Çѹø ´õ üũÇÑ´Ù. nSkillID = PassiveSkillInfo.iSkillID; if( IsExistSkill( PassiveSkillInfo.iSkillID ) ) { // °­È­ ÆÐ½Ãºê ½ºÅ³·Î ÆÐ½Ãºê ½ºÅ³ÀÌ °­È­°¡ µÈ °æ¿ì. // °­È­ ÆÐ½Ãºê ½ºÅ³ÀÇ ¾×¼ÇÀÌ ÆÐŶÀ¸·Î ¿Í¾ß Á¤»ó. DnSkillHandle hSkill = FindSkill( PassiveSkillInfo.iSkillID ); if( hSkill->IsEnchantedSkill() ) { if( PassiveSkillInfo.strEXSkillChangeActionName == pStruct->szName ) bValid = true; } else bValid = true; // Â÷Áö¼¦Àΰæ¿ì¿£ ¾×¼ÇÀÇ ÄðŸÀÓÀ» µû·Î ÃøÁ¤ÇÑ´Ù. if( strstr( pStruct->szName.c_str(), "ChargeShoot_" ) ) { if( timeGetTime() - m_dwLastChargeShootTime < 1500 ) { // Â÷Áö¼¦ ¾×¼ÇÀ» ÆÐ½Ãºê ½ºÅ³ ÆÐŶÀ¸·Î °è¼Ó ³¯¸®´Â ÇÙÀÓ. bValid = false; } else m_dwLastChargeShootTime = timeGetTime(); } } break; } } // ÀÏÄ¡ÇÏ´Â ¾×¼Ç À̸§À» ãÁö ¸øÇÑ °æ¿ì. if( false == bValid ) { for( int i = 0; i < (int)vlPassiveSkillSignalInfos.size(); ++i ) { const CDnActionSpecificInfo::S_PASSIVESKILL_SIGNAL_INFO& PassiveSkillInfo = vlPassiveSkillSignalInfos.at( i ); if( strstr( pStruct->szName.c_str(), PassiveSkillInfo.strChangeActionName.c_str() ) ) // ¼Ò¼­¸®½º´Â _Book, _Orb ÀÌ·±°Ô ºÙ±â ¶§¹®¿¡ Æ÷ÇÔ¿©ºÎ·Î üũÇÑ´Ù. { // Ŭ¶ó·ÎºÎÅÍ ¿Â ¿äû¿¡ ÀÖ´Â ¾×¼Ç À̸§ÀÌ ÇöÀç ¾×¼Ç¿¡¼­ ÀüÀÌµÉ ¼ö ÀÖ´Â ÆÐ½Ãºê ½ºÅ³ ¾×¼ÇÀÌÁö¸¸ // º¸À¯Çϰí ÀÖ´Â ÆÐ½Ãºê ½ºÅ³ÀÎÁö Çѹø ´õ üũÇÑ´Ù. nSkillID = PassiveSkillInfo.iSkillID; if( IsExistSkill( PassiveSkillInfo.iSkillID ) ) { // °­È­ ÆÐ½Ãºê ½ºÅ³·Î ÆÐ½Ãºê ½ºÅ³ÀÌ °­È­°¡ µÈ °æ¿ì. // °­È­ ÆÐ½Ãºê ½ºÅ³ÀÇ ¾×¼ÇÀÌ ÆÐŶÀ¸·Î ¿Í¾ß Á¤»ó. DnSkillHandle hSkill = FindSkill( PassiveSkillInfo.iSkillID ); if( hSkill->IsEnchantedSkill() ) { if( PassiveSkillInfo.strEXSkillChangeActionName == pStruct->szName ) bValid = true; } else bValid = true; // Â÷Áö¼¦Àΰæ¿ì¿£ ¾×¼ÇÀÇ ÄðŸÀÓÀ» µû·Î ÃøÁ¤ÇÑ´Ù. if( strstr( pStruct->szName.c_str(), "ChargeShoot_" ) ) { if( timeGetTime() - m_dwLastChargeShootTime < 1500 ) { // Â÷Áö¼¦ ¾×¼ÇÀ» ÆÐ½Ãºê ½ºÅ³ ÆÐŶÀ¸·Î °è¼Ó ³¯¸®´Â ÇÙÀÓ. bValid = false; } else m_dwLastChargeShootTime = timeGetTime(); } } } if( bValid ) break; } } if( bValid ) break; } } #if defined( PRE_FIX_CHANGESTAND_HACK ) CDnChangeStandActionBlow::ReleaseStandChangeSkill( GetActorHandle(), true ); #endif if( false == bValid ) { // Hack!! ÇöÀç ¾×¼Ç¿¡¼­ ÀüÀÌµÉ ¼ö ¾ø´Â,, °®°í ÀÖ´Â ÆÐ½Ãºê ½ºÅ³ ½Ã±×³Îµé¿¡ ¾ø´Â ¾×¼ÇÀ» ½ÇÇàÇÏ·Á ÇÔ. // ¾Æ´Ï¸é º¸À¯Çϰí ÀÖÁö ¾ÊÀº ÆÐ½Ãºê ½ºÅ³ÀÇ ¾×¼ÇÀ» ½ÇÇàÇÏ·Á Çϰųª.. // ÇÙÀÌ´Ù. #ifdef PRE_FIX_SKILL_FAILED_BY_ACTION #ifdef PRE_FIX_69469 if( GetProcessSkill() ) CancelUsingSkill(); SetAction( "Stand", 0.f, 3.f ); #endif const char* pCurrentAction = GetCurrentAction(); int iCurrentActionIndex = GetElementIndex( pCurrentAction ); BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream LocalStream( pBuffer, 32 ); CDnSkill::UsingResult eResult = CDnSkill::FailedByInvailedAction; LocalStream.Write( &nSkillID, sizeof(int) ); LocalStream.Write( &eResult, sizeof(CDnSkill::UsingResult) ); LocalStream.Write( &iCurrentActionIndex, sizeof(int) ); Send( eActor::SC_SKILLUSING_FAILED, &LocalStream ); #endif return; } // À§ÀÇ ÇÙ Å×½ºÆ®¸¦ Åë°úÇÏ¸é ³ª¸Ó nLoopCount ³ª fBlendFrame À̳ª fStartFrame µîµîÀ» ±×´ë·Î »ç¿ëÇÏ°Ô µÇ´Âµ¥ // ÀÌ ºÎºÐÀÌ ¹®Á¦µÉ ½Ã¿¡´Â ½Ã±×³Î¿¡ ÀÖ´Â µ¥ÀÌÅ͸¦ ±×´ë·Î »ç¿ëÅä·Ï ÇÑ´Ù. CmdPassiveSkillAction( nSkillID, pStruct->szName.c_str(), nLoopCount, fBlendFrame, fStartFrame, bChargeKey, false, bOnlyCheck ); m_pPlayerSpeedHackChecker->OnSyncPosition( vPos ); } break; case eActor::CS_POSREV: { if( GetGameRoom() && GetGameRoom()->GetGameTask() && !GetGameRoom()->GetGameTask()->IsSyncComplete() ) break; CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos; bool bMove; DWORD dwGap; Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &bMove, sizeof(bool) ); _ASSERT( m_pPlayerSpeedHackChecker ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); m_pPlayerSpeedHackChecker->OnSyncPosition( vPos ); SetPosition( vPos ); if( bMove ) { EtVector3 vXVec; EtVector2 vZVec; Stream.Read( &vZVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT ); EtVec3Cross( &vXVec, &EtVector3( 0.f, 1.f, 0.f ), &EtVec2toVec3( vZVec ) ); SetMoveVectorX( vXVec ); SetMoveVectorZ( EtVec2toVec3( vZVec ) ); if( EtVec3LengthSq( GetMovePos() ) > 0.f ) { float fXSpeed = 0.f, fZSpeed = 0.f; if( m_cMovePushKeyFlag & 0x01 ) fXSpeed = -100000.f; if( m_cMovePushKeyFlag & 0x02 ) fXSpeed = 100000.f; if( m_cMovePushKeyFlag & 0x04 ) fZSpeed = 100000.f; if( m_cMovePushKeyFlag & 0x08 ) fZSpeed = -100000.f; vPos += ( vXVec * fXSpeed ); vPos += ( EtVec2toVec3( vZVec ) * fZSpeed ); MovePos( vPos, false ); } } } break; case eActor::CS_ONDROP: { CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos; DWORD dwGap; Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Stream.Read( &dwGap, sizeof(DWORD) ); _ASSERT( m_pPlayerSpeedHackChecker ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); SetPosition( vPos ); SetJumpMovement( EtVector2( 0.f, 0.f ) ); } break; case eActor::CS_CMDREMOVESTATEEFFECT: { CPacketCompressStream Stream( pPacket, 32 ); STATE_BLOW::emBLOW_INDEX emBlowIndex; Stream.Read( &emBlowIndex, sizeof(STATE_BLOW::emBLOW_INDEX) ); // ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®µé¿¡°Ôµµ »óÅÂÈ¿°ú Á¦°ÅÇÑ Å¬¶ó¿¡¼­ ¿äûÇÑ Á¦°Å ÆÐŶÀ» ¾Ë¾Æ¾ß Çϱ⠶§¹®¿¡ // ´Ù½Ã ºê·Îµåij½ºÆÃ ½ÃŲ´Ù. »óÅÂÈ¿°ú Á¦°Å ¿äûÇÑ Å¬¶ó¿¡¼± ÀÌ¹Ì Á¦°ÅµÈ »óÅÂ. CmdRemoveStateEffect( emBlowIndex ); break; } break; #if defined(PRE_FIX_57706) case eActor::CS_CMDREMOVESTATEEFFECTFROMID: { CPacketCompressStream Stream( pPacket, 32 ); int nServerBlowID = 0; Stream.Read( &nServerBlowID, sizeof(int) ); //Ŭ¶óÀÌ¾ðÆ®¸¸ Á¦°Å ½Ã°£ º¯°æÀ» ¾Ë°í Àֱ⠶§¹®¿¡ Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ¼­¹ö·Î ÆÐŶÀ» Àü¼ÛÇϰí, ¼­¹ö¿¡¼­ //ºê·Îµåij½ºÆÃ ½Ã°Ü ´Ù¸¥ Ŭ¶óÀÌ¾ðÆ®µµ ÇØ´ç »óÅÂÈ¿°ú Á¦°Å¸¦ ÇÑ´Ù. CmdRemoveStateEffectFromID(nServerBlowID); break; } break; #endif // PRE_FIX_57706 case eActor::CS_CMDTOGGLEWEAPONORDER: { CPacketCompressStream Stream( pPacket, 32 ); int nEquipIndex; bool bViewCash; Stream.Read( &nEquipIndex, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &bViewCash, sizeof(bool) ); CmdToggleWeaponViewOrder( nEquipIndex, bViewCash ); } break; case eActor::CS_CMDTOGGLEPARTSORDER: { CPacketCompressStream Stream( pPacket, 32 ); int nEquipIndex; bool bViewCash; Stream.Read( &nEquipIndex, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &bViewCash, sizeof(bool) ); if( nEquipIndex == HIDEHELMET_BITINDEX ) CmdToggleHideHelmet( bViewCash ); else CmdTogglePartsViewOrder( nEquipIndex, bViewCash ); if (GetUserSession() && GetUserSession()->GetPartyID() > 0) { if( nEquipIndex == CASHEQUIP_HELMET || nEquipIndex == CASHEQUIP_EARRING || nEquipIndex == HIDEHELMET_BITINDEX ) { for (DWORD i = 0; i < m_pSession->GetGameRoom()->GetUserCount(); i++) { CDNGameRoom::PartyStruct *pStruct = m_pSession->GetGameRoom()->GetPartyData(i); if (pStruct == NULL) continue; pStruct->pSession->SendPartyMemberPart(m_pSession); } } } } break; case eActor::CS_CMDPICKUPITEM: { if( IsDie() ) break; if( IsInvalidPlayerChecker() ) break; CPacketCompressStream Stream( pPacket, 128 ); DWORD dwUniqueID; int nSignalIndex; EtVector3 vPos; int nRange = 100; Stream.Read( &dwUniqueID, sizeof(DWORD) ); Stream.Read( &nSignalIndex, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); CEtActionSignal *pSignal = GetSignal( m_nActionIndex, nSignalIndex ); if( pSignal && pSignal->GetSignalIndex() == STE_PickupItem ) { PickupItemStruct *pSignalStruct = (PickupItemStruct *)pSignal->GetData(); nRange = pSignalStruct->nRange; } m_pPlayerSpeedHackChecker->OnSyncPosition( vPos ); SetPosition( vPos ); if( GetGameRoom() ) { DnDropItemHandle hDropItem = GetGameRoom()->FindDropItem( dwUniqueID ); if( hDropItem ) { ((CDnPlayerPickupChecker*)m_pPlayerPickupChecker)->OnPickupDist( vPos, hDropItem ); if( m_pSession && m_pSession->GetItem() && m_pSession->GetItem()->GetPetEquip() )//Ç÷¹ÀÌ¾î ¾ÆÀÌÅÛ Âø¿ë ÀåºñÁß ÆêÀ» ¼ÒȯÇß´Ù¸é { const TVehicle* pPet = m_pSession->GetItem()->GetPetEquip(); // °Å¸®ÃøÁ¤(2¹è ¿ÀÂ÷ Çã¿ë) float fDist = EtVec2Length( &(EtVector2(hDropItem->GetPosition()->x,hDropItem->GetPosition()->z)-EtVector2(vPos.x,vPos.z) ) ); if( fDist > pPet->nRange*2.f ) return; } else { // °Å¸®ÃøÁ¤(2¹è ¿ÀÂ÷ Çã¿ë) float fDist = EtVec2Length( &(EtVector2(hDropItem->GetPosition()->x,hDropItem->GetPosition()->z)-EtVector2(vPos.x,vPos.z) ) ); if( fDist > nRange*2.f ) return; } PickupItemStruct Struct; Struct.nRange = nRange; CmdPickupItem( &Struct, hDropItem ); } } break; } case eActor::CS_CMDESCAPE: { // ¿©±â¼­ ½ÇÁ¦ ¸ÔÈ÷°ÔÇÒÁö Çѹø °ËÁß. if( m_LastEscapeTime > 0 && CDnActionBase::m_LocalTime - m_LastEscapeTime < 1000 * 60 * 1 ) break; CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos; Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); SetPosition( vPos ); SetStaticPosition( vPos ); SetPrevPosition( vPos ); if( m_pPlayerSpeedHackChecker ) m_pPlayerSpeedHackChecker->ResetInvalid(); if( m_pPlayerDoNotEnterChecker ) m_pPlayerDoNotEnterChecker->ResetInvalid(); CmdEscape( vPos ); } break; case eActor::CS_CANNONPOSSESS_REQ: { // ´ëÆ÷¸¦ Á¡À¯Çϰڴٴ Ŭ¶ó·ÎºÎÅÍÀÇ ¿äû. // ¿äûÀÇ °á°úµµ º¸³»ÁÖµµ·Ï ÇÑ´Ù. CPacketCompressStream Stream( pPacket, 128 ); DWORD dwCannonMonsterActorID = 0; MatrixEx Cross; Stream.Read( &dwCannonMonsterActorID, sizeof(DWORD) ); Stream.Read( &Cross, sizeof(MatrixEx) ); bool bSuccess = false; // ´ëÆ÷ ¸ó½ºÅÍ¿¡°Ô ÇÒ´ç. CDnActor *pActor = CDnActor::FindActorFromUniqueID( GetRoom(), dwCannonMonsterActorID ); if( pActor && pActor->GetActorType() == ActorTypeEnum::Cannon ) { CDnCannonMonsterActor* pCannonActor = static_cast( pActor ); // Ŭ¶ó¿¡¼­ º¸³»ÁØ ´ëÆ÷ ¸ó½ºÅÍÀÇ ±Ùó¿¡ ÀÌ Ä³¸¯ÅͰ¡ ÀÖ´ÂÁö üũÇÑ´Ù. // Press Circle º¸´Ù °Å¸®°¡ ¸Ö¸é ÇÙÀÏ °¡´É¼ºÀÌ ÀÖ´Ù.. ¾à°£ °ü¿ëµµ °ªÀ» Á־ µÉ µí. bool bValid = false; float fDistanceSQ = EtVec3LengthSq( &EtVector3(*pCannonActor->GetPosition() - *GetPosition()) ); float fPressCircleDist = float(GetUnitSize() + pCannonActor->GetUnitSize()); float fPressCircleDistSQ = fPressCircleDist * fPressCircleDist; if( fPressCircleDistSQ <= fDistanceSQ + 1000.0f || fPressCircleDistSQ - 1000.f <= fDistanceSQ) { // ÀÌ¹Ì Á¡À¯ÁßÀÎÁö. if( false == pCannonActor->IsPossessed() ) { m_bPlayerCannonMode = true; pCannonActor->SetMasterPlayerActor( GetMySmartPtr() ); m_hCannonMonsterActor = pCannonActor->GetMySmartPtr(); m_Cross = Cross; bSuccess = true; // ´ëÆ÷ Á¡À¯ ¼º°ø.. ÇÊ¿äÇÑ Á¤º¸µé°ú ÇÔ²² ÀÀ´ä º¸³»ÁÜ.. char acBuffer[ 64 ] = { 0 }; CPacketCompressStream Result( acBuffer, sizeof(acBuffer) ); Result.Write( &bSuccess, sizeof(bool) ); Result.Write( &dwCannonMonsterActorID, sizeof(DWORD) ); Result.Write( &m_Cross.m_vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Result.Write( &m_Cross.m_vXAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Result.Write( &m_Cross.m_vYAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Result.Write( &m_Cross.m_vZAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Send( eActor::SC_CANNONPOSSESS_RES, &Result ); // ´ëÆ÷»óÅ¿¡¼­´Â ¹Ð¸®Áö ¾Êµµ·Ï ¼³Á¤ÇÕ´Ï´Ù. ´ëÆ÷¿¡¼­ ³»¸®´Â °æ¿ì¿¡´Â ¸®¼Â½ÃÄÑÁà¾ßÇÕ´Ï´Ù. SetWeight(0.f); SetPressLevel(-1); #ifdef PRE_ADD_MODIFY_PLAYER_CANNON DNTableFileFormat* pTableCannon = GetDNTable( CDnTableDB::TCANNON ); if( pTableCannon->IsExistItem( pCannonActor->GetClassID() ) ) { const char* pCannonActionName = pTableCannon->GetFieldFromLablePtr( pCannonActor->GetClassID(), "_StandName" )->GetString(); CmdAction(pCannonActionName); } else { CmdAction( "Stand_Cannon" ); } #else // ´ëÆ÷ ¾×¼ÇÀ¸·Î º¯°æ. CmdAction( "Stand_Cannon" ); #endif } } } // ´ëÆ÷ Á¡À¯ ½ÇÆÐ.. ÀÀ´ä º¸³»ÁÜ. if( false == bSuccess ) { char acBuffer[ 64 ] = { 0 }; CPacketCompressStream Result( acBuffer, sizeof(acBuffer) ); Result.Write( &bSuccess, sizeof(bool) ); Send( eActor::SC_CANNONPOSSESS_RES, &Result ); } } break; case eActor::CS_CANNONRELEASE: { DWORD dwCannonMonsterID = 0; MatrixEx Cross; CPacketCompressStream Result( pPacket, 64 ); Result.Read( &dwCannonMonsterID, sizeof(DWORD) ); Result.Read( &Cross.m_vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Result.Read( &Cross.m_vXAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Result.Read( &Cross.m_vYAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); Result.Read( &Cross.m_vZAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); CDnActor* pActor = CDnActor::FindActorFromUniqueID( GetRoom(), dwCannonMonsterID ); if( pActor && pActor->GetActorType() == ActorTypeEnum::Cannon ) { CDnCannonMonsterActor* pCannonMonster = static_cast(pActor); pCannonMonster->ClearMasterPlayerActor(); m_Cross = Cross; EndCannonMode(); } } break; case eActor::CS_CANNONROTATESYNC: { _ASSERT( IsCannonMode() ); if( false == IsCannonMode() ) break; CPacketCompressStream Stream( pPacket, 64 ); DWORD dwCannonMonsterID = 0; EtVector3 vDirection( 0.0f, 0.0f, 0.0f ); Stream.Read( &dwCannonMonsterID, sizeof(DWORD) ); Stream.Read( &vDirection, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT ); CDnActor* pActor = CDnActor::FindActorFromUniqueID( GetRoom(), dwCannonMonsterID ); if( pActor && pActor->GetActorType() == ActorTypeEnum::Cannon ) { CDnCannonMonsterActor* pCannonMonster = static_cast(pActor); EtVec3Normalize( &vDirection, &vDirection ); // ¾ÐÃàµÇ¾î Àü¼ÛµÈ µ¥ÀÌÅÍÀ̹ǷΠÁ¤±ÔÈ­ ÇÑ ¹ø ÇØÁÜ. pCannonMonster->SetCannonLookDirection(&vDirection); // Rotha - ´ëÆ÷ ÀÚü¸¦ µ¹¸®´Â°Ô ¾Æ´Ñ ´ëÆ÷ÀÇ Æ÷½ÅÀ» µ¹¸®µµ·Ï ¼³Á¤ÇÕ´Ï´Ù. Æ÷½ÅÀº ½ÃÁ¡¸¸ °ü¸®ÇÕ´Ï´Ù. m_Cross.m_vZAxis = pCannonMonster->GetMatEx()->m_vZAxis; m_Cross.MakeUpCartesianByZAxis(); // press circle °ª¸¸Å­ ¹Ð¾îÁÖ¸é µÈ´Ù. m_Cross.m_vPosition = pCannonMonster->GetMatEx()->m_vPosition - (pCannonMonster->GetMatEx()->m_vZAxis*20.0f); EtVector2 vDir; float vDist = 0.0f; _ASSERT( GetPress() == CDnActorState::Press_Circle && pCannonMonster->GetPress() == CDnActorState::Press_Circle ); if( GetPress() == CDnActorState::Press_Circle && pCannonMonster->GetPress() == CDnActorState::Press_Circle ) { if( CheckPressCircle2Clrcle2( pCannonMonster->GetMySmartPtr(), GetMySmartPtr() , vDir, vDist ) ) { m_Cross.m_vPosition.x += vDir.x*vDist; m_Cross.m_vPosition.z += vDir.y*vDist; } } // ÀÌ Å¸Àֿ̹¡ ´Ù¸¥ ¾î¶² ÀÌÀ¯·Î ÀÎÇØ "Stand" ¾×¼ÇÀ» ij¸¯ÅͰ¡ ÃëÇϰí ÀÖÀ¸¸é // Stand_Cannon ·Î ¹Ù²ãÁØ´Ù. // °¨Àü ¾×¼ÇÀ» ÇÏ´Ù°¡ Ç®¸®°Å³ª ÇÏ´Â °æ¿ì. const char* pCurrentAction = GetCurrentAction(); if( strcmp(pCurrentAction, "Stand") == 0 ) { #ifdef PRE_ADD_MODIFY_PLAYER_CANNON DNTableFileFormat* pTableCannon = GetDNTable( CDnTableDB::TCANNON ); if( pTableCannon->IsExistItem( pCannonMonster->GetClassID() ) ) { const char* pCannonActionName = pTableCannon->GetFieldFromLablePtr( pCannonMonster->GetClassID(), "_StandName" )->GetString(); CmdAction(pCannonActionName); } else { CmdAction( "Stand_Cannon" ); } #else // ´ëÆ÷ ¾×¼ÇÀ¸·Î º¯°æ. CmdAction( "Stand_Cannon" ); #endif } } } break; case eActor::CS_CANNONTARGETING: { if( false == IsCannonMode() ) break; DWORD dwCannonMonsterID = 0; EtVector3 vCannonDir; // Ŭ¶óÀÌ¾ðÆ®¿¡¼­ Ä«¸Þ¶ó°¡ ¹Ù¶óº¸°í ÀÖ´Â ¹æÇâ. °á±¹ ´ëÆ÷ÀÇ ¹æÇâ. EtVector3 vShootDir; EtVector3 vCannonGroundHitPos; CPacketCompressStream Stream( pPacket, 64 ); Stream.Read( &dwCannonMonsterID, sizeof(DWORD) ); Stream.Read( &vCannonDir, sizeof(EtVector3) ); Stream.Read( &vShootDir, sizeof(EtVector3) ); Stream.Read( &vCannonGroundHitPos, sizeof(EtVector3) ); CDnActor* pActor = CDnActor::FindActorFromUniqueID( GetRoom(), dwCannonMonsterID ); if( pActor && pActor->GetActorType() == ActorTypeEnum::Cannon ) { CDnCannonMonsterActor* pCannonMonster = static_cast(pActor); pCannonMonster->SetCannonProjectileInfo( vCannonDir, vShootDir, vCannonGroundHitPos ); } } break; case eActor::CS_VEHICLE_RIDE_COMPLETE: { if(!IsVehicleMode() || !GetMyVehicleActor()) return; CPacketCompressStream Stream( pPacket, 128 ); bool bComplete = false; Stream.Read( &bComplete, sizeof(bool) ); if(bComplete) { DNVector( DnBlowHandle ) vlhFrameBlows; DNVector( DnBlowHandle ) vlhMoveSpeedBlows; m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_025, vlhFrameBlows ); m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_076, vlhMoveSpeedBlows ); if(vlhFrameBlows.size() > 0) { for(DWORD i=0 ; iCmdAddStateEffect( vlhFrameBlows[i]->GetParentSkillInfo() , vlhFrameBlows[i]->GetBlowIndex() , (int)(vlhFrameBlows[i]->GetDurationTime() * 1000) , vlhFrameBlows[i]->GetValue() ); } } if(vlhMoveSpeedBlows.size() > 0) { for(DWORD i=0 ; iCmdAddStateEffect( vlhMoveSpeedBlows[i]->GetParentSkillInfo() , vlhMoveSpeedBlows[i]->GetBlowIndex() , (int)(vlhMoveSpeedBlows[i]->GetDurationTime() * 1000) , vlhMoveSpeedBlows[i]->GetValue() ); } } } } break; case eActor::CS_SYNCPRESSEDPOS: { if( GetGameRoom() && GetGameRoom()->GetGameTask() && !GetGameRoom()->GetGameTask()->IsSyncComplete() ) break; CPacketCompressStream Stream( pPacket, 128 ); EtVector3 vPos; DWORD dwGap; Stream.Read( &dwGap, sizeof(DWORD) ); Stream.Read( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); m_pPlayerSpeedHackChecker->OnSyncDatumGap( dwGap ); SetPosition( vPos ); // SetMagnetPosition( vPos ); } break; case eActor::CS_UDP_PING: { CPacketCompressStream Stream( pPacket, 128 ); DWORD dwTick = 0; Stream.Read( &dwTick, sizeof(dwTick) ); m_pSession->RecvUdpPing( dwTick ); break; } case eActor::CS_SUMMONOFF: { CPacketCompressStream Stream( pPacket, 64 ); DWORD dwSummonMonsterUniqueID = 0; Stream.Read( &dwSummonMonsterUniqueID, sizeof(DWORD) ); CDnActor* pSummonMonster = CDnActor::FindActorFromUniqueID( GetRoom(), dwSummonMonsterUniqueID ); if (pSummonMonster) pSummonMonster->CmdSuicide(false, false); } break; #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) // case eActor::CS_TOTAL_LEVEL: // { // int nTotalLevel = 0; // // CPacketCompressStream Stream( pPacket, 128 ); // Stream.Read( &nTotalLevel, sizeof(int) ); // // UpdateTotalLevel(nTotalLevel); // } // break; case eActor::CS_ADD_TOTAL_LEVEL_SKILL: { int nSlotIndex = -1; int nSkillID = 0; bool isInitialize = false; CPacketCompressStream Stream( pPacket, 128 ); Stream.Read( &nSlotIndex, sizeof(int) ); Stream.Read( &nSkillID, sizeof(int) ); Stream.Read( &isInitialize, sizeof(bool) ); if( nSlotIndex >= TotalLevelSkill::Common::MAXSLOTCOUNT ) break; if(!m_pSession->AddTotalLevelSkillData(nSlotIndex, nSkillID, isInitialize)) { break; } else AddTotalLevelSkill(nSlotIndex, nSkillID, isInitialize); m_pSession->SendAddTotalLevelSkill(m_pSession->GetSessionID(), nSlotIndex, nSkillID, isInitialize); } break; case eActor::CS_REMOVE_TOTAL_LEVEL_SKILL: { int nSlotIndex = -1; CPacketCompressStream Stream( pPacket, 128 ); Stream.Read( &nSlotIndex, sizeof(int) ); if( nSlotIndex < 0 || nSlotIndex >= TotalLevelSkill::Common::MAXSLOTCOUNT ) break; RemoveTotalLevelSkill(nSlotIndex); m_pSession->AddTotalLevelSkillData(nSlotIndex, 0); m_pSession->SendDelTotalLevelSkill(m_pSession->GetSessionID(), nSlotIndex); } break; // case eActor::CS_TOTAL_LEVEL_SKILL_ACTIVE_LIST: // { // int nCount = 0; // int nSlotIndex = -1; // int nSkillID = 0; // // CPacketCompressStream Stream( pPacket, 128 ); // Stream.Read( &nCount, sizeof(int) ); // // for (int i = 0; i < nCount; ++i) // { // Stream.Read( &nSlotIndex, sizeof(int) ); // Stream.Read( &nSkillID, sizeof(int) ); // // ActivateTotalLevelSkillSlot(nSlotIndex, true); // AddTotalLevelSkill(nSlotIndex, nSkillID); // } // } // break; // case eActor::CS_TOTAL_LEVEL_SKILL_CASHSLOT_ACTIVATE: // { // int nSlotIndex = -1; // bool bActivate = false; // // CPacketCompressStream Stream( pPacket, 128 ); // Stream.Read(&nSlotIndex, sizeof(int)); // Stream.Read(&bActivate, sizeof(bool)); // // ActivateTotalLevelSkillCashSlot(bActivate); // } // break; #endif // PRE_ADD_TOTAL_LEVEL_SKILL #if defined(PRE_FIX_68898) case eActor::CS_SKIP_END_ACTION: { bool isSkipEndAction = false; CPacketCompressStream Stream( pPacket, 128 ); Stream.Read(&isSkipEndAction, sizeof(bool)); SetSkipEndAction(isSkipEndAction); } break; #endif // PRE_FIX_68898 } } void CDnPlayerActor::SyncClassTime( LOCAL_TIME LocalTime ) { MAActorRenderBase::m_LocalTime = LocalTime; CDnActor::SyncClassTime( LocalTime ); } void CDnPlayerActor::ProcessDie( LOCAL_TIME LocalTime, float fDelta ) { // Á×Áö¾Ê¾Æ~ if( !IsDie() ) { ToggleGhostMode( false ); return; } if( m_fDieDelta > 0.f ) { m_fDieDelta -= fDelta; if( m_fDieDelta < 0.f ) m_fDieDelta = 0.f; } if( !m_bGhost && m_fDieDelta < m_fMaxDieDelta - 4.f ) { ToggleGhostMode( true ); } if( m_fDieDelta <= 0.f ) { OnFinishProcessDie(); } // »ó¿ë ¾ÆÀÌÅÛ¿¡ ½ºÅ³ µé¾î°¥ ¼ö ÀÖ°í, Ãß°¡ÀûÀ¸·Î ¹®Àå¿¡ ½ºÅ³ÀÌ µé¾î°¨. ÀÏ´Ü ±×³É ¾Ç¼¼»ç¸® ·çÇÁµµ µ¹ÀÚ. if( m_afLastEquipItemSkillRemainTime != 0.0f ) { m_afLastEquipItemSkillRemainTime -= fDelta; if( m_afLastEquipItemSkillRemainTime < 0.0f ) m_afLastEquipItemSkillRemainTime = 0.0f; } } void CDnPlayerActor::OnKillMonster(DnActorHandle hMonster) { if ( !m_pSession ) return; if ( m_pSession->GetQuest() == NULL ) return; if( hMonster && hMonster->IsMonsterActor() ) { CDnMonsterActor* pMonster = static_cast(hMonster.GetPointer()); if ( pMonster ) { m_pSession->GetQuest()->OnKillMonster(pMonster->GetMonsterClassID()); UpdateKillMonster(); if (pMonster->IsBossKillCheck()) UpdateKillBoss(); } } } void CDnPlayerActor::OnStateBlowProcessAfter() { if( m_uiStateBlowProcessAfterBit&eStateBlowAfterProcessType::eRebirth ) { m_uiStateBlowProcessAfterBit &= ~eStateBlowAfterProcessType::eRebirth; if( !GetGameRoom() ) { _DANGER_POINT(); return; } GetGameRoom()->OnRebirth( GetActorHandle() ); } if( m_uiStateBlowProcessAfterBit & eStateBlowAfterProcessType::eDelZombie ) { m_uiStateBlowProcessAfterBit &= ~eStateBlowAfterProcessType::eDelZombie; if( GetGameRoom() && GetGameRoom()->bIsZombieMode() ) static_cast(static_cast(GetGameRoom())->GetPvPGameMode())->DelZombie( GetActorHandle(), true ); } } void CDnPlayerActor::OnAddStateBlowProcessAfterType( eStateBlowAfterProcessType Type ) { m_uiStateBlowProcessAfterBit |= Type; } void CDnPlayerActor::OnDie( DnActorHandle hHitter ) { #if defined( PRE_ADD_SECONDARY_SKILL ) if( GetUserSession() && GetUserSession()->GetSecondarySkillRepository() ) static_cast(GetUserSession()->GetSecondarySkillRepository())->CancelManufacture(); #endif // #if defined( PRE_ADD_SECONDARY_SKILL ) CDnActor::OnDie( hHitter ); // hitter ÂÊ ¹öºí ½Ã½ºÅÛÂÊ¿¡ Ÿ°ÝÇÑ ´ë»óÀÌ Á×¾úÀ½À» ¾Ë¸°´Ù. ///////////////////////////////////////////// if(hHitter && hHitter->IsPlayerActor()) { CDnPlayerActor *pPlayer = static_cast(hHitter.GetPointer()); boost::shared_ptr pEvent( IDnObserverNotifyEvent::Create( EVENT_PLAYER_KILL_TARGET ) ); pPlayer->Notify( pEvent ); } ////////////////////////////////////////////////////////////////////////// UpdateDead(); AddStageDeathCount(); if(m_pRoom && !m_pRoom->bIsPvPRoom()) { for( DWORD i=0; ipSession ) continue; if( pParty->pSession == m_pSession ) continue; DnActorHandle hActor = pParty->pSession->GetActorHandle(); if( !hActor ) continue; CDnPlayerActor *pPlayer = (CDnPlayerActor *)hActor.GetPointer(); pPlayer->UpdatePartyMemberDead(); } } // ÇöÀç ¹ßµ¿ÁßÀÎ ½ºÅ³À» ¸ðµÎ Á¾·á, // ºÎȰÇÏ°í³ª¸é ÆÐ½Ãºê ½ºÅ³Àº ´Ù½Ã °É¾îÁà¾ß ÇÔ.. if( m_hProcessSkill ) m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.0f ); // ¹ßµ¿ÁßÀÎ ¿ÀÅä ÆÐ½Ãºê ½ºÅ³ÀÌ ÀÖ´Ù¸é Á¾·á EndAutoPassiveSkill( CDnActionBase::m_LocalTime, 0.0f ); // Á¢µÎ¾î ½ºÅ³ Á¾·á EndPrefixSystemSkill(CDnActionBase::m_LocalTime, 0.0f); // #14340 À¸·Î ÀÎÇØ.. Á×¾úÀ» ¶§ ÆÐ½Ãºê ½ºÅ³Àº ¾ø¾ÖÁö ¾Ê´Â °ÍÀ¸·Î ¼öÁ¤µÊ. // ¿À¶ó½ºÅ³, Åä±Û½ºÅ³ÀÌ ÄÑÁ® ÀÖ´Ù¸é ²¨ÁØ´Ù. if( IsEnabledToggleSkill() ) OnSkillToggle( m_hToggleSkill, false ); if( IsEnabledAuraSkill() ) OnSkillAura( m_hAuraSkill, false ); // ³ª¸ÓÁö, ´Ù¸¥ Ç÷¹À̾ ¸÷¿¡ ÀÇÇØ °É·Á ÀÖ´Â »óÅÂÈ¿°ú ¸ðµÎ ¾ø¾Ø´Ù. RemoveAllBlowExpectPassiveSkill(); // Àκ¥Å丮 ¾ÆÀÌÅÛ ÄðŸÀÓ ÃʱâÈ­ ÇØÁØ´Ù. if( m_pSession && m_pSession->GetItem() ) { //m_pSession->GetItem()->ResetCoolTime(); } SetSP(0); bool bIgnoreDuration = false; if (bIgnoreDuration == false) { // ³»±¸µµ °¨¼Ò½ÃÄÑÁØ´Ù. bool bDecreaseDurability = true; if( m_pRoom ) { if( m_pRoom->bIsPvPRoom() ) bDecreaseDurability = false; else if( m_pRoom->bIsDLRoom() ) bDecreaseDurability = false; else if( m_pRoom->bIsFarmRoom() ) bDecreaseDurability = false; } if( bDecreaseDurability ) OnDecreaseEquipDurability( GetDeadDurabilityRatio(), true ); } if( GetGameRoom() ) { GetGameRoom()->OnDie( GetActorHandle(), hHitter ); if( GetGameRoom()->GetGameTask() ) GetGameRoom()->GetGameTask()->OnDie( GetActorHandle(), hHitter ); } if( IsCannonMode() ) { static_cast(m_hCannonMonsterActor.GetPointer())->OnMasterPlayerActorDie(); EndCannonMode(); } m_pBubbleSystem->Clear(); if( CDnWorld::IsActive(GetRoom()) ) { CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "DieActionPlayer", GetUniqueID() ); CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnPlayerActor::OnDie", CDnActionBase::m_LocalTime, 0.f ); } } void CDnPlayerActor::OnFinishProcessDie() { if( GetGameRoom() ) GetGameRoom()->OnFinishProcessDie( GetActorHandle() ); } void CDnPlayerActor::ResetActor() { CDnActor::ResetActor(); m_cMovePushKeyFlag = 0; m_LastEscapeTime = 0; if( IsProcessSkill() ) CancelUsingSkill(); // #26902 Àӽ÷ΠÃß°¡µÈ ½ºÅ³ÀÌ ÀÖ´Ù¸é »èÁ¦. Ŭ¶óÇÑÅ×´Â ÆÐŶÀ¸·Î ³¯¶ó°¨. if( IsTempSkillAdded() ) { RemoveAllTempSkill(); EndAddTempSkillAndSendRestoreTempJobChange(); } if( m_pPlayerSpeedHackChecker ) m_pPlayerSpeedHackChecker->ResetInvalid(); map::iterator iter = m_mapEnchantSkillFromBubble.begin(); for( iter; iter != m_mapEnchantSkillFromBubble.end(); ) { SAFE_RELEASE_SPTR( iter->second ); iter = m_mapEnchantSkillFromBubble.erase( iter ); } m_MixedActionTimeStamp = 0; } void CDnPlayerActor::GetBoundingSphere( SSphere &Sphere, bool bActorSize/* = false*/ ) { Sphere.Center = m_Cross.m_vPosition; Sphere.Center.y += 50.f; Sphere.fRadius = 50.f; } void CDnPlayerActor::SetBattleMode( bool bEnable ) { m_bBattleMode = bEnable; } bool CDnPlayerActor::IsCanBattleMode() { if( IsSwapSingleSkin() ) return false; if( m_bBattleMode && !m_hWeapon[0] ) return false; if( IsSpectatorMode() ) return false; return m_bBattleMode; } int CDnPlayerActor::GetLevelUpSkillPoint( int nPrevLevel, int nCurLevel ) { if( nPrevLevel == nCurLevel ) return 0; int nSkillPoint = 0; for( int i=nPrevLevel+1; i<=nCurLevel; i++ ) { int nItemID = ( ( GetClassID() - 1 ) * PLAYER_MAX_LEVEL ) + i; nSkillPoint += CPlayerLevelTable::GetInstance().GetValue( GetJobClassID(), i, CPlayerLevelTable::SkillPoint ); } return nSkillPoint; } void CDnPlayerActor::OnBattleToggle( bool bBattle ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &bBattle, sizeof(bool) ); Send( eActor::SC_CMDTOGGLEBATTLE, &Stream ); } void CDnPlayerActor::OnLevelUp( int nLevel, int nLevelUpAmount ) { if( !IsDie() ) { SetHP( GetMaxHP() ); SetSP( GetMaxSP() ); } int nSkillPoint = GetLevelUpSkillPoint( nLevel - nLevelUpAmount, nLevel ); //·¹º§¾÷½Ã¿¡´Â ½ºÅ³Æ÷ÀÎÆ® µÎ±ºµ¥ ¸ðµÎ Áõ°¡ m_pSession->ChangeSkillPoint(nSkillPoint, 0, true, DBDNWorldDef::SkillPointCode::LevelUp, DualSkill::Type::Primary); m_pSession->ChangeSkillPoint(nSkillPoint, 0, true, DBDNWorldDef::SkillPointCode::LevelUp, DualSkill::Type::Secondary); m_pSession->SetLevel(m_nLevel, DBDNWorldDef::CharacterLevelChangeCode::Normal, true); m_pSession->SetExp(m_nExperience, DBDNWorldDef::CharacterExpChangeCode::Dungeon, 0, true); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nLevel, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Write( &m_nExperience, sizeof(int) ); Send( eActor::SC_LEVELUP, &Stream ); #if !defined(PRE_DELETE_DUNGEONCLEAR) // ´øÀü ÀúÀå °ü·Ã µ¥ÀÌŸ ¿©±â¼­ Çѹø ¸®Ç÷¹½¬ ÇØ¼­ ÇÊ¿ä¾ø´Â°Íµé Áö¿öÁÖ°Ô ÇÏÀÚ m_pSession->RefreshDungeonEnterLevel(); #endif // #if !defined(PRE_DELETE_DUNGEONCLEAR) // Refresh ÇØº¸°í °ÔÀÌÆ®ÀÇ º¯°æ»çÇ×ÀÌ »ý°åÀ¸¸é °ÔÀÌÆ®ÀÎÆ÷¸¦ º¸³½´Ù. if( CDnPartyTask::IsActive(GetRoom()) ) CDnPartyTask::GetInstance(GetRoom()).UpdateGateInfo(); // ·¹º§¿¡ µû¶ó ½ºÅ³ ¼Ò¸ð SP °¡ ´Ù¸£±â¶«½Ã ¾ðÁ¦³ª ¸®Ç÷¹½¬ ÇØÁà¾ßÇÑ´Ù. for( DWORD i=0; iRefreshDecreaseMP(); } m_pSession->NotifyGuildMemberLevelUp(nLevel); m_pSession->GetEventSystem()->OnEvent( EventSystem::OnLevelUp ); // »çÁ¦ Á¹¾÷ if( m_pSession->GetMasterSystemData()->SimpleInfo.iMasterCount > 0 && nLevel >= static_cast(CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::MasterSystem_GraduateLevel )) ) { if( m_pSession->CheckDBConnection() ) m_pSession->GetDBConnection()->QueryMasterSystemGraduate( m_pSession ); } if( CDnWorld::GetInstance(GetRoom()).GetMapType() == EWorldEnum::MapTypeDungeon && m_pSession->GetPeriodExpItemRate() > 0 ) m_pSession->SetPeriodExpItemRate(); #if defined( PRE_ADD_BESTFRIEND ) m_pSession->BestFriendChangeLevel(nLevel, true); #endif #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) UpdateTotalLevelByCharLevel(); #endif // PRE_ADD_TOTAL_LEVEL_SKILL } void CDnPlayerActor::OnAddExperience( int nAddExperience, int nLogCode, INT64 biFKey ) { m_pSession->ChangeExp(nAddExperience, nLogCode, biFKey); // dbÀúÀå ¾È¿¡ÀÖÀ½ // °æÇèÄ¡´Â ¸¶ÃâÇÊ¿ä ¾ø´Ù. } void CDnPlayerActor::OnBeginStateBlow( DnBlowHandle hBlow ) { // ³ªÁß¿¡ °íÄ¡ÀÚ.. DNVector(DnActorHandle) hVecList; ScanActor( GetRoom(), m_Cross.m_vPosition, 2000.f, hVecList ); for( DWORD i=0; iGetAggroSystem(); // ÀϹݴøÁ¯ Ç÷¹À̽ÿ¡´Â PlayerActor ´Â AggroSystem ÀÌ ¾ø´Ù. if( !pAggroSystem ) continue; if( !pAggroSystem->bOnCheckPlayerBeginStateBlow( this ) ) continue; pAggroSystem->OnStateBlowAggro( hBlow ); } } void CDnPlayerActor::UnLockSkill( int nSkillID, INT64 nUnlockPrice/*=0*/ ) { // ÀÌ¹Ì ¾ð¶ô µÇ¾îÀÖ´Â ½ºÅ³ÀÌ ¶Ç µé¾î¿À¸é ¾ÈµÇ°í.. vector::iterator iter = find( m_vlUnlockZeroLevelSkills.begin(), m_vlUnlockZeroLevelSkills.end(), nSkillID ); _ASSERT( m_vlUnlockZeroLevelSkills.end() == iter ); if( m_vlUnlockZeroLevelSkills.end() == iter ) { m_vlUnlockZeroLevelSkills.push_back( nSkillID ); CDnSkillTreeSystem::S_POSSESSED_SKILL_INFO SkillInfo; SkillInfo.iSkillID = nSkillID; SkillInfo.iSkillLevel = 0; SkillInfo.bCurrentLock = false; m_vlPossessedSkill.push_back( SkillInfo ); INT64 biCurrentCoin = 0; INT64 biPickUpCoin = 0; if( nUnlockPrice > 0 ) { biCurrentCoin = m_pSession->GetCoin(); biPickUpCoin = m_pSession->GetPickUpCoin(); m_pSession->SelPickUpCoin(0); } m_pSession->GetDBConnection()->QueryAddSkill(m_pSession, nSkillID, SkillInfo.iSkillLevel, 0, DBDNWorldDef::SkillChangeCode::GainByBuy, nUnlockPrice, biCurrentCoin, biPickUpCoin); } } int CDnPlayerActor::CanAcquireSkillIfUnlock( int nSkillID ) { int nRetCode = ERROR_NONE; CDnSkillTreeSystem* pSkillTreeSystem = g_pDataManager->GetSkillTreeSystem(); CDnSkillTreeSystem::S_TRY_ACQUIRE TryAcquire( GetPossessedSkillInfo() ); CDnSkillTreeSystem::S_OUTPUT Output; TryAcquire.iCurrentCharLevel = GetLevel(); TryAcquire.iTryAcquireSkillID = nSkillID; TryAcquire.iHasSkillPoint = GetAvailSkillPointByJob( nSkillID ); DNTableFileFormat* pSkillTable = GetDNTable( CDnTableDB::TSKILL ); int iNeedJob = pSkillTable->GetFieldFromLablePtr( nSkillID, "_NeedJob" )->GetInteger(); if( IsPassJob( iNeedJob ) ) { pSkillTreeSystem->TryAcquireSkill( TryAcquire, &Output ); // #36858 ±Û·Î¹ú ½ºÅ³·Î ¼­·Î ¿«¿© ÀÖ´Ù¸é ÇØ´ç ±×·ìÁß¿¡ Çϳª¸¸ ¹è¿öµµ ºÎ¸ð ½ºÅ³ Á¶°Ç¾øÀÌ ¹è¿ï ¼ö ÀÖ´Ù. bool bAlreadyGlobalSkillAcquired = HasSameGlobalIDSkill( nSkillID ); bool bIgnoreParentSkillCondition = ( (CDnSkillTreeSystem::R_DONT_HAVE_PARENT_SKILL == Output.eResult) || (CDnSkillTreeSystem::R_LOCKED_PARENTSKILL == Output.eResult) || (CDnSkillTreeSystem::R_NOT_ENOUGH_PARENT_SKILL_LEVEL == Output.eResult) ) && true == bAlreadyGlobalSkillAcquired; if( CDnSkillTreeSystem::R_SUCCESS != Output.eResult && false == bIgnoreParentSkillCondition ) { switch( Output.eResult ) { // ij¸¯ÅÍ ¿ä±¸·¹º§ÀÌ ¸ðÀÚ¶÷. case CDnSkillTreeSystem::R_NOT_ENOUGH_CHAR_LEVEL: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_NOT_ENOUGH_CHAR_LEVEL; break; // ¼±Çà(ºÎ¸ð) ½ºÅ³ÀÌ ¾øÀ½. case CDnSkillTreeSystem::R_DONT_HAVE_PARENT_SKILL: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_DONT_HAVE_PARENT_SKILL; break; // ºÎ¸ð ½ºÅ³ÀÇ ·¹º§ÀÌ ÃæÁ·µÇÁö ¾ÊÀ½. case CDnSkillTreeSystem::R_NOT_ENOUGH_PARENT_SKILL_LEVEL: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_NOT_ENOUGH_PARENT_SKILL_LEVEL; break; // ½ºÅ³ Æ÷ÀÎÆ®°¡ ¸ðÀÚ¶ó¼­ ½ºÅ³À» ȹµæÇÒ ¼ö ¾øÀ½. case CDnSkillTreeSystem::R_NOT_ENOUGH_SKILLPOINT_TO_ACQUIRE: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_NOT_ENOUGH_SKILLPOINT; break; } } } return nRetCode; } int CDnPlayerActor::AcquireSkill( int nSkillID ) { int nRetCode = ERROR_NONE; vector::iterator iter = find( m_vlUnlockZeroLevelSkills.begin(), m_vlUnlockZeroLevelSkills.end(), nSkillID ); _ASSERT( m_vlUnlockZeroLevelSkills.end() != iter ); if( m_vlUnlockZeroLevelSkills.end() != iter ) { // ¼­·Î ¸ø¹è¿ì°Ô ÇÑ ½ºÅ³Àº ¸ø¹è¿ì°Ô ó¸®. TSkillData* pSkillData = g_pDataManager->GetSkillData( nSkillID ); if( IsExclusiveSkill( nSkillID, pSkillData->nExclusiveID ) ) { // Ŭ¶ó¿¡¼­ ±âº»ÀûÀ¸·Î ¸·±â ¶§¹®¿¡ ¿©±â±îÁö ¿À¸é ÇÙÀÌ´Ù. return ERROR_SKILL_ACQUIRE_FAIL_EXCLUSIVE; } CDnSkillTreeSystem* pSkillTreeSystem = g_pDataManager->GetSkillTreeSystem(); CDnSkillTreeSystem::S_TRY_ACQUIRE TryAcquire( GetPossessedSkillInfo() ); CDnSkillTreeSystem::S_OUTPUT Output; TryAcquire.iCurrentCharLevel = GetLevel(); TryAcquire.iTryAcquireSkillID = nSkillID; TryAcquire.iHasSkillPoint = GetAvailSkillPointByJob( nSkillID ); DNTableFileFormat* pSkillTable = GetDNTable( CDnTableDB::TSKILL ); int iNeedJob = pSkillTable->GetFieldFromLablePtr( nSkillID, "_NeedJob" )->GetInteger(); if( IsPassJob( iNeedJob ) ) { //TryAcquire.iJobID = iNeedJob; pSkillTreeSystem->TryAcquireSkill( TryAcquire, &Output ); #if defined(PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP) std::vector nNeedSPValues; CDnSkillTask* pSkillTask = static_cast(CTaskManager::GetInstance( m_pSession->GetGameRoom() ).GetTask( "SkillTask" )); if (pSkillTask) pSkillTask->GetNeedSPValuesByJob(nSkillID, nNeedSPValues); std::vector jobHistory; GetJobHistory(jobHistory); bool bAvailableSPByJob = false; if (pSkillTask) bAvailableSPByJob = pSkillTask->IsAvailableSPByJob(jobHistory, nNeedSPValues, this); if (bAvailableSPByJob == false) Output.eResult = CDnSkillTreeSystem::R_NOT_ENOUGH_SKILLPOINT_TO_ACQUIRE; #endif // PRE_ADD_SKILL_LEVELUP_LIMIT_BY_SP // #36858 ±Û·Î¹ú ½ºÅ³·Î ¼­·Î ¿«¿© ÀÖ´Ù¸é ÇØ´ç ±×·ìÁß¿¡ Çϳª¸¸ ¹è¿öµµ ºÎ¸ð ½ºÅ³ Á¶°Ç¾øÀÌ ¹è¿ï ¼ö ÀÖ´Ù. bool bAlreadyGlobalSkillAcquired = HasSameGlobalIDSkill( nSkillID ); bool bIgnoreParentSkillCondition = ( (CDnSkillTreeSystem::R_DONT_HAVE_PARENT_SKILL == Output.eResult) || (CDnSkillTreeSystem::R_LOCKED_PARENTSKILL == Output.eResult) || (CDnSkillTreeSystem::R_NOT_ENOUGH_PARENT_SKILL_LEVEL == Output.eResult) ) && true == bAlreadyGlobalSkillAcquired; if( CDnSkillTreeSystem::R_SUCCESS == Output.eResult || true == bIgnoreParentSkillCondition ) { // ³»ºÎ¿¡¼­ Á÷Á¢ ·¹º§ 1·Î ¹Ù²Þ. //vector::iterator iter = m_vlPossessedSkill.begin(); //for( iter; m_vlPossessedSkill.end() != iter; ++iter ) //{ // if( iter->iSkillID == nSkillID ) // { // iter->iSkillLevel = 1; // break; // } //} bool bSuccess = AddSkill( nSkillID, 1 ); _ASSERT( bSuccess ); DnSkillHandle hAcquiredSkill = FindSkill( nSkillID ); m_pSession->ChangeSkillPoint( -hAcquiredSkill->GetNowLevelSkillPoint(), nSkillID, false, 0 ); m_pSession->GetDBConnection()->QueryModSkillLevel(m_pSession, nSkillID, 1, 0, -hAcquiredSkill->GetNowLevelSkillPoint(), DBDNWorldDef::SkillChangeCode::GainByBuy); // dbÀúÀå: ½ºÅ³Æ÷ÀÎÆ®±îÁö °°ÀÌ ¾÷µ¥ÀÌÆ® } else { switch( Output.eResult ) { // ij¸¯ÅÍ ¿ä±¸·¹º§ÀÌ ¸ðÀÚ¶÷. case CDnSkillTreeSystem::R_NOT_ENOUGH_CHAR_LEVEL: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_NOT_ENOUGH_CHAR_LEVEL; break; // ¼±Çà(ºÎ¸ð) ½ºÅ³ÀÌ ¾øÀ½. case CDnSkillTreeSystem::R_DONT_HAVE_PARENT_SKILL: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_DONT_HAVE_PARENT_SKILL; break; // ºÎ¸ð ½ºÅ³ÀÇ ·¹º§ÀÌ ÃæÁ·µÇÁö ¾ÊÀ½. case CDnSkillTreeSystem::R_NOT_ENOUGH_PARENT_SKILL_LEVEL: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_NOT_ENOUGH_PARENT_SKILL_LEVEL; break; // ½ºÅ³ Æ÷ÀÎÆ®°¡ ¸ðÀÚ¶ó¼­ ½ºÅ³À» ȹµæÇÒ ¼ö ¾øÀ½. case CDnSkillTreeSystem::R_NOT_ENOUGH_SKILLPOINT_TO_ACQUIRE: nRetCode = ERROR_SKILL_ACQUIRE_FAIL_NOT_ENOUGH_SKILLPOINT; break; } } } } return nRetCode; } void CDnPlayerActor::CheckAndRegisterObserverStateBlow( DnBlowHandle hBlow ) { switch( hBlow->GetBlowIndex() ) { // ºí·Ï »óÅÂÈ¿°ú case STATE_BLOW::BLOW_030: { CDnBlockBlow* pObservable = static_cast( hBlow.GetPointer() ); pObservable->RegisterObserver( m_pBubbleSystem ); } break; // ÆÐ¸µ »óÅÂÈ¿°ú case STATE_BLOW::BLOW_031: { CDnParryBlow* pObservable = static_cast( hBlow.GetPointer() ); pObservable->RegisterObserver( m_pBubbleSystem ); } break; // ÄðŸÀÓ ÆÐ¸µ »óÅÂÈ¿°ú. case STATE_BLOW::BLOW_153: { CDnCooltimeParryBlow* pObservable = static_cast( hBlow.GetPointer() ); pObservable->RegisterObserver( m_pBubbleSystem ); } break; } } void CDnPlayerActor::OnApplyPassiveSkillBlow( int iBlowID ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlowFromID( iBlowID ); if( hBlow ) CheckAndRegisterObserverStateBlow( hBlow ); } bool CDnPlayerActor::CanAddSkill( int nSkillTableID, int nLevel /*= 1*/ ) { TSkillData* pSkillData = g_pDataManager->GetSkillData( nSkillTableID ); if( pSkillData == NULL ) return false; if( GetGameRoom() == NULL ) return false; if( GetGameRoom()->bIsZombieMode() == true ) { if( CDnSkill::Passive == pSkillData->cSkillType && CDnSkill::DurationTypeEnum::Buff == pSkillData->cDurationType ) return false; } return true; } bool CDnPlayerActor::AddSkill( int nSkillTableID, int nLevel /* = 1 */, int iSkillLevelApplyType/* = CDnSkill::PVE*/ ) { bool bSuccess = false; if( 0 < nLevel ) { // ½ºÅ³ ·¹º§ µ¥ÀÌÅ͸¦ pve/pvp ÀÎ °æ¿ì¿Í ³ª´²¼­ ¼ÂÆÃÇØÁØ´Ù. int iSkillLevelDataType = CDnSkill::PVE; if( GetGameRoom()->bIsPvPRoom() ) iSkillLevelDataType = CDnSkill::PVP; bSuccess = MASkillUser::AddSkill( nSkillTableID, nLevel, iSkillLevelDataType ); vector::iterator iter = find( m_vlUnlockZeroLevelSkills.begin(), m_vlUnlockZeroLevelSkills.end(), nSkillTableID ); if( m_vlUnlockZeroLevelSkills.end() != iter ) m_vlUnlockZeroLevelSkills.erase( iter ); } else { // óÀ½¿¡ DB ·ÎºÎÅÍ ½ºÅ³ ¸®½ºÆ® ¹ÞÀ» ¶§ ·¹º§ÀÌ 0 À̸é ÀÌÂÊÀ¸·Î µé¾î¿Â´Ù. // ¾ð¶ô¸¸ µÇ¾îÀÖ°í ½ÇÁ¦·Î °®°íÀÖÁö´Â ¾ÊÀº ½ºÅ³. m_vlUnlockZeroLevelSkills.push_back( nSkillTableID ); bSuccess = true; } //if( bSuccess ) //{ // bool bFinded = false; // int iNumPossessed = (int)m_vlPossessedSkill.size(); // for( int i = 0; i < iNumPossessed; ++i ) // { // CDnSkillTreeSystem::S_POSSESSED_SKILL_INFO& PossessedSkill = m_vlPossessedSkill.at( i ); // if( PossessedSkill.iSkillID == nSkillTableID ) // { // PossessedSkill.iSkillLevel = nLevel; // bFinded = true; // } // } // if( false == bFinded ) // { // // unlock ¸¸ µÈ ·¹º§ 0 Â¥¸® ½ºÅ³µµ °¨¾ÈÇϱ⠶§¹®¿¡ °°ÀÌ ¸®½ºÆ®¿¡ ³Ö¾îÁØ´Ù. // CDnSkillTreeSystem::S_POSSESSED_SKILL_INFO SkillInfo; // SkillInfo.iSkillID = nSkillTableID; // SkillInfo.iSkillLevel = nLevel; // SkillInfo.bCurrentLock = false; // m_vlPossessedSkill.push_back( SkillInfo ); // } //} return bSuccess; } bool CDnPlayerActor::ExecuteSkill( DnSkillHandle hSkill, LOCAL_TIME LocalTime, float fDelta ) { ResetCustomAction(); // ¿À¶ó ½ºÅ³ÀÌ ²¨Áö´Â °ÍÀ¸·Î Åä±Û¸µ µÉ ¶© m_hAuraSkill ¾ø¾îÁü. // CDnActor::OnSkillExecute( LocalTime, fDelta ); DnSkillHandle hNowSkill; if( m_hAuraSkill ) hNowSkill = m_hAuraSkill; bool bResult = CDnActor::ExecuteSkill( hSkill, LocalTime, fDelta ); if( m_hProcessSkill ) hNowSkill = m_hProcessSkill; else if( m_hAuraSkill ) hNowSkill = m_hAuraSkill; if( bResult && hNowSkill ) { UpdateUseSkill( hNowSkill ); // ÀÏ´Ü ÀνºÅÏÆ®¸¸ ¾Æ´Ï¸é ¹«Á¶°Ç À̺¥Æ® ¹ß»ý½ÃŲ´Ù. ÃßÈÄ¿¡ ¿À¿À¶ó³ª ŸÀÓÅä±Û °°Àº °æ¿ìµµ ÇÊ¿ä¾ø´Ù¸é // ÀÌÂÊ¿¡¼­ ¶Ç °É·¯ÁØ´Ù. switch( hNowSkill->GetDurationType() ) { case CDnSkill::Instantly: break; default: { if( m_pSession && m_pSession->GetMissionSystem() ) { m_pSession->GetEventSystem()->OnEvent( EventSystem::OnSkillUse, 2, EventSystem::SkillID, hNowSkill->GetClassID(), EventSystem::SkillLevel, hNowSkill->GetLevel() ); } } break; } } #ifdef PRE_ADD_EXPORT_DPS_INFORMATION if( bResult && CDnDPSReporter::IsActive() ) { if(CDnDPSReporter::GetInstance().IsEnabledUser( GetCharacterDBID() )) { DNVector(DnActorHandle) hVecList; ScanActor( GetRoom(), *GetPosition() , 500.f , hVecList ); CDnDPSReporter::GetInstance().ReportSkillInfo( hSkill , (int)hVecList.size()); } } #endif return bResult; } void CDnPlayerActor::OnHitSuccess( LOCAL_TIME LocalTime, DnActorHandle hActor, HitStruct *pStruct ) { // #33265 by kalliste // #if defined( PRE_ADD_LOTUSGOLEM ) // if( hActor->GetHitParam()->bIgnoreShowDamage == true ) // { // m_nComboDelay = -1; // return; // } // #endif // #if defined( PRE_ADD_LOTUSGOLEM ) // #12170 ÄÞº¸ µô·¹ÀÌ °ªÀÌ 0ÀÎ hit ´Â ÄÞº¸ ÆÇÁ¤¿¡ ¾Æ¹«·± ¿µÇâÀ» ÁÖÁö ¾Êµµ·Ï ó¸®. if( m_bAllowCalcCombo && 0 < pStruct->nComboDelay ) { if( m_nComboDelay > 0 ) { #if defined( PRE_ADD_LOTUSGOLEM ) if( hActor->GetHitParam()->bIgnoreShowDamage == false ) m_nComboCount++; #else m_nComboCount++; #endif // #if defined( PRE_ADD_LOTUSGOLEM ) if( m_nComboCount > m_nTotalComboCount ) m_nTotalComboCount = m_nComboCount; UpdateMaxCombo( m_nComboCount ); } else { m_nComboCount = 1; } m_nComboDelay = pStruct->nComboDelay; if( m_nComboDelay == 0 ) { m_nComboCount = 0; } } switch( hActor->GetHitParam()->HitType ) { case CDnWeapon::Critical: UpdateCriticalHit(); break; case CDnWeapon::Stun: UpdateStunHit(); break; } CheckNormalHitSEProcessor( hActor, *hActor->GetHitParam() ); if( hActor && hActor->IsHit() && pStruct->szTargetHitAction != NULL ) { if( IsAppliedThisStateBlow(STATE_BLOW::BLOW_246) ) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_246, vlBlows ); for( DWORD i=0; iGetParentSkillInfo(); if( pSkillInfo ) { DnActorHandle hHitter = pSkillInfo->hSkillUser; if( hHitter == hActor ) { vlBlows[i]->SetState(STATE_BLOW::STATE_END); SendRemoveStateEffectFromID( vlBlows[i]->GetBlowID() ); } } } } } } } // ÀÌ ¾×ÅͰ¡ ½ð ¹ß»çü°¡ ¸íÁߵǾúÀ» ¶§. void CDnPlayerActor::OnHitProjectile( LOCAL_TIME LocalTime, DnActorHandle hHittedTarget, const CDnDamageBase::SHitParam& HitParam ) { CheckNormalHitSEProcessor( hHittedTarget, HitParam ); } void CDnPlayerActor::CheckNormalHitSEProcessor( DnActorHandle hHittedTarget, const CDnDamageBase::SHitParam& HitParam ) { // #23818 ¹«±â¿¡ ºÙÀº ¾ÆÀÌÅÛ Á¢µÎ¾î ½ºÅ³À» ó¸®Çϱâ À§ÇÑ "ÆòŸ" ¸¦ ±¸ºÐÇϱâ À§ÇÑ ÄÚµå. // ÆòŸÀÎ °æ¿ì¿£ ÆòŸ·Î ´ë»ó¿¡°Ô »óÅÂÈ¿°ú¸¦ ºÎ¿©ÇÏ´Â ¹ßÇöŸÀÔÀÌ ÀÖ´ÂÁö È®ÀÎÇØ¼­ ó¸®. if( hHittedTarget ) { // ³»°¡ ½ºÅ³À» ¾²°í ÀÖÁö ¾ÊÀ» ¶§¸¸. if( ( false == IsProcessSkill() || false == HitParam.bFromProjectileSkill) ) { int iNumApplySEProcessor = (int)m_vlpApplySEWhenNormalHitProcessor.size(); for( int i = 0; i < iNumApplySEProcessor; ++i ) { CDnApplySEWhenTargetNormalHitProcessor* pProcessor = static_cast( m_vlpApplySEWhenNormalHitProcessor.at( i ) ); pProcessor->OnNormalHitSuccess( hHittedTarget ); } } } } void CDnPlayerActor::OnHitFinish( LOCAL_TIME LocalTime, HitStruct *pStruct ) { CDnActor::OnHitFinish( LocalTime, pStruct ); /* if( m_nComboDelay > 0 && pStruct->bFinish ) { for( DWORD i=0; iIsAir() ) { m_nChainCount++; UpdateChainCombo(); char pBuffer[2]; CPacketCompressStream Stream( pBuffer, sizeof(pBuffer) ); Stream.Write( &m_nChainCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT ); Send( eActor::SC_CHAIN, &Stream ); break; } } } */ int nDieCount = 0; for( DWORD i=0; iIsDie() ) nDieCount++; } UpdateMissionByMonsterKillCount(nDieCount); } void CDnPlayerActor::UpdateMissionByMonsterKillCount(int nCount) { if( nCount >= 3 ) UpdateGenocide(); if( nCount >= 2 && m_pSession ) { m_pSession->GetEventSystem()->OnEvent( EventSystem::OnKillMonster, 1, EventSystem::GenocideCount, nCount ); } } void CDnPlayerActor::SaveUserData(TUserData &UserData) { #ifndef PRE_FIX_SKILLLIST memset( UserData.Skill.SkillList, 0, sizeof(UserData.Skill.SkillList) ); if( static_cast(GetRoom())->bIsPvPRoom() == false ) { int iIndex = 0; for( UINT i=0 ; iGetClassID(); UserData.Skill.SkillList[iIndex].cSkillLevel = hSkill->GetLevel(); UserData.Skill.SkillList[iIndex].nCoolTime = static_cast(hSkill->GetElapsedDelayTime()*1000); ++iIndex; } } #else memset( UserData.Skill[0].SkillList, 0, sizeof(UserData.Skill[0].SkillList) ); if( static_cast(GetRoom())->bIsPvPRoom() == false ) { int iIndex = 0; DWORD dwNumSkill = GetSkillCount(); for( DWORD i = 0; i < dwNumSkill; ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); if( !hSkill ) continue; UserData.Skill[0].SkillList[iIndex].nSkillID = hSkill->GetClassID(); UserData.Skill[0].SkillList[iIndex].cSkillLevel = hSkill->GetLevel(); UserData.Skill[0].SkillList[iIndex].nCoolTime = static_cast(hSkill->GetElapsedDelayTime()*1000); ++iIndex; } } #endif // #ifndef PRE_FIX_SKILLLIST UserData.Status.nGlyphDelayTime = (int)(m_afLastEquipItemSkillDelayTime * 1000.f); UserData.Status.nGlyphRemainTime = (int)(m_afLastEquipItemSkillRemainTime * 1000.f); if( GetUserSession() && m_nInvalidPlayerCheckCounter > 0 ) { g_Log.Log( LogType::_HACK, GetUserSession(), L"HackChecker(DB) : CharName=%s Counter=%d\n", GetUserSession()->GetCharacterName(), m_nInvalidPlayerCheckCounter ); m_pSession->GetDBConnection()->QueryAddAbuseMonitor( m_pSession, m_nInvalidPlayerCheckCounter, 0 ); m_nInvalidPlayerCheckCounter = 0; } } void CDnPlayerActor::SetUserSession(CDNUserSession * pSession) { m_pSession = pSession; m_pPartyData = pSession->GetGameRoom()->GetPartyData( m_pSession ); // EquipDelayTime, EquipRemainTime ¼¼ÆÃ ¿©±â¼­ ±×³É ÇØÁØ´Ù;; m_afLastEquipItemSkillDelayTime = (float)m_pSession->GetGlyphDelayTime() / 1000.f; m_afLastEquipItemSkillRemainTime = (float)m_pSession->GetGlyphRemainTime() / 1000.f; // ÇöÀç Àåºñ ½½·Ô¿¡ ¸ÅÄ¡µÇ´Â ½ºÅ³ÀÌ ÀÖ´Ù¸é ÄðŸÀÓ ¼ÂÆÃÇØÁÜ. if( m_ahEquipSkill ) m_ahEquipSkill->SetOnceCoolTime( m_afLastEquipItemSkillDelayTime, m_afLastEquipItemSkillRemainTime ); SetAccountLevel(m_pSession->GetAccountLevel()); } void CDnPlayerActor::ProcessCombo( LOCAL_TIME LocalTime, float fDelta ) { if( m_nComboDelay > 0 ) m_nComboDelay -= (int)( fDelta * 1000 ); if( m_nComboDelay < 0 ) { OnComboFinish( m_nComboCount ); m_nComboCount = 0; m_nComboDelay = 0; } } void CDnPlayerActor::OnComboFinish( int nCombo ) { if( nCombo > 1 ) { UpdateCombo( nCombo ); } } bool CDnPlayerActor::IsGMTrace() const { if( m_pSession && m_pSession->bIsGMTrace() ) return true; return false; } UINT CDnPlayerActor::GetSessionID() { return m_pSession ? m_pSession->GetSessionID() : 0; } int CDnPlayerActor::GetMoveSpeed() { int nMoveSpeed = CDnActor::GetMoveSpeed(); if( CDnWorld::IsActive(GetRoom()) && ( CDnWorld::GetInstance(GetRoom()).GetMapType() == EWorldEnum::MapTypeVillage || CDnWorld::GetInstance(GetRoom()).GetMapType() == EWorldEnum::MapTypeWorldMap ) ) nMoveSpeed += GetSafeZoneMoveSpeed(); if( IsTransformMode() ) { nMoveSpeed = g_pDataManager->GetMonsterMutationMoveSpeed( m_nMonsterMutationTableID ); if( m_cMovePushKeyFlag & 0x08 ) nMoveSpeed /= 2; return nMoveSpeed; } if( m_cMovePushKeyFlag & 0x08 ) nMoveSpeed /= 2; // #62481 ¿ùµåÁ¸ À̵¿¼Óµµ¸¦ ¸¶À»°ú µ¿ÀÏÇÏ°Ô º¯°æ if( !IsGhost() && !IsBattleMode() ) nMoveSpeed = (int)( nMoveSpeed * 1.4f ); if( IsDie() && IsGhost() ) nMoveSpeed = (int)( nMoveSpeed * 1.5f ); return nMoveSpeed; } void CDnPlayerActor::OnAddSkill( DnSkillHandle hSkill, bool isInitialize/* = false*/ ) { CDnActor::OnAddSkill( hSkill, isInitialize ); if( hSkill ) { bool bFinded = false; int iNumPossessed = (int)m_vlPossessedSkill.size(); for( int i = 0; i < iNumPossessed; ++i ) { CDnSkillTreeSystem::S_POSSESSED_SKILL_INFO& PossessedSkill = m_vlPossessedSkill.at( i ); if( PossessedSkill.iSkillID == hSkill->GetClassID() ) { PossessedSkill.iSkillLevel = hSkill->GetLevel(); bFinded = true; } } if( false == bFinded ) { // unlock ¸¸ µÈ ·¹º§ 0 Â¥¸® ½ºÅ³µµ °¨¾ÈÇϱ⠶§¹®¿¡ °°ÀÌ ¸®½ºÆ®¿¡ ³Ö¾îÁØ´Ù. CDnSkillTreeSystem::S_POSSESSED_SKILL_INFO SkillInfo; SkillInfo.iSkillID = hSkill->GetClassID(); SkillInfo.iSkillLevel = hSkill->GetLevel(); SkillInfo.bCurrentLock = false; m_vlPossessedSkill.push_back( SkillInfo ); } } // Ãß°¡µÈ ½ºÅ³ÀÌ °­È­ ÆÐ½Ãºê ½ºÅ³ÀÎ °æ¿ì.(°­È­ ÆÐ½Ãºê ½ºÅ³À» ȹµæ Ç߰ųª ´Ù¸¥ Ç÷¹À̾ ·¹º§¾÷ ÇÑ °æ¿ì) if( hSkill->GetSkillType() == CDnSkill::EnchantPassive ) { int iBaseSkillID = hSkill->GetBaseSkillID(); DnSkillHandle hBaseSkill = FindSkill( iBaseSkillID ); if( hBaseSkill ) { #if defined(PRE_FIX_64312) //¼Òȯ¸ó½ºÅÍ¿ë ½ºÅ³ÀÌ °æ¿ì ¹Ù·Î Àû¿ë ÇÏÁö ¾Ê°í ´ã¾Æ ³õ°í, MAAiSkill¿¡¼­ UseSkill½ÃÁ¡¿¡ Àû¿ë ÇÑ´Ù. bool isSummonMonsterSkill = false; isSummonMonsterSkill = hBaseSkill->IsSummonMonsterSkill(); if (isSummonMonsterSkill == false) hBaseSkill->ApplyEnchantSkill( hSkill ); else hBaseSkill->AddSummonMonsterEnchantSkill(hSkill); #else hBaseSkill->ApplyEnchantSkill( hSkill ); #endif // PRE_FIX_64312 } } else { // Ãß°¡µÈ ½ºÅ³ÀÌ °®°í ÀÖ´Â °­È­ ÆÐ½Ãºê ½ºÅ³ÀÇ º£À̽º ½ºÅ³ÀÎ °æ¿ì. (´Ù¸¥ Ç÷¹À̾îÀÇ °­È­µÈ ½ºÅ³ÀÌ ·¹º§¾÷ µÈ °æ¿ì) CheckAndApplyEnchantPassiveSkill( hSkill ); } } void CDnPlayerActor::OnRemoveSkill( DnSkillHandle hSkill ) { CDnActor::OnRemoveSkill( hSkill ); if( hSkill ) { vector::iterator iter = m_vlPossessedSkill.begin(); for( iter; iter != m_vlPossessedSkill.end(); ++iter ) { if( iter->iSkillID == hSkill->GetClassID() ) { m_vlPossessedSkill.erase( iter ); break; } } } // ´Ù¸¥ Ç÷¹À̾îÀÇ ÆÐ½Ãºê °­È­ ½ºÅ³ÀÌ ·¹º§¾÷ µÇ¾î ÀÌÀü ·¹º§ÀÇ ½ºÅ³ °´Ã¼°¡ »èÁ¦ ·çƾÀ» Ÿ°í ÀÌÂÊÀ¸·Î ¿À´Â °æ¿ì. // Àû¿ëµÇ°í ÀÖ´ø º£À̽º ½ºÅ³ÀÇ °­È­ »óŸ¦ ¸®¼ÂÀ¸·Î µ¹¸°´Ù. if( CDnSkill::EnchantPassive == hSkill->GetSkillType() && 0 < hSkill->GetBaseSkillID() ) { DnSkillHandle hBaseSkill = FindSkill( hSkill->GetBaseSkillID() ); if( hBaseSkill ) { #if defined(PRE_FIX_64312) //¼Òȯ¸ó½ºÅÍ¿ë ½ºÅ³ÀÌ °æ¿ì ¹Ù·Î Àû¿ë ÇÏÁö ¾Ê°í ´ã¾Æ ³õ°í, MAAiSkill¿¡¼­ UseSkill½ÃÁ¡¿¡ Àû¿ë ÇÑ´Ù. bool isSummonMonsterSkill = false; isSummonMonsterSkill = hBaseSkill->IsSummonMonsterSkill(); if (isSummonMonsterSkill == false) hBaseSkill->ReleaseEnchantSkill(); else hBaseSkill->RemoveSummonMonsterEnchantSkill(); #else hBaseSkill->ReleaseEnchantSkill(); #endif // PRE_FIX_64312 } } // ´Ù¸¥ Ç÷¹À̾îÀÇ ÆÐ½Ãºê °­È­ ½ºÅ³ÀÇ ´ë»óÀÌ µÇ´Â º£À̽º ½ºÅ³ÀÌ ·¹º§¾÷ µÇ¾î »èÁ¦ ·çƾÀ» Ÿ°í ÀÌÂÊÀ¸·Î ¿À´Â °æ¿ì. // ÀÌ °æ¿ì¿£ º£À̽º ½ºÅ³ °´Ã¼¸¦ ±×³É »èÁ¦ÇÏ¸é µÇ¹Ç·Î µû·Î ó¸®ÇÒ °ÍÀº ¾ø´Ù. } void CDnPlayerActor::ProcessRecoverySP( LOCAL_TIME LocalTime, float fDelta ) { if( IsDie() ) { m_fRecoverySPDelta = 0.f; return; } m_fRecoverySPDelta += fDelta; int nValue = GetSP(); if( m_fRecoverySPDelta >= s_fRecoverySPTime ) { m_fRecoverySPDelta -= s_fRecoverySPTime; nValue += GetRecoverySP(); } else return; if( GetSP() >= GetMaxSP() ) return; nValue = min( nValue, GetMaxSP() ); SetSP( nValue ); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nValue, sizeof(int) ); Send( eActor::SC_RECOVERYSP, &Stream ); } void CDnPlayerActor::CmdToggleWeaponViewOrder( int nEquipIndex, bool bShowCash ) { SetWeaponViewOrder( nEquipIndex, bShowCash ); RefreshWeaponViewOrder( nEquipIndex ); if( m_pSession ) { m_pSession->SetViewCashEquipBitmap(CASHEQUIP_WEAPON1 + nEquipIndex, bShowCash); } } void CDnPlayerActor::CmdTogglePartsViewOrder( int nEquipIndex, bool bShowCash ) { if ((nEquipIndex < 0) || (nEquipIndex >= _countof(m_bPartsViewOrder))) return; SetPartsViewOrder( nEquipIndex, bShowCash ); RefreshPartsViewOrder( nEquipIndex ); if( m_pSession ) m_pSession->SetViewCashEquipBitmap(nEquipIndex, bShowCash); } void CDnPlayerActor::CmdToggleHideHelmet( bool bHideHelmet ) { if( m_pSession ) m_pSession->SetViewCashEquipBitmap(HIDEHELMET_BITINDEX, bHideHelmet); } void CDnPlayerActor::CmdChangeJob( int nJobID ) { SetJobHistory( nJobID ); OnChangeJob( nJobID ); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &nJobID, sizeof(int) ); Send( eActor::SC_CHANGEJOB, m_pSession->GetSessionID(), &Stream ); } void CDnPlayerActor::CmdEscape( EtVector3 &vPos ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); Stream.Write( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT ); Send( eActor::SC_CMDESCAPE, &Stream ); } void CDnPlayerActor::ToggleGhostMode( bool bGhost ) { if( bGhost == m_bGhost ) return; m_bGhost = bGhost; if( bGhost == true && GetSP() > 0 ) SetSP(0); #ifdef PRE_FIX_GAMESERVER_USE_GHOST_MODE bool bGhostMode = true; CDnGameTask* pGameTask = m_pSession->GetGameRoom()->GetGameTask(); if( pGameTask && pGameTask->GetGameTaskType() == GameTaskType::PvP ) { bGhostMode = false; CDNGameRoom* pGameRoom = GetGameRoom(); #if defined(PRE_ADD_PVP_TOURNAMENT) if( pGameRoom && pGameRoom->GetPvPGameMode() && (pGameRoom->GetPvPGameMode()->bIsAllKillMode() || pGameRoom->GetPvPGameMode()->bIsTournamentMode())) #else if( pGameRoom && pGameRoom->GetPvPGameMode() && pGameRoom->GetPvPGameMode()->bIsAllKillMode() ) #endif //#if defined(PRE_ADD_PVP_TOURNAMENT) bGhostMode= true; } if( !bGhostMode ) { if( bGhost ) { if( IsMovable() || IsStay() ) { SetAction( "Die", 0.f, 0.f, false ); } } else { std::string szActionName = "Stand"; if(m_bShootMode) szActionName = "MOD_Stand"; if(IsTransformMode()) { if(IsExistAction( "Summon_On" )) szActionName = "Summon_On"; } SetAction( szActionName.c_str(), 0.f, 0.f ); } } else { if( bGhost ) { SwapSingleSkin( 499 + m_nClassID ); SetAction( "Stand", 0.f, 0.f ); } else { SwapSingleSkin( -1 ); SetAction( "Stand", 0.f, 0.f ); } } #endif if( m_bGhost && GetGameRoom() && GetGameRoom()->GetGameTask() ) GetGameRoom()->GetGameTask()->OnGhost( GetActorHandle() ); } void CDnPlayerActor::_CheckProcessSkillActioncChange( const char* pAction ) { // #26467 ¾×¼ÇÀÌ ¼ÂÆÃµÇ°í ´ÙÀ½ ÇÁ·¹ÀÓ¿¡ °»½ÅµÇ¹Ç·Î °ð¹Ù·Î ½ºÅ³ »ç¿ëÁßÀÎÁö Ã¼Å©ÇØ¼­ ½ºÅ³ ¾×¼ÇÀÌ ¾Æ´Ï¸é ½ºÅ³À» Á¾·á½Ã۵µ·Ï ÇÑ´Ù. if( m_hProcessSkill ) { m_setUseActionName.clear(); m_setUseActionName.insert( pAction ); if( false == m_hProcessSkill->IsUseActionNames( m_setUseActionName ) ) { if( false == (IsEnabledAuraSkill() && m_hProcessSkill->IsAuraOn()) ) { m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.f ); } m_hProcessSkill.Identity(); } } } void CDnPlayerActor::_CheckActionWithProcessPassiveActionSkill( const char* szPrevAction ) { // °°Àº ¾×¼Ç ¹Ýº¹ÁßÀÌ¸é ÆÐ½º if( szPrevAction && m_nPrevActionIndex == m_nActionIndex ) return; // if instantly passive skill, then cancel skill. ( ex) archer's spinkick) // because state effect must deactivate when change to another attack action. if( m_hProcessSkill ) { m_setUseActionName.clear(); m_setUseActionName.insert( szPrevAction ); // ÇöÀç ¾×¼ÇÀÌ prev ¾×¼ÇÀÇ next ¾×¼ÇÀ̶ó¸é ½ºÅ³ÀÌ À̾îÁö´Â °ÍÀ¸·Î º»´Ù. // ÀÌÀü ¾×¼ÇÀÌ ÇöÀç ÁøÇàÁßÀÎ ½ºÅ³¿¡¼­ »ç¿ëÇÏ´Â ¾×¼ÇÀ̾ú°í ÇöÀç ¾×¼ÇÀÌ ÀÌÀü ¾×¼ÇÀÇ next ¾×¼ÇÀÌ ¾Æ´Ï¶ó¸é // ÆÐ½Ãºê ½ºÅ³ÀÌ ³¡³­ °ÍÀ¸·Î ÆÇ´ÜÇÑ´Ù. ActionElementStruct* pElement = GetElement( szPrevAction ); bool bIsNextAction = false; if( pElement ) { // #25154 ±âº» ½ºÅÄµå ¾×¼ÇÀº ½ºÅ³¿¡¼­ ÁöÁ¤µÈ next ¾×¼ÇÀÌ À̾îÁö´Â °ÍÀ¸·Î º¸Áö ¾Ê´Â´Ù. // ¿À¶ó ½ºÅ³ ¾×¼ÇÀÌ ³¡³ª°í ÀÌ ÇÔ¼ö°¡ È£ÃâµÇ¾úÀ» ¶§ ÇöÀç ¾×¼ÇÀÌ Stand ·Î µÇ¾îÀִµ¥ ÇØ´ç ½ÃÁ¡¿¡¼­ // m_hProcessSkill ÀÌ ½ºÅ³ÀÌ ³¡³­ °ÍÀ¸·Î ÆÇ´ÜµÇ¾î¼­ NULL ·Î µÇ¾î¾ß ÇÑ´Ù. // m_hProcessSkill ÀÌ ³²¾ÆÀÖÀ¸¸é ´Ù¸¥ ½ºÅ³ ½èÀ» ¶§ °­Á¦·Î onend µÉ ¼ö Àֱ⠶§¹®¿¡ ¾ÈµÊ. // µû¶ó¼­ bIsNextAction ÀÌ false °¡ µÇ°í m_hProcessSkill->IsUseSkillActionNames() ÇÔ¼ö ³»ºÎ¿¡¼­ // ½ºÅ³ ¾×¼ÇÀÌ Á¾·áµÈ °ÍÀ¸·Î ÆÇ´ÜµÇ¾î¾ß ÇÑ´Ù. bIsNextAction = ((pElement->szNextActionName != "Stand") && (pElement->szNextActionName == GetCurrentAction())); } if( false == bIsNextAction && m_hProcessSkill->IsUseActionNames( m_setUseActionName ) ) { // ¾×Ƽºê ½ºÅ³ÀÌ ÆÐ½Ãºê ÇüÅ·Πµî·ÏµÇ¾î »ç¿ëµÇ¾úÀ»¶§ , GetPassiveSkillLengh() ·Î ¾Ë¼öÀÖ´Ù. if( ( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetPassiveSkillLength() != 0.f ) || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) && m_hProcessSkill->GetDurationType() == CDnSkill::Instantly ) { // ÆÐ½Ãºê ½ºÅ³ÀÌ Ã¼ÀÎ ÀÔ·ÂÀÌ µé¾î¿ÔÀ» ¶§¸¦ üũÇÑ´Ù. Çѹø üũµÇ´Â ¼ø°£ üÀÎ ÀÔ·Â Ç÷¡±×´Â ÃʱâÈ­µÈ´Ù. // üÀÎÀԷµǴ ¼ø°£ ¾×¼ÇÀÇ ±æÀ̸¸Å­ ÆÐ½Ãºê ½ºÅ³ »ç¿ë ±æÀ̰¡ ´Ã¾î³­´Ù. // ÀÌ·¸°Ô Ç÷¡±×¿Í ½Ã°£ µÑ ´Ù °°ÀÌ »ç¿ëÇØ¾ß ÆÐ½Ãºê ½ºÅ³ÀÇ ¿¬¼Ó üÀÎÀÌ °¡´ÉÇØÁø´Ù. if( false == m_hProcessSkill->CheckChainingPassiveSkill() ) { if( false == m_hProcessSkill->IsChainInputAction( GetCurrentAction() ) ) { m_hProcessSkill->OnEnd( MAActorRenderBase::m_LocalTime, 0.0f ); m_hProcessSkill.Identity(); } } } else if( IsEnabledAuraSkill() && m_hProcessSkill->IsAuraOn() ) { // Note Çѱâ: m_hProcessSkill ½º¸¶Æ® Æ÷ÀÎÅÍ´Â ¿À¶ó ½ºÅ³ »ç¿ëÇÏ´Â ¾×¼ÇÀÌ Àç»ýµÇ´Â µ¿¾ÈÀº À¯È¿ÇØ¾ß // °ÔÀÓ ¼­¹ö¿¡¼­ CDnPlayerActor::CmdStop() ÂÊ¿¡¼­ °É·¯Áö±â ¶§¹®¿¡ °× ¼­¹ö¿¡¼­ ÇØ´ç ¾×¼Ç ½Ã±×³ÎÀÌ ³¡±îÁö // 󸮵Ê. µû¶ó¼­ CDnActor::OnChangeAction ÂÊ¿¡¼­ ProcessAction À» Identity ½ÃÅ´. m_hProcessSkill.Identity(); ClearSelfStateSignalBlowQueue(); // ¿À¶ó ½ºÅ³ÀÇ ÀÚ±â Àڽſ¡°Ô Àû¿ëÇÏ´Â »óÅÂÈ¿°ú ŸÀÌ¹Ö ½Ã±×³Î¿¡ º¸³»Áִ ť ÃʱâÈ­ ½ÃÅ´. ¾È±×·³ ´Ù¸¥ ½ºÅ³¿¡ ¿µÇâÀ» ÁØ´Ù. } } } } void CDnPlayerActor::OnChangeAction( const char* szPrevAction ) { // 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() ); pChangeActionSetBlow->UpdateEnable( szPrevAction, GetCurrentAction() ); // ¾×¼Ç º¯°æ½Ã¿¡ »óÅÂÈ¿°ú Àû¿ë ¹ßÇöŸÀÔÀÌ ÀÖ´Ù¸é ÇÔ¼ö È£ÃâÇØÁÜ. // Ŭ¶ó¿¡¼­ ¾×¼ÇÀÌ ÀÌ¹Ì º¯È¯µÇ¾î ³¯¾Æ¿À±â ¶§¹®¿¡.. CDnChangeActionStrProcessor* pProcessor = pChangeActionSetBlow->GetChangeActionStrProcessor(); // ¾×¼Ç º¯°æ ¹ßÇöŸÀÔÀÌ ºñȰ¼ºÈ­ »óÅÂÀ϶§´Â NULL ¸®ÅϵÊ. if( pProcessor && pProcessor->IsChangedActionName( GetCurrentAction() ) ) { pChangeActionSetBlow->OnChangeAction(); } else { // ¼­¹ö¿¡¼­ ÀÚüÀûÀ¸·Î ¾×¼ÇÀÌ Ã³¸®µÇ´Â setaction ÂÊ¿¡¼­µµ È£ÃâÇØÁà¾ßÇÔ. pChangeActionSetBlow->OnNotChangeAction(); } } } _CheckActionWithProcessPassiveActionSkill( szPrevAction ); //CDnActor::OnChangeAction( szPrevAction ); if( !( szPrevAction && m_nPrevActionIndex == m_nActionIndex ) ) { if( CDnWorld::IsActive(GetRoom()) ) { CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "ChangeActionPlayer", GetUniqueID() ); CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnPlayerActor::OnChangeAction", CDnActionBase::m_LocalTime, 0.f ); } } m_bUseSignalSkillCheck = false; ZeroMemory( m_abSignalSkillCheck, sizeof(m_abSignalSkillCheck) ); // mixed ¾×¼ÇÁßÀÏ ¶§´Â mixed ¾×¼Ç ÆÐŶ ¿ÔÀ» ¶§ ÀÌ¹Ì ¾÷µ¥ÀÌÆ® µÈ »óÅÂ. if( false == m_bUpdatedProjectileInfoFromCmdAction ) { if( false == IsCustomAction() ) _UpdateMaxProjectileCount( m_nActionIndex ); } else m_bUpdatedProjectileInfoFromCmdAction = false; // ÀÌ ´ÙÀ½¿¡ OnChangeAction() È£ÃâµÇ¸é ¾÷µ¥ÀÌÆ® ÇØÁÖ¾î¾ß Çϱ⠶§¹®¿¡ Ç÷¡±×¸¦ ²¨ÁØ´Ù. // ¾×¼ÇÀÌ ¹Ù²î¸é ÅÒ Ã¼Å©Çϵµ·Ï ¿ø»ó º¹±¸ ½ÃÄÑÁÜ. m_bCheckProjectileSignalTerm = true; if( false == m_mapIcyFractionHitted.empty() ) m_mapIcyFractionHitted.clear(); // ¹öºí ½Ã½ºÅÛÂÊ¿¡ ¾Ë·ÁÁÜ. ¾ÆÄ«µ¥¹Í ÂÊ¿¡¼­ ¾²´Â °æ¿ì°¡.. boost::shared_ptr pEvent( IDnObserverNotifyEvent::Create( EVENT_ONCHANGEACTION ) ); Notify( pEvent ); } void CDnPlayerActor::OnBreakSkillSuperAmmor( int nIndex, int nOriginalSupperAmmor, int nDescreaseSupperAmmor ) { if( nOriginalSupperAmmor >= 200 ) { UpdateSuperAmmorBreak(); } } void CDnPlayerActor::OnAirCombo( int nComboCount ) { if( nComboCount >= 2 ) { UpdateAirCombo(); } } void CDnPlayerActor::PushSummonMonster( DnMonsterActorHandle hMonster, const SummonMonsterStruct* pSummonMonsterStruct, bool bReCreateFollowStageMonster/* = false*/ ) { CDnActor::PushSummonMonster( hMonster, pSummonMonsterStruct, bReCreateFollowStageMonster ); // ½ºÅ×ÀÌÁö À̵¿À¸·Î Àç»ý¼º µÇ´Â ¼Òȯ¸÷ÀÎÁö ¿©ºÎ¿Í °ü°è ¾øÀÌ (bReCreateFollowStageMonster) // ÇØ´ç ±×·ì ¾ÆÀ̵ð·Î ³Ö¾îÁØ´Ù. ½ºÅ×ÀÌÁö À̵¿Çϸ鼭 CDnActor::bIsCanSummonMonster() ÇÔ¼ö¿¡¼­ À¯È¿ÇÏÁö ¾ÊÀº // ¸ó½ºÅÍ ¾×ÅÍ °´Ã¼ ÇÚµéÀº Á¤¸®µÈ´Ù. if( 0 < pSummonMonsterStruct->nGroupID ) { m_mapSummonMonsterByGroup[ pSummonMonsterStruct->nGroupID ].push_back( hMonster ); hMonster->SetSummonGroupID( pSummonMonsterStruct->nGroupID ); } if( bReCreateFollowStageMonster ) { // °ü¸®µÇ°í ÀÖ´Â ½ºÅ×ÀÌÁö µû¶ó°¡´Â ¸ó½ºÅͰ¡ »õ ½ºÅ×ÀÌÁö¿¡¼­ ´Ù½Ã »ý¼ºµÇ´Â °æ¿ì ÇÚµé ±³Ã¼. DWORD dwMonsterClassID = hMonster->GetMonsterClassID(); std::list::iterator iter = m_listSummonedMonstersFollowStageInfos.begin(); for( iter; iter != m_listSummonedMonstersFollowStageInfos.end(); ++iter ) { if( false == iter->bReCreatedFollowStageMonster && dwMonsterClassID == iter->dwMonsterClassID ) { iter->hMonster = hMonster; iter->hMonster->SetActionQueue( "Stand" ); // »õ·Î ¼ÒȯµÇ´Â °ÍÀÌ ¾Æ´Ï¹Ç·Î °ð¹Ù·Î stand ¾×¼Ç. iter->hMonster->CmdWarp( *GetPosition(), EtVec3toVec2( *GetLookDir() ) ); iter->bReCreatedFollowStageMonster = true; break; } } } else { // Ãß°¡ÀûÀ¸·Î Ç÷¹À̾îÀÎ °æ¿ì ½ºÅ×ÀÌÁö À̵¿À̳ª Á¸ À̵¿(CmdWarp) ¸¦ ÇÏ´Â °æ¿ì µû¶ó°¡µµ·Ï ¼³Á¤µÈ ¼Òȯü´Â // ¶Ç µû·Î °®°í ÀÖµµ·Ï ÇÑ´Ù. if( pSummonMonsterStruct->bFollowSummonerStage ) { S_FOLLOWSTAGE_SUMMONED_MONSTER_INFO Info; Info.hMonster = hMonster; Info.dwMonsterClassID = hMonster->GetMonsterClassID(); #ifdef PRE_FIX_MEMOPT_SIGNALH CopyShallow_SummonMonsterStruct(Info.SummonMonsterSignalData, pSummonMonsterStruct); #else Info.SummonMonsterSignalData = *pSummonMonsterStruct; #endif Info.iRemainDestroyTime = pSummonMonsterStruct->nLifeTime; m_listSummonedMonstersFollowStageInfos.push_back( Info ); } } } // ¼ÒȯµÈ ¸ó½ºÅÍ °´Ã¼°¡ Á¦ÇÑ ½Ã°£ÀÌ ´Ù µÇ¾ú°Å³ª HP °¡ 0 ÀÌ µÇ¾î Á×´Â °æ¿ì È£ÃâµÊ. // ÀÌ µÎ°¡Áö °æ¿ì¿¡ ´ëÇØ¼­´Â ½ºÅ×ÀÌÁö¸¦ µû¶ó°¡´Â ¼Òȯ ¸ó½ºÅ͵éÀÇ °ü¸® ¸®½ºÆ®¿¡¼­ Á¦°ÅÇØÁØ´Ù. // ½ºÅ×ÀÌÁö À̵¿½Ã ÇØ´ç ¸ó½ºÅÍ °´Ã¼°¡ ÆÄ±«µÉ ¶§´Â È£ÃâµÇÁö ¾Ê´Â´Ù. void CDnPlayerActor::OnDieSummonedMonster( DnMonsterActorHandle hSummonedMonster ) { std::list::iterator iter = m_listSummonedMonstersFollowStageInfos.begin(); for( iter; iter != m_listSummonedMonstersFollowStageInfos.end(); ++iter ) { if( hSummonedMonster == iter->hMonster ) { m_listSummonedMonstersFollowStageInfos.erase( iter ); break; } } int iGroupID = hSummonedMonster->GetSummonGroupID(); if( 0 < m_mapSummonMonsterByGroup.count( iGroupID ) ) { list& listSummonedMonsters = m_mapSummonMonsterByGroup[ iGroupID ]; list::iterator iter = find( listSummonedMonsters.begin(), listSummonedMonsters.end(), hSummonedMonster ); if( listSummonedMonsters.end() != iter ) listSummonedMonsters.erase( iter ); // ÇØ´ç ±×·ìÀÇ ¸®½ºÆ®°¡ ºñ¾úÀ¸¸é ¸Ê¿¡¼­ Á¦°Å. if( listSummonedMonsters.empty() ) m_mapSummonMonsterByGroup.erase( iGroupID ); } #if defined(PRE_ADD_65808) if (hSummonedMonster) { CDnMonsterActor* pMonsterActor = static_cast(hSummonedMonster.GetPointer()); if (pMonsterActor) { RemoveSummonMonsterGlyphStateEffects(pMonsterActor->GetMonsterClassID()); } } #endif // PRE_ADD_65808 } // ½ºÅ×ÀÌÁö¿¡ ÀÖ´Â ¸ó½ºÅ͵éÀÌ »èÁ¦µÇ±â Á÷Àü¿¡ È£ÃâµÈ´Ù. // ÇÊ¿äÇÑ Á¤º¸¸¦ ¿©±â¼­ »Ì¾Æ³»¼­ °®°í Àִ´Ù. void CDnPlayerActor::OnBeforeDestroyStageMonsters( void ) { std::list::iterator iter = m_listSummonedMonstersFollowStageInfos.begin(); for( iter; iter != m_listSummonedMonstersFollowStageInfos.end(); ) { // ¸®½ºÆ®¿¡ °®°í ÀÖ´Â ¸ó½ºÅÍ ÇÚµéÀÌ invalid ÇÑ °æ¿ì¿£ ½ºÅ×ÀÌÁö À̵¿½Ã ¹ö¸®°í °£´Ù. if( iter->hMonster ) { iter->iRemainDestroyTime = iter->hMonster->GetRemainDestroyTime(); iter->bReCreatedFollowStageMonster = false; // TODO: Ãß°¡ÀûÀ¸·Î ¹Þ¾ÆµÑ ³»¿ëÀÌ ÀÖÀ¸¸é ¹Þ¾ÆµÐ´Ù. ++iter; } else { iter = m_listSummonedMonstersFollowStageInfos.erase( iter ); } } } void CDnPlayerActor::OnInitializeNextStageFinished( void ) { // ¼ÒȯµÈ ¸ó½ºÅÍ Á¦°ÅµÈ °Íµé »õ·Î »ý¼ºÇÑ´Ù. STE_SummonMonster ½Ã±×³Î ±×´ë·Î µ¹¸². CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); std::list::iterator iter = m_listSummonedMonstersFollowStageInfos.begin(); for( iter; iter != m_listSummonedMonstersFollowStageInfos.end(); ++iter ) { // ½ºÅ×ÀÌÁö À̵¿¿¡ µû¶ó ´Ù½Ã »ý¼ºÇÏ´Â ¸ó½ºÅÍÀ̱⠶§¹®¿¡ PushMonster() ÇÔ¼ö¿¡¼­ ¾×ÅÍ ÇÚµé °»½Å¸¸ ÀÌ·ç¾îÁø´Ù. // ´Ù½Ã ¼ÒȯÇÏ´Â ¸ó½ºÅÍÀÇ Áö¼Ó½Ã°£À» ³²Àº Áö¼Ó½Ã°£À¸·Î ¼ÂÆÃÇØÁÜ. iter->SummonMonsterSignalData.nLifeTime = (int)iter->iRemainDestroyTime; pTask->RequestSummonMonster( GetMySmartPtr(), &(iter->SummonMonsterSignalData), true ); } #ifdef PRE_ADD_WEEKLYEVENT RemoveEventStateBlow(); ApplyEventStateBlow(); #endif #if defined( PRE_FIX_70618 ) if( IsAppliedThisStateBlow(STATE_BLOW::BLOW_078) ) CmdRemoveStateEffect(STATE_BLOW::BLOW_078); #endif // #if defined( PRE_FIX_70618 ) } bool CDnPlayerActor::_bIsMasterSystemDurabilityReward() { if( GetGameRoom() && GetGameRoom()->GetMasterRewardSystem() ) { if( GetGameRoom()->GetMasterRewardSystem()->bIsDurabilityReward( m_pSession ) ) { #if defined( _WORK ) WCHAR wszBuf[MAX_PATH]; wsprintf( wszBuf, L"[»çÁ¦½Ã½ºÅÛ] ³»±¸µµ º¸»ó Àû¿ëÀ¸·Î ±ðÀÌÁö ¾ÊÀ½" ); m_pSession->SendDebugChat( wszBuf ); #endif // #if defined( _WORK ) return true; } } return false; } void CDnPlayerActor::OnRepairEquipDurability( bool bDBSave, INT64 nPriceCoin ) { bool bRefreshStatus = false; std::vector VecSerialList; std::vector VecDurList; VecSerialList.clear(); VecDurList.clear(); for( int i=CDnParts::Helmet; i<=CDnParts::Ring2; i++ ) { DnPartsHandle hParts = GetParts( (CDnParts::PartsTypeEnum)i ); if( !hParts ) continue; if( hParts->IsInfinityDurability() ) continue; if( hParts->GetDurability() == hParts->GetMaxDurability() ) continue; int nTemp = hParts->GetMaxDurability(); hParts->SetDurability( nTemp ); bRefreshStatus = true; m_pSession->GetItem()->SetEquipItemDurability( i, nTemp, true ); if (bDBSave && m_pSession->GetItem()->GetEquip(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetEquip(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetEquip(i)->wDur); } } for( int i=0; i<2; i++ ) { DnWeaponHandle hWeapon = m_hWeapon[i]; if( !hWeapon ) continue; if( hWeapon->IsInfinityDurability() ) continue; if( hWeapon->GetDurability() == hWeapon->GetMaxDurability() ) continue; int nTemp = hWeapon->GetMaxDurability(); hWeapon->SetDurability( nTemp ); bRefreshStatus = true; m_pSession->GetItem()->SetEquipItemDurability( EQUIP_WEAPON1 + i, nTemp, true ); if (bDBSave && m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)){ VecSerialList.push_back(m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)->wDur); } } if( bRefreshStatus ) { RefreshState( RefreshEquip, ST_All ); } if (bDBSave) { INT64 biCurrentCoin = 0; INT64 biPickUpCoin = 0; if( nPriceCoin > 0 ) { biCurrentCoin = m_pSession->GetCoin(); biPickUpCoin = m_pSession->GetPickUpCoin(); m_pSession->SelPickUpCoin(0); } m_pSession->GetDBConnection()->QueryModItemDurability(m_pSession, nPriceCoin, VecSerialList, VecDurList, biCurrentCoin, biPickUpCoin); } } void CDnPlayerActor::OnDecreaseEquipDurability( int nValue, bool bDBSave ) { if( _bIsMasterSystemDurabilityReward() ) return; bool bRefreshStatus = false; std::vector VecSerialList; std::vector VecDurList; VecSerialList.clear(); VecDurList.clear(); for( int i=CDnParts::Helmet; i<=CDnParts::Ring2; i++ ) { DnPartsHandle hParts = GetParts( (CDnParts::PartsTypeEnum)i ); if( !hParts ) continue; if( hParts->IsInfinityDurability() ) continue; if( hParts->GetDurability() == 0 ) continue; int nTemp = hParts->GetDurability() - nValue; if( nTemp <= 0 ) { nTemp = 0; bRefreshStatus = true; } hParts->SetDurability( nTemp ); m_pSession->GetItem()->SetEquipItemDurability( i, nTemp ); if (bDBSave && m_pSession->GetItem()->GetEquip(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetEquip(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetEquip(i)->wDur); } } for( int i=0; i<2; i++ ) { DnWeaponHandle hWeapon = m_hWeapon[i]; if( !hWeapon ) continue; if( hWeapon->IsInfinityDurability() ) continue; if( hWeapon->GetDurability() == 0 ) continue; int nTemp = hWeapon->GetDurability() - nValue; if( nTemp <= 0 ) { nTemp = 0; bRefreshStatus = true; } hWeapon->SetDurability( nTemp ); m_pSession->GetItem()->SetEquipItemDurability( EQUIP_WEAPON1 + i, nTemp ); if (bDBSave && m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)){ VecSerialList.push_back(m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)->wDur); } } if( bRefreshStatus ) { RefreshState( RefreshEquip, ST_All ); } if (bDBSave) m_pSession->GetDBConnection()->QueryModItemDurability(m_pSession, 0, VecSerialList, VecDurList); } void CDnPlayerActor::OnDecreaseEquipDurability( float fValue, bool bDBSave ) { if( _bIsMasterSystemDurabilityReward() ) return; bool bRefreshStatus = false; std::vector VecSerialList; std::vector VecDurList; VecSerialList.clear(); VecDurList.clear(); #if defined( PRE_ADD_TOTAL_LEVEL_SKILL ) float fTotalLevelValue = 0.0f; if ( m_pRoom->bIsPvPRoom() == false && IsAppliedThisStateBlow(STATE_BLOW::BLOW_259)) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex(STATE_BLOW::BLOW_259, vlBlows); { int nCount = (int)vlBlows.size(); for (int i = 0; i < nCount; ++i) { DnBlowHandle hBlow = vlBlows[i]; if (hBlow && hBlow->IsEnd() == false) { fTotalLevelValue += hBlow->GetFloatValue(); } } } } #endif for( int i=CDnParts::Helmet; i<=CDnParts::Ring2; i++ ) { DnPartsHandle hParts = GetParts( (CDnParts::PartsTypeEnum)i ); if( !hParts ) continue; if( hParts->IsInfinityDurability() ) continue; if( hParts->GetDurability() == 0 ) continue; #if defined( PRE_ADD_TOTAL_LEVEL_SKILL ) int nTemp = (int)( hParts->GetDurability() - (( hParts->GetMaxDurability() * fValue ) * (1 - fTotalLevelValue)) ); #else int nTemp = (int)( hParts->GetDurability() - ( hParts->GetMaxDurability() * fValue ) ); #endif if( nTemp <= 0 ) { nTemp = 0; bRefreshStatus = true; } hParts->SetDurability( nTemp ); m_pSession->GetItem()->SetEquipItemDurability( i, nTemp ); if (bDBSave && m_pSession->GetItem()->GetEquip(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetEquip(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetEquip(i)->wDur); } } for( int i=0; i<2; i++ ) { DnWeaponHandle hWeapon = m_hWeapon[i]; if( !hWeapon ) continue; if( hWeapon->IsInfinityDurability() ) continue; if( hWeapon->GetDurability() == 0 ) continue; #if defined( PRE_ADD_TOTAL_LEVEL_SKILL ) int nTemp = (int)( hWeapon->GetDurability() - (( hWeapon->GetMaxDurability() * fValue ) * (1 - fTotalLevelValue)) ); #else int nTemp = (int)( hWeapon->GetDurability() - ( hWeapon->GetMaxDurability() * fValue ) ); #endif if( nTemp <= 0 ) { nTemp = 0; bRefreshStatus = true; } hWeapon->SetDurability( nTemp ); m_pSession->GetItem()->SetEquipItemDurability( EQUIP_WEAPON1 + i, nTemp ); if (bDBSave && m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)){ VecSerialList.push_back(m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetEquip(EQUIP_WEAPON1 + i)->wDur); } } if( bRefreshStatus ) { RefreshState( RefreshEquip, ST_All ); } if (bDBSave) m_pSession->GetDBConnection()->QueryModItemDurability(m_pSession, 0, VecSerialList, VecDurList); } void CDnPlayerActor::OnDecreaseInvenDurability( int nValue, bool bDBSave ) { if( _bIsMasterSystemDurabilityReward() ) return; std::vector VecSerialList; std::vector VecDurList; VecSerialList.clear(); VecDurList.clear(); for( int i=0; iGetItem()->GetInventory(i); if( !pItem ) continue; switch( g_pDataManager->GetItemMainType( pItem->nItemID ) ) { case ITEMTYPE_WEAPON: { CDnWeapon *pWeapon = static_cast(m_pPartyData->pInventory[i]); if( !pWeapon ) continue; if( pWeapon->IsInfinityDurability() ) continue; if( pWeapon->GetDurability() == 0 ) continue; int nTemp = pWeapon->GetDurability() - nValue; if( nTemp <= 0 ) nTemp = 0; pWeapon->SetDurability( nTemp ); m_pSession->GetItem()->SetInvenItemDurability( i, nTemp ); if (bDBSave && m_pSession->GetItem()->GetInventory(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetInventory(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetInventory(i)->wDur); } } break; case ITEMTYPE_PARTS: { CDnParts *pParts = static_cast(m_pPartyData->pInventory[i]); if( pParts->IsInfinityDurability() ) continue; if( pParts->GetDurability() == 0 ) continue; int nTemp = pParts->GetDurability() - nValue; if( nTemp <= 0 ) nTemp = 0; pParts->SetDurability( nTemp ); m_pSession->GetItem()->SetInvenItemDurability( i, nTemp ); if (bDBSave && m_pSession->GetItem()->GetInventory(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetInventory(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetInventory(i)->wDur); } } break; default: continue; } } if (bDBSave) m_pSession->GetDBConnection()->QueryModItemDurability(m_pSession, 0, VecSerialList, VecDurList); } void CDnPlayerActor::OnDecreaseInvenDurability( float fValue, bool bDBSave ) { if( _bIsMasterSystemDurabilityReward() ) return; std::vector VecSerialList; std::vector VecDurList; VecSerialList.clear(); VecDurList.clear(); for( int i=0; iGetItem()->GetInventory(i); if( !pItem ) continue; switch( g_pDataManager->GetItemMainType( pItem->nItemID ) ) { case ITEMTYPE_WEAPON: { CDnWeapon *pWeapon = static_cast(m_pPartyData->pInventory[i]); if( !pWeapon ) continue; if( pWeapon->IsInfinityDurability() ) continue; if( pWeapon->GetDurability() == 0 ) continue; int nTemp = (int)( pWeapon->GetDurability() - ( pWeapon->GetMaxDurability() * fValue ) ); if( nTemp <= 0 ) nTemp = 0; pWeapon->SetDurability( nTemp ); m_pSession->GetItem()->SetInvenItemDurability( i, nTemp ); if (m_pSession->GetItem()->GetInventory(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetInventory(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetInventory(i)->wDur); } } break; case ITEMTYPE_PARTS: { CDnParts *pParts = static_cast(m_pPartyData->pInventory[i]); if( !pParts ) continue; if( pParts->IsInfinityDurability() ) continue; if( pParts->GetDurability() == 0 ) continue; int nTemp = (int)( pParts->GetDurability() - ( pParts->GetMaxDurability() * fValue ) ); if( nTemp <= 0 ) nTemp = 0; pParts->SetDurability( nTemp ); m_pSession->GetItem()->SetInvenItemDurability( i, nTemp ); if (m_pSession->GetItem()->GetInventory(i)){ VecSerialList.push_back(m_pSession->GetItem()->GetInventory(i)->nSerial); VecDurList.push_back(m_pSession->GetItem()->GetInventory(i)->wDur); } } break; default: continue; } } m_pSession->GetDBConnection()->QueryModItemDurability(m_pSession, 0, VecSerialList, VecDurList); } bool CDnPlayerActor::IsPenaltyStageGiveUp() { if (!m_pRoom) return false; switch( m_pRoom->GetGameTaskType() ) { case GameTaskType::PvP: return false; case GameTaskType::DarkLair: return false; case GameTaskType::Farm: return false; default: break; } if (IsDie()) return false; if (CDnWorld::IsActive(GetRoom())) { EWorldEnum::MapTypeEnum mapType = CDnWorld::GetInstance(GetRoom()).GetMapType(); if (mapType == EWorldEnum::MapTypeDungeon) { CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); if (pTask->GetDungeonClearState() == CDnGameTask::DCS_WarpStandBy) return false; } else { return false; } } return true; } // ³»±¸µµ °¨¼Ò°¡ µÇ¾úÀ¸¸é return true; ±×·¸Áö ¾ÊÀ¸¸é return false; bool CDnPlayerActor::OnStageGiveUp() { if (IsPenaltyStageGiveUp() == false) return false; DNTableFileFormat *pDungeonSox = GetDNTable( CDnTableDB::TDUNGEONENTER ); if( pDungeonSox->GetFieldFromLablePtr( GetGameRoom()->GetGameTask()->GetDungeonEnterTableID(), "_StageOutDurability" )->GetInteger() == 0) return false; OnDecreaseEquipDurability( CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StageGiveupDurabilityPenalty ), true ); OnDecreaseInvenDurability( CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StageGiveupDurabilityPenalty ), true ); // Æ÷±âÇÏ°í °¡¸é Equip ÀÌ¾ß ¾Ë¾Æ¼­ °»½ÅµÇÁö¸¸ Àκ¥Å丮´Â ±×·¸Áö ¾Ê½À´Ï´Ù. ±×·¡¼­ ¾Ë·ÁÁà¾ß ÇÕ´Ï´Ù. if( m_pSession ) { float fRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StageGiveupDurabilityPenalty ); m_pSession->SendDecreaseDurabilityInventory( 1, (void*)&fRatio ); } return true; } void CDnPlayerActor::RecvPartyRefreshGateInfo( const EtVector3& Pos ) { SetPosition( Pos ); SetStaticPosition( Pos ); } bool CDnPlayerActor::AttachParts( DnPartsHandle hParts, CDnParts::PartsTypeEnum Index, bool bDelete ) { if( !hParts ) return false; bool bResult = MAPartsBody::AttachParts( hParts, Index, bDelete ); #if defined(_GAMESERVER) int nSkillID = -1; int nSkillLevel = 0; if (hParts->HasPrefixSkill(nSkillID, nSkillLevel)) { DnSkillHandle hSkill = CDnSkill::CreateSkill(GetMySmartPtr(), nSkillID, nSkillLevel); if (!hSkill) { OutputDebug("%s ==> SkillID %d, SkillLevel %d... CreateSkill Failed!!!!\n", __FUNCTION__, nSkillID, nSkillLevel); } else { #if defined(PRE_ADD_PREFIXSKILL_PVP) // ½ºÅ³ ·¹º§ µ¥ÀÌÅ͸¦ pve/pvp ÀÎ °æ¿ì¿Í ³ª´²¼­ ¼ÂÆÃÇØÁØ´Ù. int iSkillLevelDataType = CDnSkill::PVE; if( GetGameRoom()->bIsPvPRoom() ) iSkillLevelDataType = CDnSkill::PVP; hSkill->SelectLevelDataType( iSkillLevelDataType ); #endif // PRE_ADD_PREFIXSKILL_PVP if (!MASkillUser::AddPreFixSystemDefenceSkill(Index, hSkill)) { SAFE_RELEASE_SPTR(hSkill); OutputDebug("MASkillUser::AddPreFixSystemDeffenceSkill ===> slotIndex %d, ItemID %d, SkillID %d, SkillLevel %d AddPreFixSystem Deffence skill Failed !!!\n", Index, hParts->GetClassID(), nSkillID, nSkillLevel); } } } #endif // _GAMESERVER int nLevelUpSkillID = -1; int nLevelUpSkillLevelValue = 0; int nLevelUpItemSkillUsingType = 0; if (hParts->HasLevelUpInfo(nLevelUpSkillID, nLevelUpSkillLevelValue, nLevelUpItemSkillUsingType)) { if (CDnItem::ItemSkillApplyType::SkillLevelUp == nLevelUpItemSkillUsingType) AddSkillLevelUpInfo(Index, nLevelUpSkillID, nLevelUpSkillLevelValue); } return bResult; } bool CDnPlayerActor::DetachParts( CDnParts::PartsTypeEnum Index ) { #if defined(_GAMESERVER) MASkillUser::RemovePreFixSystemDefenceSkill(Index); #endif // _GAMESERVER RemoveSkillLevelUpInfo(Index); // Note: ÆÄÃ÷ ºÐ¸®¿¡ ½ÇÆÐÇÑ °æ¿ì¿¡µµ ½ºÅ³Àº »ç¶óÁú ¼ö ÀÖÀ½. bool bResult = MAPartsBody::DetachParts( Index ); return bResult; } bool CDnPlayerActor::AttachCashParts( DnPartsHandle hParts, CDnParts::PartsTypeEnum Index, bool bDelete ) { if( !hParts ) return false; bool bResult = MAPartsBody::AttachCashParts( hParts, Index, bDelete ); int nLevelUpSkillID = -1; int nLevelUpSkillLevelValue = 0; int nLevelUpItemSkillUsingType = 0; if (hParts->HasLevelUpInfo(nLevelUpSkillID, nLevelUpSkillLevelValue, nLevelUpItemSkillUsingType)) { if (CDnItem::ItemSkillApplyType::SkillLevelUp == nLevelUpItemSkillUsingType) AddSkillLevelUpInfoByCashItem(Index, nLevelUpSkillID, nLevelUpSkillLevelValue); } return bResult; } bool CDnPlayerActor::DetachCashParts( CDnParts::PartsTypeEnum Index ) { RemoveSkillLevelUpInfoByCashItem(Index); // Note: ÆÄÃ÷ ºÐ¸®¿¡ ½ÇÆÐÇÑ °æ¿ì¿¡µµ ½ºÅ³Àº »ç¶óÁú ¼ö ÀÖÀ½. bool bResult = MAPartsBody::DetachCashParts( Index ); return bResult; } void CDnPlayerActor::ReplacementGlyph( DnSkillHandle hNewSkill ) { DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TGLYPHSKILL ); if( !pSox ) { g_Log.Log( LogType::_FILELOG, L"GlyphSkillTable.ext failed\r\n"); return; } int iSkillID = hNewSkill->GetClassID(); for( int itr = 0; itr < CDnGlyph::GlyphSlotEnum_Amount; ++itr ) { if( m_hGlyph[itr] ) { int eType = pSox->GetFieldFromLablePtr( m_hGlyph[itr]->GetClassID(), "_GlyphType" )->GetInteger(); int iGlyphSkillID = pSox->GetFieldFromLablePtr( m_hGlyph[itr]->GetClassID(), "_SkillID" )->GetInteger(); if( CDnGlyph::PassiveSkill == eType && iSkillID == iGlyphSkillID ) hNewSkill->AddGlyphStateEffect( m_hGlyph[itr]->GetClassID() ); } } } bool CDnPlayerActor::AttachGlyph( DnGlyphHandle hGlyph, CDnGlyph::GlyphSlotEnum Index, bool bDelete /* = false */ ) { if( !MAPlateUser::AttachGlyph( hGlyph, Index, bDelete ) ) return false; DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TGLYPHSKILL ); if( !pSox ) { g_Log.Log( LogType::_FILELOG, L"GlyphSkillTable.ext failed\r\n"); return false; } int eType = pSox->GetFieldFromLablePtr( hGlyph->GetClassID(), "_GlyphType" )->GetInteger(); // ¹®Àå¿¡ ½ºÅ³ÀÌ Á¸Àç ÇÒ °æ¿ì ¹®ÀåÀÌ ½ºÅ³Ãß°¡ ÀÎÁö ½ºÅ³È¿°úÃß°¡ ÀÎÁö ¾Ë¾Æ ³½´Ù. if( CDnItem::TemperedSkill == eType ) { DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TGLYPHSKILL ); if( !pSox ) { g_Log.Log( LogType::_FILELOG, L"GlyphSkillTable.ext failed\r\n"); return false; } int nSkillID = pSox->GetFieldFromLablePtr( hGlyph->GetClassID(), "_SkillID" )->GetInteger(); DnSkillHandle hSkill = FindSkill( nSkillID ); if( !hSkill ) return false; //CDnSkill¿¡ SkillEffect¸¦ Ãß°¡ÇؾßÇÔ hSkill->AddGlyphStateEffect( hGlyph->GetClassID() ); } else if( CDnItem::AddSKill == eType && 0 != hGlyph->GetSkillID() && 0 != hGlyph->GetSkillLevel() ) { AddSkill( hGlyph->GetSkillID(), hGlyph->GetSkillLevel() ); DnSkillHandle hSkill = FindSkill( hGlyph->GetSkillID() ); if( !hSkill ) return false; hSkill->AsEquipItemSkill(); hSkill->SetEquipIndex( Index ); m_ahEquipSkill = hSkill; if( 0.0f != m_afLastEquipItemSkillDelayTime ) { hSkill->SetOnceCoolTime( m_afLastEquipItemSkillDelayTime, m_afLastEquipItemSkillRemainTime ); } } return true; } bool CDnPlayerActor::DetachGlyph( CDnGlyph::GlyphSlotEnum Index ) { DnGlyphHandle hGlyph = m_hGlyph[Index]; if( !hGlyph ) return false; DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TGLYPHSKILL ); if( !pSox ) { g_Log.Log( LogType::_FILELOG, L"GlyphSkillTable.ext failed\r\n"); return false; } int eType = pSox->GetFieldFromLablePtr( hGlyph->GetClassID(), "_GlyphType")->GetInteger(); if( CDnItem::TemperedSkill == eType ) { int nSkillID = pSox->GetFieldFromLablePtr( hGlyph->GetClassID(), "_SkillID")->GetInteger(); DnSkillHandle hSkill = FindSkill( nSkillID ); if( !hSkill ) return false; hSkill->DelGlyphStateEffect( hGlyph->GetClassID() ); } else if( CDnItem::AddSKill == eType && 0 != hGlyph->GetSkillID() && 0 != hGlyph->GetSkillLevel() ) { DnSkillHandle hSkill = FindSkill( hGlyph->GetSkillID() ); m_afLastEquipItemSkillDelayTime = hSkill->GetDelayTime(); m_afLastEquipItemSkillRemainTime = hSkill->GetElapsedDelayTime(); RemoveSkill( hGlyph->GetSkillID() ); } return true; } void CDnPlayerActor::AttachWeapon( DnWeaponHandle hWeapon, int nEquipIndex /*= 0*/, bool bDelete/* = false */) { CDnActor::AttachWeapon( hWeapon, nEquipIndex, bDelete ); #if defined(PRE_ADD_50907) if (IsSkipOnAttatchDetachWeapon() == true) return; #endif // PRE_ADD_50907 RefreshWeaponViewOrder( nEquipIndex ); if( m_hCashWeapon[nEquipIndex] ) { m_hCashWeapon[nEquipIndex]->RecreateCashWeapon( GetMySmartPtr(), nEquipIndex ); LinkCashWeapon( nEquipIndex ); } #if defined(_GAMESERVER) int nSkillID = -1; int nSkillLevel = 0; if (hWeapon->HasPrefixSkill(nSkillID, nSkillLevel)) { DnSkillHandle hSkill = CDnSkill::CreateSkill(GetMySmartPtr(), nSkillID, nSkillLevel); if (!hSkill) { OutputDebug("%s ==> SkillID %d, SkillLevel %d... CreateSkill Failed!!!!\n", __FUNCTION__, nSkillID, nSkillLevel); } else { #if defined(PRE_ADD_PREFIXSKILL_PVP) // ½ºÅ³ ·¹º§ µ¥ÀÌÅ͸¦ pve/pvp ÀÎ °æ¿ì¿Í ³ª´²¼­ ¼ÂÆÃÇØÁØ´Ù. int iSkillLevelDataType = CDnSkill::PVE; if( GetGameRoom()->bIsPvPRoom() ) iSkillLevelDataType = CDnSkill::PVP; hSkill->SelectLevelDataType( iSkillLevelDataType ); #endif // PRE_ADD_PREFIXSKILL_PVP if (!MASkillUser::AddPreFixSystemOffenceSkill(nEquipIndex, hSkill)) { SAFE_RELEASE_SPTR(hSkill); OutputDebug("MASkillUser::AddPreFixSystemOffenceSkill ===> slotIndex %d, ItemID %d, SkillID %d, SkillLevel %d AddPreFixSystem Deffence skill Failed !!!\n", nEquipIndex, hWeapon->GetClassID(), nSkillID, nSkillLevel); } } } #endif // _GAMESERVER int nLevelUpSkillID = -1; int nLevelUpSkillLevelValue = 0; int nLevelUpItemSkillUsingType = 0; if (hWeapon->HasLevelUpInfo(nLevelUpSkillID, nLevelUpSkillLevelValue, nLevelUpItemSkillUsingType)) { if (CDnItem::ItemSkillApplyType::SkillLevelUp == nLevelUpItemSkillUsingType) AddSkillLevelUpInfo(CDnParts::PartsTypeEnum::PartsTypeEnum_Amount+nEquipIndex, nLevelUpSkillID, nLevelUpSkillLevelValue); } } void CDnPlayerActor::DetachWeapon( int nEquipIndex/* = 0*/ ) { CDnActor::DetachWeapon( nEquipIndex ); #if defined(PRE_ADD_50907) if (IsSkipOnAttatchDetachWeapon() == true) return; #endif // PRE_ADD_50907 RefreshWeaponViewOrder( nEquipIndex ); #if defined(_GAMESERVER) MASkillUser::RemovePreFixSystemOffenceSkill(nEquipIndex); #endif // _GAMESERVER RemoveSkillLevelUpInfo(CDnParts::PartsTypeEnum::PartsTypeEnum_Amount+nEquipIndex); } void CDnPlayerActor::AttachCashWeapon( DnWeaponHandle hWeapon, int nEquipIndex, bool bDelete ) { if( m_hCashWeapon[nEquipIndex] ) { DetachCashWeapon( nEquipIndex ); } m_hCashWeapon[nEquipIndex] = hWeapon; m_bCashSelfDeleteWeapon[nEquipIndex] = bDelete; if( !m_hCashWeapon[nEquipIndex] ) return; m_hCashWeapon[nEquipIndex]->CreateObject(); RefreshWeaponViewOrder( nEquipIndex ); m_hCashWeapon[nEquipIndex]->RecreateCashWeapon( GetMySmartPtr(), nEquipIndex ); LinkCashWeapon( nEquipIndex ); int nLevelUpSkillID = -1; int nLevelUpSkillLevelValue = 0; int nLevelUpItemSkillUsingType = 0; if (hWeapon->HasLevelUpInfo(nLevelUpSkillID, nLevelUpSkillLevelValue, nLevelUpItemSkillUsingType)) { if (CDnItem::ItemSkillApplyType::SkillLevelUp == nLevelUpItemSkillUsingType) AddSkillLevelUpInfoByCashItem(CASHEQUIP_WEAPON1+nEquipIndex, nLevelUpSkillID, nLevelUpSkillLevelValue); } } void CDnPlayerActor::LinkCashWeapon( int nEquipIndex ) { switch( m_hCashWeapon[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_hCashWeapon[nEquipIndex]->LinkWeapon( GetMySmartPtr(), nEquipIndex ); break; case CDnWeapon::Arrow: m_hCashWeapon[nEquipIndex]->LinkWeapon( GetMySmartPtr(), m_hCashWeapon[0] ); break; } } void CDnPlayerActor::DetachCashWeapon( int nEquipIndex ) { if( !m_hCashWeapon[nEquipIndex] ) return; m_hCashWeapon[nEquipIndex]->FreeObject(); m_hCashWeapon[nEquipIndex]->UnlinkWeapon(); if( m_bCashSelfDeleteWeapon[nEquipIndex] ) { SAFE_RELEASE_SPTR( m_hCashWeapon[nEquipIndex] ); m_bCashSelfDeleteWeapon[nEquipIndex] = false; } m_hCashWeapon[nEquipIndex].Identity(); RefreshWeaponViewOrder( nEquipIndex ); RemoveSkillLevelUpInfoByCashItem(CASHEQUIP_WEAPON1+nEquipIndex); } void CDnPlayerActor::ShowCashWeapon( int nEquipIndex, bool bShow ) { if( m_hCashWeapon[nEquipIndex] ) m_hCashWeapon[nEquipIndex]->ShowWeapon( bShow ); } void CDnPlayerActor::SetWeaponViewOrder( int nEquipIndex, bool bShowCash ) { if( nEquipIndex < 0 || nEquipIndex >= 2 ) return; m_bWeaponViewOrder[nEquipIndex] = bShowCash; } void CDnPlayerActor::RefreshWeaponViewOrder( int nEquipIndex ) { if( nEquipIndex < 0 || nEquipIndex >= 2 ) return; if( m_hWeapon[nEquipIndex] && m_hCashWeapon[nEquipIndex] ) { if( m_bWeaponViewOrder[nEquipIndex] ) { if( !m_hCashWeapon[nEquipIndex]->IsCreateObject() ) { m_hCashWeapon[nEquipIndex]->CreateObject(); m_hCashWeapon[nEquipIndex]->RecreateCashWeapon( GetMySmartPtr(), nEquipIndex ); LinkCashWeapon( nEquipIndex ); m_hCashWeapon[nEquipIndex]->ShowWeapon( true ); } if( m_hWeapon[nEquipIndex]->IsCreateObject() ) { m_hWeapon[nEquipIndex]->FreeObject(); m_hWeapon[nEquipIndex]->ShowWeapon( false ); } } else { if( !m_hWeapon[nEquipIndex]->IsCreateObject() ) { m_hWeapon[nEquipIndex]->CreateObject(); LinkWeapon( nEquipIndex ); m_hWeapon[nEquipIndex]->ShowWeapon( true ); } if( m_hCashWeapon[nEquipIndex]->IsCreateObject() ) { m_hCashWeapon[nEquipIndex]->FreeObject(); m_hCashWeapon[nEquipIndex]->ShowWeapon( false ); } } } else if( m_hWeapon[nEquipIndex] && !m_hCashWeapon[nEquipIndex] ) { if( !m_hWeapon[nEquipIndex]->IsCreateObject() ) { m_hWeapon[nEquipIndex]->CreateObject(); LinkWeapon( nEquipIndex ); m_hWeapon[nEquipIndex]->ShowWeapon( true ); } } else { if( nEquipIndex == 0 ) { if( m_hCashWeapon[nEquipIndex] && m_hCashWeapon[nEquipIndex]->IsCreateObject() ) { m_hCashWeapon[nEquipIndex]->FreeObject(); m_hCashWeapon[nEquipIndex]->ShowWeapon( false ); } } } SetBattleMode( IsBattleMode() ); } void CDnPlayerActor::OnEventCP( CPTypeEnum Type, int nResult ) { #if defined( PRE_ADD_CP_RENEWAL ) MACP_Renewal::OnEventCP( Type, nResult ); #else // #if defined( PRE_ADD_CP_RENEWAL ) MACP::OnEventCP( Type, nResult ); #endif // #if defined( PRE_ADD_CP_RENEWAL ) switch( Type ) { case MACP::MaxComboCount: case MACP::KillBossCount: case MACP::SuperAmmorBreakScore: case MACP::GenocideScore: case MACP::AirComboScore: case MACP::RebirthPlayerScore: case MACP::ComboScore: case MACP::PartyComboScore: case MACP::AssistMonsterScore: { BYTE pBuffer[32]; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &Type, sizeof(int), CPacketCompressStream::INTEGER_CHAR ); Stream.Write( &nResult, sizeof(int) ); Send( eActor::SC_CP, &Stream ); } break; } } void CDnPlayerActor::UpdateAttackedCPPoint( CDnDamageBase *pHitter , CDnWeapon::HitTypeEnum eHitType ) { bool bIsSameTeam = false; if( pHitter && pHitter->GetActorHandle() ) { if( GetTeam() == pHitter->GetActorHandle()->GetTeam() ) { bIsSameTeam = true; } } if( bIsSameTeam == false ) { switch( eHitType ) { case CDnWeapon::Normal: case CDnWeapon::CriticalRes: { UpdateAttackedHit(); } break; case CDnWeapon::Critical: { UpdateAttackedCriticalHit(); } break; case CDnWeapon::Stun: { UpdateAttackedStunHit(); } break; } } } DnWeaponHandle CDnPlayerActor::GetActiveWeapon( int nEquipIndex ) { if( m_bWeaponViewOrder[nEquipIndex] && m_hCashWeapon[nEquipIndex] ) return m_hCashWeapon[nEquipIndex]; return CDnActor::GetActiveWeapon( nEquipIndex ); } float CDnPlayerActor::PreCalcDamage( CDnDamageBase *pHitter, SHitParam &HitParam, const float fDefenseRate, float fStateEffectAttackM ) { float fResult = CDnActor::PreCalcDamage( pHitter, HitParam, fDefenseRate, fStateEffectAttackM ); return fResult; } bool CDnPlayerActor::IsDie() { bool bResult = CDnPlayerState::IsDie(); if( bResult ) return true; // PvP ¿¡¼­´Â return true ÇÒ Çʿ䰡 ¾ø½À´Ï´Ù. if( IsGMTrace() && GetGameRoom() && !GetGameRoom()->bIsPvPRoom() ) return true; return false; } bool CDnPlayerActor::SetActionQueue( const char *szActionName, int nLoopCount, float fBlendFrame , float fStartFrame , bool bCheck , bool bCheckStateEffect ) { if(m_bShootMode && !m_bTransformMode && m_bBattleMode) szActionName = GetChangeShootActionName(szActionName); #if defined(PRE_FIX_63219) //#63219 //ºí·°ÀÌ ¹ßµ¿µÈ ½ÃÁ¡¿¡ Á¿ì À̵¿Å°¸¦ ´©¸£¸é MAWalkMovement¿¡¼­ OnStopÀÌ È£Ã⠵ǰí //À̶§ CmdStopÀ¸·Î "Stand"µ¿ÀÛÀÌ ¼³Á¤µÇ¾î ¹ö¸°´Ù. //Ŭ¶óÀÌ¾ðÆ®¿¡¼­ À̵¿Áß block ¹ßµ¿ µÇ°í Ư¼ö°ø°ÝŰ ´­·¯ ÆÐ½Ãºê ½ºÅ³À» »ç¿ëÇϸé //¼­¹ö¿¡¼­´Â Standµ¿ÀÛÀ¸·Î º¯°æµÇ ¼­¹ö¿¡¼­´Â ½ºÅ³ÀÌ µ¿ÀÛ ÇÏÁö ¾Ê°Ô µÊ. //ÀÏ´Ü Blockµ¿ÀÛ¿¡ Stand·Î º¯°æÀº ¹«½Ã if ((strstr(m_szAction.c_str(), "Block") != NULL || strstr(m_szActionQueue.c_str(), "Block") != NULL)&& strstr(szActionName, "Stand") != NULL) { //#68376 ½ºÅĽº ¿Àºê ÆäÀ̽º ¿À·ù //Skill_StandOfFaith_EX_Block ÀÌ·± µ¿ÀÛ¿¡¼­ Stand·Î´Â ÀüȯÀÌ µÇ¾î¾ß ÇÑ´Ù... //´Ù¸¥ BlockÀÌ ÀÖÀ» ¼ö À־ "StandOfFaith"ÀÌ ÀÖÀ¸¸é Àüȯ Çϵµ·Ï ¼öÁ¤. bool isSkillAction = (strstr(m_szAction.c_str(), "StandOfFaith") != NULL || strstr(m_szActionQueue.c_str(), "StandOfFaith")); if (isSkillAction == false) return false; } #endif // PRE_FIX_63219 return CDnActor::SetActionQueue( szActionName , nLoopCount, fBlendFrame, fStartFrame, bCheck, bCheckStateEffect ); } void CDnPlayerActor::_UpdateMaxProjectileCount( int nActionIndex, bool bUpdateReservedCount/* = false*/ ) { if( NULL == m_pProjectileCountInfo ) return; // ÇöÀç ¾×¼Ç¿¡¼­ ÃÖ´ëÇÑ ¹ß»çÇÒ ¼ö ÀÖ´Â ¹ß»çü °¹¼ö. m_iNowMaxProjectileCount = 0; map::const_iterator iterProj = m_pProjectileCountInfo->mapMaxProjectileCountInAction.find( nActionIndex ); if( m_pProjectileCountInfo->mapMaxProjectileCountInAction.end() != iterProj ) m_iNowMaxProjectileCount = iterProj->second; // ¹ß»çü ½Ã±×³Î ¼ø¼­´ë·Î »ç¿ëÇÏ´Â ¹«±â Å×À̺í À妽º // º¸Åë ¹ß»çü ½Ã±×³Î°ú ¹«±â SendAction ÀÌ ¼¯¿©ÀÖÁö ¾Ê´Ù¸é µ¦ÀÌ ¸®¼ÂµÇÁö ¾Ê¾Æ¼­ ¾Æ·¡ÂÊ ¹«±â üũÇÏ´Â ·çÇÁ¿¡¼­ °è¼Ó ½×ÀÌ°Ô µÇ¹Ç·Î // ¿©±â¼­ Çѹø Ŭ¸®¾î ÇØÁØ´Ù. m_setWeaponIDUsingProjectileSignal.clear(); map >::const_iterator iterWeaponIDs = m_pProjectileCountInfo->mapUsingProjectileWeaponTableIDs.find( nActionIndex ); if( m_pProjectileCountInfo->mapUsingProjectileWeaponTableIDs.end() != iterWeaponIDs ) m_setWeaponIDUsingProjectileSignal = iterWeaponIDs->second; // ÇöÀç ¾×¼Ç¿¡¼­ ¹ß»çü°¡ ³ª°¡´Â ÇÁ·¹ÀÓµé ¸ðÀ½. // º¸Åë ¹ß»çü ½Ã±×³Î°ú ¹«±â SendAction ÀÌ ¼¯¿©ÀÖÁö ¾Ê´Ù¸é µ¦ÀÌ ¸®¼ÂµÇÁö ¾Ê¾Æ¼­ ¾Æ·¡ÂÊ ¹«±â üũÇÏ´Â ·çÇÁ¿¡¼­ °è¼Ó ½×ÀÌ°Ô µÇ¹Ç·Î // ¿©±â¼­ Çѹø Ŭ¸®¾î ÇØÁØ´Ù. m_dqProjectileSignalOffset.clear(); map >::const_iterator iterProjOffset = m_pProjectileCountInfo->mapProjectileSignalFrameOffset.find( nActionIndex ); if( m_pProjectileCountInfo->mapProjectileSignalFrameOffset.end() != iterProjOffset ) m_dqProjectileSignalOffset = iterProjOffset->second; sort( m_dqProjectileSignalOffset.begin(), m_dqProjectileSignalOffset.end() ); map >::const_iterator iterWeapon = m_pProjectileCountInfo->mapSendActionWeapon.find( nActionIndex ); if( m_pProjectileCountInfo->mapSendActionWeapon.end() != iterWeapon ) { const vector& vlWeaponInfo = iterWeapon->second; for( int i = 0; i < (int)vlWeaponInfo.size(); ++i ) { const CDnActionSpecificInfo::S_WEAPONACTION_INFO& Struct = vlWeaponInfo.at( i ); // ±×³É È£ÃâÇϸé TDnPlayer~~::GetActiveWeapon() ÇÔ¼ö°¡ È£ÃâµÇ¾î ¹ßÂ÷±â Áß ½î´Â ¾×¼ÇÀ¸·Î ¹Ù²ð ¶§ ¹ß ¹«±â°¡ ¾ò¾î¿ÍÁö¹Ç·Î ÇÙüũ¿¡ °É·Á¼­ CDnPlayerActor::GetActiveWeapon() À» È£Ãâ Çϵ¹°í º¯°æ. DnWeaponHandle hWeapon = CDnPlayerActor::GetActiveWeapon( Struct.iWeaponIndex ); if( hWeapon ) { if( false == Struct.strActionName.empty() ) { // Ç÷¹ÀÌ¾î ¾×ÅÍÀÎ °æ¿ìÇöÀç ¾×¼Ç¿¡¼­ ½ò ¼ö ÀÖ´Â ¹ß»çü °¹¼ö¿¡ ¹«±âÀÇ ¹ß»çü °¹¼ö¸¦ ´õÇØÁØ´Ù. if( hWeapon->IsExistAction( Struct.strActionName.c_str() ) ) { hWeapon->SetActionQueue( Struct.strActionName.c_str() ); if( m_ActorType <= Reserved6 ) { int nWeaponActionIndex = hWeapon->GetElementIndex( Struct.strActionName.c_str() ); int nAddCount = hWeapon->GetMaxProjectileCountInAction( nWeaponActionIndex ); if( false == bUpdateReservedCount ) m_iNowMaxProjectileCount += nAddCount; else m_iReservedProjectileCount += nAddCount; // ¹«±â¿¡¼­ ½î´Â ¹ß»çü¿¡¼­ »ç¿ëÇÏ´Â ¹«±â Å×À̺í Á¤º¸ Ãß°¡. hWeapon->AddUsingProjectileWeaponTableIDs( nWeaponActionIndex, m_setWeaponIDUsingProjectileSignal ); // ¹«±â¿¡¼­ ½î´Â ¹ß»çü ÇÁ·¹ÀÓ Á¤º¸ Ãß°¡. // ¸¶Áö¸· ÇÁ·¹ÀÓ °°Àº °÷¿¡ ¹«±â¿¡°Ô shoot ¾×¼ÇÀ» Ç϶ó´Â ½Ã±×³ÎÀ» ¹Ú´ø°¡Çϸé ÀÌ Ç٠üũ ·çƾ¿¡ °É¸± ¼ö ÀÖ½À´Ï´Ù. // ÇöÀç·Î½ã ±×·² °¡´É¼ºÀÌ ¾ø±â ¶§¹®¿¡ ÀÏ´Ü ÆÐ½º. hWeapon->AddProjectileSignalOffset( nWeaponActionIndex, Struct.iFrame, m_dqProjectileSignalOffset ); // °á°ú·Î ¾ò¾î¿Â °ÍÀº Á¤·Ä·Î °¡Áö°í ÀÖµµ·Ï ÇÕ´Ï´Ù. // ÇÁ·¹ÀÓ ¼ø¼­´ë·Î Á¤·ÄÇØ¼­ °®°í ÀÖ´Ù°¡ ºñ±³ÇÒ¶§ »ç¿ëÇÔ. sort( m_dqProjectileSignalOffset.begin(), m_dqProjectileSignalOffset.end() ); } } } } } } } bool CDnPlayerActor::UseAndCheckAvailProjectileCount( void ) { if( m_iNowMaxProjectileCount <= 0 ) { // ¹ß»çü¿¡¼­ ¹ß»çü ½î´Â °æ¿ìó·³ ¿¹¾àµÈ ¹ß»çü °¹¼öµµ ¾ø´Â °æ¿ì ÇÙÀ¸·Î ÆÇ´Ü. if( m_iReservedProjectileCount <= 0 ) { // ÇÙÀ¸·Î ¹ß»çü¸¦ ¸¶±¸ ³¯¸®°í ÀÖÀ½. OutputDebug( "CS_PROJECTILE: ÇöÀç ¾×¼ÇÀÇ ÃÖ´ë °¹¼ö¸¦ ³Ñ´Â ¹ß»çü ¿äû. ÇÙÀ¸·Î ÆÇ´ÜµÊ.\n" ); return false; } --m_iReservedProjectileCount; } if( 0 < m_iNowMaxProjectileCount ) --m_iNowMaxProjectileCount; return true; } bool CDnPlayerActor::IsExclusiveSkill( int iSkillID, int iExclusiveID ) { #ifndef PRE_FIX_SKILLLIST // ¹è¿î ½ºÅ³ Áß¿¡ °°Àº ½ºÅ³ ¸ø ¹è¿ì°Ô ÇÏ´Â id °¡ ÀÖÀ¸¸é true. int iNumSkill = (int)m_vlhSkillList.size(); for( int iSkill = 0; iSkill < iNumSkill; ++iSkill ) { DnSkillHandle hSkill = m_vlhSkillList.at( iSkill ); // ÀÚ½ÅÀÇ ½ºÅ³Àº Á¦¿ÜÇϰí. if( hSkill->GetClassID() == iSkillID ) continue; if( 0 == hSkill->GetExclusiveID() ) continue; if( iExclusiveID == hSkill->GetExclusiveID() ) { return true; } } #else // ¹è¿î ½ºÅ³ Áß¿¡ °°Àº ½ºÅ³ ¸ø ¹è¿ì°Ô ÇÏ´Â id °¡ ÀÖÀ¸¸é true. DWORD dwNumSkill = GetSkillCount(); for( DWORD i = 0; i < dwNumSkill; ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); // ÀÚ½ÅÀÇ ½ºÅ³Àº Á¦¿ÜÇϰí. if( hSkill->GetClassID() == iSkillID ) continue; if( 0 == hSkill->GetExclusiveID() ) continue; if( iExclusiveID == hSkill->GetExclusiveID() ) { return true; } } #endif // #ifndef PRE_FIX_SKILLLIST return false; } int CDnPlayerActor::GetAvailSkillPointByJob( int iSkillID ) { // ÇöÀç Á÷¾÷ Â÷¼ö int iJobDegree = g_pDataManager->GetJobNumber( GetJobClassID() ); int iWholeSP = GetLevelUpSkillPoint( 1, GetLevel() ); int iWholeAvailSPByJob = int(iWholeSP * m_pSession->GetAvailSkillPointRatioByJob( iSkillID )); // ½ºÅ³¿¡ ÇÊ¿äÇÑ Á÷¾÷¿¡ ÇØ´çµÇ´Â »ç¿ëÇÑ SP ¸¦ ¸ðÀº´Ù. int iUsedSPByJob = 0; const TSkillData* pSkillDataForNeedJobID = g_pDataManager->GetSkillData( iSkillID ); #ifndef PRE_FIX_SKILLLIST for( int i = 0; i < (int)m_vlhSkillList.size(); ++i ) { DnSkillHandle hSkill = m_vlhSkillList.at( i ); #else DWORD dwNumSkill = GetSkillCount(); for( DWORD i = 0; i < dwNumSkill; ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); #endif // #ifndef PRE_FIX_SKILLLIST if( hSkill->GetNeedJobClassID() == pSkillDataForNeedJobID->nNeedJobID ) { int iLevel = hSkill->GetLevel(); for( int k = 0; k < iLevel; ++k ) { const TSkillData* pSkillData = g_pDataManager->GetSkillData( hSkill->GetClassID() ); iUsedSPByJob += pSkillData->vLevelDataList.at( k ).nNeedSkillPoint; } } } // Àüü »ç¿ë°¡´É SP º¸´Ù Á÷¾÷ SP °¡ ³²Àº °ÍÀÌ ¸¹À¸¸é Àüü »ç¿ë°¡´É SP °¡ ÁøÂ¥ÀÌ¹Ç·Î ÇØ´ç Æ÷ÀÎÆ®·Î ¸®ÅÏ. int iAvailPoint = iWholeAvailSPByJob - iUsedSPByJob; if( m_pSession->GetSkillPoint() < iAvailPoint ) iAvailPoint = m_pSession->GetSkillPoint(); return iAvailPoint; } int CDnPlayerActor::GetUsedSkillPointInThisJob( const int nJobID ) { int iUsedSPByJob = 0; #ifndef PRE_FIX_SKILLLIST for( int i = 0; i < (int)m_vlhSkillList.size(); ++i ) { DnSkillHandle hSkill = m_vlhSkillList.at( i ); #else DWORD dwNumSkill = GetSkillCount(); for( DWORD i = 0; i < dwNumSkill; ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); #endif // #ifndef PRE_FIX_SKILLLIST if( hSkill->GetNeedJobClassID() == nJobID ) { int iLevel = hSkill->GetLevel(); for( int k = 0; k < iLevel; ++k ) { const TSkillData* pSkillData = g_pDataManager->GetSkillData( hSkill->GetClassID() ); iUsedSPByJob += pSkillData->vLevelDataList.at( k ).nNeedSkillPoint; } } } return iUsedSPByJob; } void CDnPlayerActor::OnChangePlaySpeed( DWORD dwFrame, float fSpeed ) { // ¸Â°Å³ª ÇØ¼­ ½´ÆÛ¾Æ¸Ó ¶§¹®¿¡ Ç÷¹ÀÌ ½Ã°£ÀÌ ´Ã¾î³­ °æ¿ì ½Ã±×³Î ÅÒ ÇÁ·¹ÀÓ °ªÀ» // °°ÀÌ ¾÷µ¥ÀÌÆ® ÇØÁà¾ß ÇÙ¿¡ ¾È°É¸°´Ù. // ÇÁ·¹ÀÓ ½ºÇÇµå º¯°æµÈ °¡¿îµ¥ ¾×¼ÇÀ» ½ÃÀÛÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î °ªÀ» ¹Þ¾Æ³õ°í üũÇÒ ¶§ Àû¿ëÇÏ´Â °ÍÀ¸·Î º¯°æ. //for( int i = 0; i < (int)m_dqProjectileSignalOffset.size(); ++i ) //{ // int& iSignalOffsetFrame = m_dqProjectileSignalOffset.at( i ); // iSignalOffsetFrame = (int)((float)iSignalOffsetFrame * fSpeed ); //} // ½´ÆÛ¾Æ¸Ó·Î ¾Æ¿¹ ÇÁ·¹ÀÓÀÌ ¼ø°£ÀûÀ¸·Î ÀÏÁ¤ ½Ã°£ Á¤ÁöµÇ´Â °æ¿ì if( dwFrame <= 200 && fSpeed < 0.05f) m_bCheckProjectileSignalTerm = false; m_fFrameSpeed = fSpeed; } void CDnPlayerActor::ProcessCompanion( LOCAL_TIME LocalTime, float fDelta ) { CheckPetSatietyPercent(); } void CDnPlayerActor::CheckPetSatietyPercent() { if( !IsCanPetMode() ) return; const TVehicle* pEquipPet = GetUserSession()->GetItem()->GetPetEquip(); if( pEquipPet && (pEquipPet->nType & Pet::Type::ePETTYPE_SATIETY) && pEquipPet->Vehicle[Pet::Slot::Body].nItemID > 0 ) { if( GetUserSession()->GetItem()->GetPetSatietyPercent() < 50.f ) // ¿©±â¿¡ Limit üũ ÇØ¾ß ÇÕ´Ï´Ù. { DnSkillHandle hFirstSkill = FindSkill(pEquipPet->nSkillID1); if(hFirstSkill && hFirstSkill->GetSkillType() == CDnSkill::Passive ) { CmdForceRemoveSkill(pEquipPet->nSkillID1); m_bDeletedPetSkill[Pet::Skill::Primary] = true; } DnSkillHandle hSecondSkill = FindSkill(pEquipPet->nSkillID2); if(hSecondSkill && hSecondSkill->GetSkillType() == CDnSkill::Passive ) { CmdForceRemoveSkill(pEquipPet->nSkillID2); m_bDeletedPetSkill[Pet::Skill::Secondary] = true; } } else { if( m_bDeletedPetSkill[Pet::Skill::Primary] == true ) { if( !IsExistSkill( pEquipPet->nSkillID1 ) ) CmdForceAddSkill( pEquipPet->nSkillID1 ); m_bDeletedPetSkill[Pet::Skill::Primary] = false; } if( m_bDeletedPetSkill[Pet::Skill::Secondary] == true ) { if( !IsExistSkill( pEquipPet->nSkillID2 ) ) CmdForceAddSkill( pEquipPet->nSkillID2 ); m_bDeletedPetSkill[Pet::Skill::Secondary] = false; } } } } CDnVehicleActor *CDnPlayerActor::GetMyVehicleActor() { if(m_hVehicleActor) { return static_cast(m_hVehicleActor.GetPointer()); } return NULL; } bool CDnPlayerActor::IsCanVehicleMode() { if( IsDie() || IsGhost() || m_nTeam == PvPCommon::Team::Observer ) return false; if( IsSpectatorMode() ) return false; int nCurrentMapID = 0; CDnGameTask *pGameTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); if( pGameTask ) // °ÔÀÓÅ×½ºÅ©À϶§ÀÇ °ËÃâ nCurrentMapID = pGameTask->GetMapTableID(); else nCurrentMapID = m_pSession->GetMapIndex(); bool bIsCanVehicleMode = g_pDataManager->IsVehicleMode(nCurrentMapID); #if defined( PRE_ADD_FORCE_RIDE_ENABLE_TRIGGER ) bIsCanVehicleMode = bIsCanVehicleMode && m_bForceEnableRideByTrigger; #endif // #if defined( PRE_ADD_FORCE_RIDE_ENABLE_TRIGGER ) return bIsCanVehicleMode; } bool CDnPlayerActor::IsCanPetMode() { int nCurrentMapID = 0; CDnGameTask *pGameTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" ); if( pGameTask ) // °ÔÀÓÅ×½ºÅ©À϶§ÀÇ °ËÃâ nCurrentMapID = pGameTask->GetMapTableID(); else nCurrentMapID = m_pSession->GetMapIndex(); return g_pDataManager->IsPetMode( nCurrentMapID ); } void CDnPlayerActor::RideVehicle(TVehicle *pInfo) { if( !IsPlayerActor() || IsVehicleMode() || !pInfo ) return; if( !IsCanVehicleMode()) return; if(IsBattleMode()) SetBattleMode(false); int nVehicleActorTableID = g_pDataManager->GetVehicleActorID(pInfo->Vehicle[Vehicle::Slot::Body].nItemID); DnActorHandle hVehicle; hVehicle = CreateActor( GetRoom(), nVehicleActorTableID ); if( !hVehicle || !hVehicle->GetObjectHandle()) return; CDnVehicleActor* pVehicle = (CDnVehicleActor *)hVehicle.GetPointer(); if(!pVehicle) return; pVehicle->SetMyPlayerActor(GetActorHandle()); pVehicle->Show( false ); float fLandHeight = INSTANCE(CDnWorld).GetHeight( GetMatEx()->m_vPosition ); pVehicle->SetPosition(GetMatEx()->m_vPosition); pVehicle->SetPrevPosition(GetMatEx()->m_vPosition); pVehicle->SetAddHeight( GetMatEx()->m_vPosition.y - fLandHeight ); pVehicle->GetMatEx()->CopyRotationFromThis(GetMatEx()); pVehicle->SetItemID(pInfo->Vehicle[Vehicle::Slot::Body].nItemID); // ÀÚ½ÅÀÇ ¾ÆÀÌÅÛ ¾ÆÀ̵𸦠°¡Áö°í ÀÖ½À´Ï´Ù. #ifdef PRE_ADD_VEHICLE_ACTION_STRING DNTableFileFormat* pVehicleTable = GetDNTable( CDnTableDB::TVEHICLE ); std::string strVehicleAction = pVehicleTable->GetFieldFromLablePtr( pInfo->Vehicle[Vehicle::Slot::Body].nItemID , "_RiderString" )->GetString(); if(!strVehicleAction.empty() || strstr(strVehicleAction.c_str() , "Vehicle_") != NULL ) pVehicle->SetVehicleActionString(strVehicleAction.c_str()); #endif // ºÎÀ§º° ÀåÂø // ÆÄÃ÷ Á¤º¸¸¦ ÇÔÀ¯ÇÏ°í µé¾î¿À´Â °æ¿ì´Â ÀåÂøÀ» ½ÃÄÑÁÝ´Ï´Ù. for (int i= Vehicle::Slot::Saddle; iVehicle[i].nItemID != 0 && pInfo->Vehicle[i].nSerial != 0) { pVehicle->EquipItem(pInfo->Vehicle[i]); } } //////////////// if(pInfo->dwPartsColor1 != 0 && pInfo->dwPartsColor1 != -1) // ¼³Á¤µÈ »öÀÌ Àִ°æ¿ì¿¡´Â »ö ¼³Á¤À» ÇØÁÝ´Ï´Ù. { pVehicle->ChangeHairColor(pInfo->dwPartsColor1); // ±âº» Å×ÀÌºí¿¡ Á¤ÀÇµÈ »öÁöÁ¤. } SetMyVehicleActor(pVehicle->GetActorHandle()); pVehicle->InitializeRoom((CDNGameRoom*)GetRoom()); pVehicle->Initialize(); pVehicle->SetUniqueID( m_pSession->GetVehicleObjectID() ); pVehicle->SetVehicleClassID(pInfo->Vehicle[Vehicle::Slot::Body].nItemID); pVehicle->RefreshState(); pVehicle->Show(true); pVehicle->SetAttachToPlayer(true); pVehicle->SetProcess(true); SetVehicleMode(true); pVehicle->SetActionQueue( "Stand" ); pVehicle->SetTeam(GetTeam()); } void CDnPlayerActor::UnRideVehicle(bool bForce) { if(!IsVehicleMode()) return; if(GetMyVehicleActor() && !GetMyVehicleActor()->IsDestroy()) { float fLandHeight = INSTANCE(CDnWorld).GetHeight( GetMyVehicleActor()->GetMatEx()->m_vPosition ); SetPosition(GetMyVehicleActor()->GetMatEx()->m_vPosition); SetPrevPosition(GetMyVehicleActor()->GetMatEx()->m_vPosition); SetAddHeight( GetMyVehicleActor()->GetMatEx()->m_vPosition.y - fLandHeight ); GetMyVehicleActor()->SetAttachToPlayer(false); GetMyVehicleActor()->Show(false); GetMyVehicleActor()->SetUniqueID(GetMyVehicleActor()->GetUniqueID() +1 ); // SetDestroy°¡ ¼³Á¤µÇ°í ÇÁ·Î¼¼½º ÀÌÈÄ¿¡ ¾×ÅͰ¡ »èÁ¦µÇ´Â »çÀÌ¿¡ »õ·Î¿î ¸»À» Ÿ°ÔµÇ¸é À¯´ÏÅ© ¾ÆÀ̵𰡠°ãÄ¡´Â ¹®Á¦°¡ ¹ß»ýµÈ´Ù // < ½Å±Ô À¯´ÏÅ©¾ÆÀ̵𸦠ÀÌÈÄ ÇÁ·Î¼¼½º¿¡¼­ »èÁ¦Çϴ°æ¿ì°¡ »ý±è > ±×·¯¹Ç·Î µð½ºÆ®·ÎÀÌ ÇϱâÀü¿¡ À¯´ÏÅ©¾ÆÀ̵𸦠º¯°æ½ÃÄÑÁÖÀÚ. GetMyVehicleActor()->SetDestroy(); } SetVehicleMode(false); Show(true); SetActionQueue("Stand"); return; } void CDnPlayerActor::ForceUnRideVehicle() { if(!IsVehicleMode()) return; CDNGameRoom* pRoom = GetGameRoom(); if (!pRoom) return; api_trigger_UnRideVehicle( pRoom, GetSessionID() ); } void CDnPlayerActor::RemoveVehicleStateEffectImmediately(int nBlowIndex ) { if(IsVehicleMode() && GetMyVehicleActor()) { GetMyVehicleActor()->CmdRemoveStateEffectImmediately( (STATE_BLOW::emBLOW_INDEX)nBlowIndex ); GetMyVehicleActor()->SendRemoveStateEffect( (STATE_BLOW::emBLOW_INDEX)nBlowIndex ); } } void CDnPlayerActor::SetForceEnableRide( const bool bForceEnableRide ) { if( false == bForceEnableRide ) ForceUnRideVehicle(); m_bForceEnableRideByTrigger = bForceEnableRide; m_pSession->SendTriggerForceEnableRide( GetSessionID(), bForceEnableRide ); } void CDnPlayerActor::OnCannonMonsterDie( void ) { // ´ëÆ÷ ¸ðµå ÇØÁ¦ EndCannonMode(); SetActionQueue( "Stand" ); } void CDnPlayerActor::EndCannonMode() { m_bPlayerCannonMode = false; m_hCannonMonsterActor.Identity(); DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TACTOR ); if( pSox && pSox->IsExistItem(GetClassID())) { float fWeight = pSox->GetFieldFromLablePtr( GetClassID(), "_Weight" )->GetFloat(); int fPressLevel = pSox->GetFieldFromLablePtr( GetClassID(), "_PressLevel" )->GetInteger(); SetWeight(fWeight); SetPressLevel(fPressLevel); } } void CDnPlayerActor::ProcessNonLocalShootModeAction() { if(!IsLocalActor()) return; if( strcmp( GetCurrentAction(), "MOD_Stand" ) == NULL ) { if( strstr( m_szCustomAction.c_str(), "MOD_Shoot" ) ) { float fFrame = ( ( CDnActionBase::m_LocalTime - m_CustomActionTime ) / 1000.f ) * CDnActionBase::m_fFPS; CmdStop( "MOD_Shoot_Stand", 0, 8.f, fFrame ); ResetCustomAction(); } } } const char *CDnPlayerActor::GetChangeShootActionName(const char *szActionName) // ÀÛ¾÷Áß. { if(strcmp(szActionName,"Stand") == NULL) { szActionName = "MOD_Stand"; } if(strcmp(szActionName,"Move_Front") == NULL) { szActionName = "MOD_Move_Front"; } if(strcmp(szActionName,"Move_Back") == NULL) { szActionName = "MOD_Move_Back"; } if(strcmp(szActionName,"Move_Left") == NULL) { szActionName = "MOD_Move_Left"; } if(strcmp(szActionName,"Move_Right") == NULL) { szActionName = "MOD_Move_Right"; } if(strcmp(szActionName,"Jump") == NULL) { szActionName = "MOD_Jump"; } if(strstr(szActionName,"Attack1")) { szActionName = "MOD_Shoot_Stand"; } return szActionName; } bool CDnPlayerActor::IsTransformSkill( int nSkillID ) { for( DWORD i=0; iIsApplied(STATE_BLOW::BLOW_232)) { DNVector(DnBlowHandle) vlBlows; GatherAppliedStateBlowByBlowIndex(STATE_BLOW::BLOW_232, vlBlows); for (DWORD i = 0; i < vlBlows.size(); i++) { if( vlBlows[i] ) { CDnTransformBlow *pTransformBlow = static_cast( vlBlows[i].GetPointer() ); if( pTransformBlow && pTransformBlow->GetParentSkillInfo()->iSkillID == m_hProcessSkill->GetClassID() ) { bCancelSkill = false; break; } } } } if( bCancelSkill == true ) { CancelUsingSkill(); SetAction("Stand",0.f,0.f); } } else { SetAction("Stand",0.f,0.f); } if(IsTransformMode() == true) { int nActorIndex = pMonsterSox->IsExistItem(m_nMonsterMutationTableID) ? pMonsterSox->GetFieldFromLablePtr( m_nMonsterMutationTableID , "_ActorTableID" )->GetInteger() : 0; int nSkillTableIndex = pMonsterSox->IsExistItem(m_nMonsterMutationTableID) ? pMonsterSox->GetFieldFromLablePtr( m_nMonsterMutationTableID , "_SkillTable" )->GetInteger() : 0; if(GetStateBlow()->IsApplied(STATE_BLOW::BLOW_176)) { CmdRemoveStateEffect(STATE_BLOW::BLOW_176); GetStateBlow()->Process( 0, 0.f ); } DNTableFileFormat* pActorSox = GetDNTable( CDnTableDB::TACTOR ); if(!pActorSox || !pActorSox->IsExistItem(nActorIndex)) return; if(nActorIndex > 0) { SwapSingleSkin( nActorIndex ); ResetCustomAction(); SetAction( "Stand", 0.f, 0.f ); } else return; if( pMonsterSkillSox && pMonsterSkillSox->IsExistItem(nSkillTableIndex)) { if(!m_vecTransformSkillList.empty()) // ÀÌ¹Ì Àû¿ëµÈ ½ºÅ³ÀÌÀÖÀ»¶§´Â Áö¿öÁØ´Ù. < º¯½ÅÇß´Ù°¡ ¶Çº¯½ÅÇϴ°æ¿ì > { for (int i=0; i<(int)m_vecTransformSkillList.size(); i++) { if(m_vecTransformSkillList[i] != -1 ) RemoveSkill(m_vecTransformSkillList[i]); } m_vecTransformSkillList.clear(); } for (int i=0; iGetFieldFromLablePtr( nSkillTableIndex, szStr )->GetInteger(); sprintf_s( szStr, "_SkillLevel%d", i+1 ); nSkillLevel = pMonsterSkillSox->GetFieldFromLablePtr( nSkillTableIndex, szStr )->GetInteger(); if(nSkillIndex != -1 && nSkillLevel != -1) { m_vecTransformSkillList.push_back(nSkillIndex); AddSkill(nSkillIndex,nSkillLevel); } else break; } std::string strSkillVec = ""; for(DWORD i=0; i 0) { CmdRemoveStateEffectFromID(m_nAllowedSkill); m_nAllowedSkill = 0; } m_vecTransformSkillList.clear(); } SetBattleMode(true); RefreshState(); } void CDnPlayerActor::ToggleTransformMode( bool bTrue,int nMonsterMutatorTableID , bool bForce, const char* strEndAction ) { if( m_bTransformMode == bTrue && !bForce ) return; m_bTransformMode = bTrue; m_nMonsterMutationTableID = nMonsterMutatorTableID; m_bRefreshTransformMode = true; m_strTransformEndAction = strEndAction; } void CDnPlayerActor::CmdShootMode(bool bTrue) { m_bShootMode = bTrue; if(m_bShootMode) CmdStop("MOD_Shoot_Stand"); else CmdStop("Stand"); BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); DWORD dwUniqueID = GetUniqueID(); Stream.Write( &dwUniqueID, sizeof(dwUniqueID) ); Stream.Write( &m_bShootMode, sizeof(bool) ); Send( eActor::SC_CMDSHOOTMODE, &Stream ); } void CDnPlayerActor::CmdWarp( EtVector3 &vPos, EtVector2 &vLook, CDNUserSession* pGameSession, bool bCheckPlayerFollowSummonedMonster/*=false*/ ) { if(IsVehicleMode() && GetMyVehicleActor() ) GetMyVehicleActor()->CmdWarp(vPos, vLook, pGameSession); CDnActor::CmdWarp( vPos, vLook, pGameSession, bCheckPlayerFollowSummonedMonster ); if( m_pPlayerSpeedHackChecker ) m_pPlayerSpeedHackChecker->ResetInvalid(); // #32426 ¼Òȯü ÄÁÆ®·Ñ ±â´É - ½ºÅ×ÀÌÁö À̵¿ ȤÀº Á¸ À̵¿(CmdWarp)¸¦ ÇÒ ¶§ µû¶ó°¡¾ß µÇ´Â // ÀÌ Ç÷¹À̾ ¼ÒȯÇÑ ¸ó½ºÅÍ °´Ã¼µé Ã¼Å©ÇØ¼­ ó¸®. if( bCheckPlayerFollowSummonedMonster ) { list::iterator iter = m_listSummonedMonstersFollowStageInfos.begin(); for( iter; iter != m_listSummonedMonstersFollowStageInfos.end(); ) { DnMonsterActorHandle hMonsterActor = iter->hMonster; if( hMonsterActor && false == hMonsterActor->IsDie() ) { hMonsterActor->CmdWarp( vPos, vLook, pGameSession, false ); hMonsterActor->ResetAggro(); hMonsterActor->CmdAction( "Stand" ); ++iter; } else { iter = m_listSummonedMonstersFollowStageInfos.erase( iter ); } } } } void CDnPlayerActor::RequestCooltimeParrySuccess( int iSkillID ) { BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &iSkillID, sizeof(int) ); Send( eActor::CS_COOLTIMEPARRY_SUCCESS, &Stream ); } bool CDnPlayerActor::IsInvalidPlayerChecker() { if( !m_pSession ) return false; if( m_pSession->GetHackPlayRestraintValue() <= 0 ) return false; if( m_pSession->GetHackAbuseDBValue() + m_nInvalidPlayerCheckCounter >= m_pSession->GetHackPlayRestraintValue() ) return true; return false; } void CDnPlayerActor::SwapSingleSkin( int nChangeActorTableID ) { if( m_nSwapSingleSkinActorID == nChangeActorTableID ) return; m_nSwapSingleSkinActorID = nChangeActorTableID; // FreeAction(); #ifdef PRE_FIX_MEMOPT_EXT if (g_pDataManager == NULL) { _ASSERT(0); return; } #endif DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TACTOR ); if( m_nSwapSingleSkinActorID == -1 ) { #ifdef PRE_FIX_MEMOPT_EXT std::string szSkinName, szAniName, szActName; g_pDataManager->GetFileNameFromFileEXT(szSkinName, pSox, m_nClassID, "_SkinName"); g_pDataManager->GetFileNameFromFileEXT(szAniName, pSox, m_nClassID, "_AniName"); g_pDataManager->GetFileNameFromFileEXT(szActName, pSox, m_nClassID, "_ActName"); #else std::string szSkinName = pSox->GetFieldFromLablePtr( m_nClassID, "_SkinName" )->GetString(); std::string szAniName = pSox->GetFieldFromLablePtr( m_nClassID, "_AniName" )->GetString(); std::string szActName = pSox->GetFieldFromLablePtr( m_nClassID, "_ActName" )->GetString(); #endif SAFE_RELEASE_SPTR( GetObjectHandle() ); FreeAction(); LoadSkin( CEtResourceMng::GetInstance().GetFullName( szSkinName ).c_str(), CEtResourceMng::GetInstance().GetFullName( szAniName ).c_str() ); LoadAction( CEtResourceMng::GetInstance().GetFullName( szActName ).c_str() ); SetAction( "Stand", 0.f, 0.f ); for( int i=0; iGetFileNameFromFileEXT(szSkinName, pSox, m_nSwapSingleSkinActorID, "_SkinName"); g_pDataManager->GetFileNameFromFileEXT(szAniName, pSox, m_nSwapSingleSkinActorID, "_AniName"); g_pDataManager->GetFileNameFromFileEXT(szActName, pSox, m_nSwapSingleSkinActorID, "_ActName"); #else std::string szSkinName = pSox->GetFieldFromLablePtr( m_nSwapSingleSkinActorID, "_SkinName" )->GetString(); std::string szAniName = pSox->GetFieldFromLablePtr( m_nSwapSingleSkinActorID, "_AniName" )->GetString(); std::string szActName = pSox->GetFieldFromLablePtr( m_nSwapSingleSkinActorID, "_ActName" )->GetString(); #endif if( !m_hSwapOriginalHandle && m_hObject ) { m_hSwapOriginalHandle = EternityEngine::CreateAniObject( GetRoom(), CEtResourceMng::GetInstance().GetFullName( m_hObject->GetSkinFileName() ).c_str(), CEtResourceMng::GetInstance().GetFullName( m_hObject->GetAniHandle()->GetFileName() ).c_str() ); } SAFE_RELEASE_SPTR( GetObjectHandle() ); if( !m_pSwapOriginalAction ) { m_pSwapOriginalAction = new CDnActionBase; m_pSwapOriginalAction->LoadAction( CEtResourceMng::GetInstance().GetFullName( CDnActionBase::m_szFileName ).c_str() ); } SAFE_RELEASE_SPTR( GetObjectHandle() ); FreeAction(); LoadSkin( CEtResourceMng::GetInstance().GetFullName( szSkinName ).c_str(), CEtResourceMng::GetInstance().GetFullName( szAniName ).c_str() ); LoadAction( CEtResourceMng::GetInstance().GetFullName( szActName ).c_str() ); SetAction( "Stand", 0.f, 0.f ); } if( m_hObject ) { m_hObject->SetCollisionGroup( COLLISION_GROUP_DYNAMIC( 1 ) ); m_hObject->SetTargetCollisionGroup( COLLISION_GROUP_STATIC( 1 ) | COLLISION_GROUP_DYNAMIC( 2 ) | COLLISION_GROUP_DYNAMIC( 3 ) ); } if(m_pBubbleSystem) m_pBubbleSystem->Clear(); } void CDnPlayerActor::InitializeEnchantPassiveSkills( void ) { // °­È­ ÆÐ½Ãºê ŸÀÔÀÇ ½ºÅ³À» ã¾Æ¼­ º£À̽º ½ºÅ³¿¡ ¼öÄ¡¸¦ Àû¿ëÇϵµ·Ï ÇÑ´Ù. #ifndef PRE_FIX_SKILLLIST for( DWORD i = 0; i < m_vlhSkillList.size(); i++ ) { DnSkillHandle hSkill = m_vlhSkillList[ i ]; #else for( DWORD i = 0; i < GetSkillCount(); ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); #endif // #ifndef PRE_FIX_SKILLLIST if( CDnSkill::EnchantPassive == hSkill->GetSkillType() && 0 < hSkill->GetBaseSkillID() ) { DnSkillHandle hEnchantPassiveSkill = hSkill; int iBaseSkillID = hEnchantPassiveSkill->GetBaseSkillID(); DnSkillHandle hBaseSkill = FindSkill( iBaseSkillID ); // Àӽ÷Π¹æ¾îÄÚµå ³ÖÀ½. ½ºÅ³¸®¼Â ij½¬ÅÛÀÌ Á¦´ë·Î ¿Ã¶ó°¡¸é ¾ø¾Ö¾ß ÇÔ. if( hBaseSkill ) hBaseSkill->ApplyEnchantSkill( hEnchantPassiveSkill ); } } } void CDnPlayerActor::OnReplacementSkill( DnSkillHandle hLegacySkill, DnSkillHandle hNewSkill ) { MASkillUser::OnReplacementSkill( hLegacySkill, hNewSkill ); // ·ÎÄà Ç÷¹À̾îÀÇ ÆÐ½Ãºê °­È­ ½ºÅ³ÀÌ ·¹º§¾÷ µÇ¾î ÀÌÀü ·¹º§ÀÇ ½ºÅ³ °´Ã¼ÀÇ ±³Ã¼ ·çƾÀ» Ÿ°í ÀÌÂÊÀ¸·Î ¿À´Â °æ¿ì. // Àû¿ëµÇ°í ÀÖ´ø º£À̽º ½ºÅ³ÀÇ °­È­ »óŸ¦ ¸®¼ÂÀ¸·Î µ¹¸®°í ·¹º§¾÷µÈ »õ·Î¿î °­È­ ½ºÅ³ÀÇ °ÍÀ» Àû¿ë½ÃŲ´Ù. if( CDnSkill::EnchantPassive == hLegacySkill->GetSkillType() && 0 < hLegacySkill->GetBaseSkillID() ) { DnSkillHandle hBaseSkill = FindSkill( hLegacySkill->GetBaseSkillID() ); if( hBaseSkill ) { _ASSERT( hLegacySkill->GetBaseSkillID() == hNewSkill->GetBaseSkillID() ); hBaseSkill->ReleaseEnchantSkill(); hBaseSkill->ApplyEnchantSkill( hNewSkill ); } } else { // ·ÎÄà Ç÷¹À̾îÀÇ ÆÐ½Ãºê °­È­ ½ºÅ³ÀÇ ´ë»óÀÌ µÇ´Â º£À̽º ½ºÅ³ÀÌ ·¹º§¾÷ µÇ¾î ±³Ã¼ ·çƾÀ» Ÿ°í ÀÌÂÊÀ¸·Î ¿À´Â °æ¿ì. // ÀÌ °æ¿ì¿£ º£À̽º ½ºÅ³ °´Ã¼´Â SkillTask ¿¡¼­ ÀÌ ·çƾÀÌ ³¡³­ ÈÄ ±×³É »èÁ¦µÉ °ÍÀ̹ǷΠ³öµÎ°í // »õ·Î ·¹º§¾÷ µÈ º£À̽º ½ºÅ³¿¡ °­È­ ½ºÅ³À» Àû¿ë½ÃÄÑ ÁÖ¸é µÈ´Ù. CheckAndApplyEnchantPassiveSkill( hNewSkill ); } } void CDnPlayerActor::CheckAndApplyEnchantPassiveSkill( DnSkillHandle hBaseSkill ) { if( hBaseSkill ) { DnSkillHandle hEnchantPassiveSkill; #ifndef PRE_FIX_SKILLLIST for( DWORD i = 0; i < m_vlhSkillList.size(); i++ ) { DnSkillHandle hSkill = m_vlhSkillList[ i ]; #else for( DWORD i = 0; i < GetSkillCount(); ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); #endif // #ifndef PRE_FIX_SKILLLIST if( hSkill->GetBaseSkillID() == hBaseSkill->GetClassID() ) { hEnchantPassiveSkill = hSkill; break; } } if( hEnchantPassiveSkill ) hBaseSkill->ApplyEnchantSkill( hEnchantPassiveSkill ); } } // ÇöÀç ¿¤¸®¸àÅ»·ÎµåÀÇ ¾ÆÀ̽à ÇÁ·¢¼Ç¿¡¼­¸¸ ¿¹¿ÜÀûÀ¸·Î 2°¡ÁöÀÇ »óÅÂÈ¿°ú ÇÊÅ͸µÀ» °É°í Àִµ¥ // µÑ Áß¿¡ Çϳª¸¸ hit µÇ±æ ¿øÇϱ⠶§¹®¿¡ ¸ÕÀú üũµÈ °ÍÀº ´ÙÀ½ ÇÊÅ͸µ¿¡ °É¸®Áö ¾Êµµ·Ï ÇÑ´Ù. #28747 void CDnPlayerActor::OnHitSignalStateEffectFilterException( DWORD dwTargetActorUniqueID, int iBlowIndex ) { if( STATE_BLOW::BLOW_041 == (STATE_BLOW::emBLOW_INDEX)iBlowIndex || STATE_BLOW::BLOW_144 == (STATE_BLOW::emBLOW_INDEX)iBlowIndex ) { m_mapIcyFractionHitted[ dwTargetActorUniqueID ] = true; } } bool CDnPlayerActor::CheckHitSignalStateEffectFilterException( DWORD dwTargetActorUniqueID, int iBlowIndex ) { bool bResult = true; if( STATE_BLOW::BLOW_041 == (STATE_BLOW::emBLOW_INDEX)iBlowIndex || STATE_BLOW::BLOW_144 == (STATE_BLOW::emBLOW_INDEX)iBlowIndex ) { if( m_mapIcyFractionHitted.end() != m_mapIcyFractionHitted.find( dwTargetActorUniqueID ) ) { bResult = false; } } return bResult; } bool CDnPlayerActor::IsMyRelicMonster( DnActorHandle hActor ) { bool bResult = false; if( hActor && hActor->IsMonsterActor() ) { CDnMonsterActor* pMonsterActor = static_cast(hActor.GetPointer()); if( pMonsterActor->IsClericRelicMonster() ) { if( GetMySmartPtr() == pMonsterActor->GetSummonerPlayerActor() ) bResult = true; } } return bResult; } INT64 CDnPlayerActor::GetCharacterDBID() { return m_pSession ? m_pSession->GetCharacterDBID() : 0; } // #26902 // Àӽ÷ΠŬ¶óÀÌ¾ðÆ®¿¡°Ô ÀÌ Á÷¾÷À¸·Î ÀüÁ÷ÇÒ °ÍÀ» ¸í·É. // ÀÌ ½ÃÁ¡ºÎÅÍ´Â ½ºÅ³ ·¹º§¾÷ ¹× °¢Á¾ Á¶ÀÛÀÌ ºÒ°¡ÇÏ´Ù. // °ÔÀÓ ¼­¹ö ÂÊ¿¡¼­µµ ½ºÅ³ ·¹º§¾÷ µîÀÇ ÆÐŶÀÌ ¿À¸é ¹«½ÃÇϵµ·Ï ÇÑ´Ù. // ½ºÅ×ÀÌÁö À̵¿½Ã °ð¹Ù·Î ¸®¼Â½ÃŲ´Ù. bool CDnPlayerActor::CanChangeJob( int iJobID ) { // °ÔÀÓ¼­¹ö¿¡¼­´Â ½ÇÁ¦ ÀüÁ÷ÇÏÁö ¾Ê´Â´Ù. // ÇöÀç Á÷¾÷¿¡¼­ ÀüÁ÷ÀÌ °¡´ÉÇÑ 2Â÷ Á÷¾÷ÀÎÁö ÀÎÁõ¸¸Çؼ­ Ŭ¶ó·Î º¸³»ÁØ´Ù. DNTableFileFormat* pJobTable = GetDNTable( CDnTableDB::TJOB ); // ÇöÀç Á÷¾÷ÀÇ ´Ü°è°ª°ú ·çÆ® Á÷¾÷À» ¾ò¾î¿È. int iNowJob = m_pSession->GetUserJob(); int iNowJobDeep = 0; int iNowRootJob = 0; for( int i = 0; i < pJobTable->GetItemCount(); ++i ) { int iItemID = pJobTable->GetItemID( i ); if( iItemID == iNowJob ) { iNowJobDeep = pJobTable->GetFieldFromLablePtr( iItemID, "_JobNumber" )->GetInteger(); iNowRootJob = pJobTable->GetFieldFromLablePtr( iItemID, "_BaseClass" )->GetInteger(); break; } } int iJobIDToChange = iJobID; // ¹Ù²Ù±â ¿øÇÏ´Â Á÷¾÷°ú ´Ü°è°¡ °°°Å³ª Å«Áö È®ÀÎ. bool bResult = false; map mapRootJob; for( int i = 0; i < pJobTable->GetItemCount(); ++i ) { int iItemID = pJobTable->GetItemID( i ); if( iItemID == iJobIDToChange ) { int iJobRootToChange = pJobTable->GetFieldFromLablePtr( iItemID, "_BaseClass" )->GetInteger(); if( iNowRootJob == iJobRootToChange ) { int iJobDeepToChange = pJobTable->GetFieldFromLablePtr( iItemID, "_JobNumber" )->GetInteger(); if( iNowJobDeep < iJobDeepToChange ) { // ºÎ¸ð Á÷¾÷µµ ¸Â¾Æ¾ß ÇÔ. int iParentJobID = pJobTable->GetFieldFromLablePtr( iItemID, "_ParentJob" )->GetInteger(); if( iParentJobID == iNowJob ) { bResult = true; } else { // ¹Ù²Ù°íÀÚ ÇÏ´Â Á÷¾÷ÀÇ ºÎ¸ð Á÷¾÷ÀÌ ÇöÀç Á÷¾÷ÀÌ ¾Æ´Ô. wstring wszString = FormatW(L"ÇöÀç Á÷¾÷¿¡¼± ÀüÁ÷ ÇÒ ¼ö ¾ø´Â Á÷¾÷ÀÔ´Ï´Ù.!!\r\n"); m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size()*sizeof(WCHAR), L"", (WCHAR*)wszString.c_str()); } } else { // ¹Ù²Ù°íÀÚÇÏ´Â Á÷¾÷ÀÌ ¾Æ·¡ ´Ü°èÀÓ. ¸ø¹Ù²Þ. wstring wszString = FormatW(L"°°°Å³ª ³·Àº ´Ü°èÀÇ Á÷¾÷À¸·Î ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù!!\r\n"); m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size()*sizeof(WCHAR), L"", (WCHAR*)wszString.c_str()); } } else { // ¹Ù²Ù°íÀÚÇÏ´Â Á÷¾÷ÀÌ ´Ù¸¥ Ŭ·¡½ºÀÓ. ¸ø¹Ù²Þ. wstring wszString = FormatW(L"´Ù¸¥ Ŭ·¡½ºÀÇ Á÷¾÷À¸·Î ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù!!\r\n"); m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size()*sizeof(WCHAR), L"", (WCHAR*)wszString.c_str()); } } } if( false == bResult ) { wstring wszString = FormatW(L"À߸øµÈ Job ID ÀÔ´Ï´Ù..\r\n"); m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size()*sizeof(WCHAR), L"", (WCHAR*)wszString.c_str()); } return bResult; } void CDnPlayerActor::SendTempJobChange( int iJobID ) { BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &iJobID, sizeof(int) ); Send( eActor::SC_DO_TEMP_JOBCHANGE, &Stream ); m_iTempChangedJob = iJobID; } // Àӽà ÀüÁ÷À» ¿ø·¡´ë·Î º¹±¸ÇÒ °ÍÀ» ¸í·É. // ÀÌ ½ÃÁ¡ºÎÅÍ´Â ½ºÅ³ ·¹º§¾÷ ¹× °¢Á¾ Á¶ÀÛÀÌ °¡´ÉÇÏ´Ù. void CDnPlayerActor::EndAddTempSkillAndSendRestoreTempJobChange( void ) { BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &m_iTempChangedJob, sizeof(int) ); Send( eActor::SC_RESTORE_TEMP_JOBCHANGE, &Stream ); m_iTempChangedJob = 0; } void CDnPlayerActor::AddTempSkill( int iSkillID ) { // Àӽ÷Π¸¸µé·Á°í ÇÏ´Â ½ºÅ³ÀÌ °­È­ ÆÐ½Ãºê ½ºÅ³ÀÎ °æ¿ì // º£À̽º°¡ µÇ´Â ½ºÅ³À» °®°í ÀÖ´ÂÁö ã¾Æ¼­ ¾ø´Ù¸é ¿ª½Ã Àӽà ½ºÅ³·Î º£À̽º ½ºÅ³·Î Ãß°¡ÇÑ´Ù. DNTableFileFormat* pSkillTable = GetDNTable( CDnTableDB::TSKILL ); int iNeedBaseSkillID = 0; if( pSkillTable->IsExistItem( iSkillID ) ) iNeedBaseSkillID = pSkillTable->GetFieldFromLablePtr( iSkillID, "_BaseSkillID" )->GetInteger(); DNVector(int) vlSkillsToAdd; if( 0 < iNeedBaseSkillID ) { // °­È­ ´ë»ó ½ºÅ³À» °®°í ÀÖÁö ¾ÊÀº »óŶó¸é À̰͵µ »õ·Î »ý¼ºÇϵµ·Ï º¤ÅÍ¿¡ ³Ö¾îÁÜ. if( false == IsExistSkill( iNeedBaseSkillID ) ) vlSkillsToAdd.push_back( iNeedBaseSkillID ); } vlSkillsToAdd.push_back( iSkillID ); for( int i = 0; i < (int)vlSkillsToAdd.size(); ++i ) { int iSkillIDToAdd = vlSkillsToAdd.at( i ); bool bSuccess = AddSkill( iSkillIDToAdd, 1, CDnSkill::PVE ); if( bSuccess ) { DnSkillHandle hSkill = FindSkill( iSkillIDToAdd ); if( hSkill ) { hSkill->AsTempSkill(); // 2Â÷ ÀüÁ÷½ºÅ³ÀÌ¶ó¼­ ÇöÀç »ç¿ëÇÒ ¼ö ¾ø´Â ½ºÅ³À̶ó¸é, // ÇöÀç ij¸¯ÅÍ ·¹º§ ¹× Á÷¾÷¿¡ ¸Â°Ô °´Ã¼ °ªÀ» ¹Ù²ãÁØ´Ù. if( GetLevel() < hSkill->GetLevelLimit() ) hSkill->SetLevelLimit( GetLevel() ); if( false == IsPassJob( hSkill->GetNeedJobClassID() ) ) hSkill->SetNeedJobClassID( GetJobClassID() ); // Ŭ¶ó·Î Àӽà ½ºÅ³ Ãß°¡ º¸³¿. BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &iSkillID, sizeof(int) ); Send( eActor::SC_ADD_TEMP_SKILL, &Stream ); m_bTempSkillAdded = true; } } } } void CDnPlayerActor::RemoveAllTempSkill( void ) { #ifndef PRE_FIX_SKILLLIST DNVector(DnSkillHandle)::iterator iter = m_vlhSkillList.begin(); for( iter; iter != m_vlhSkillList.end(); ) { DnSkillHandle hSkill = *iter; if( hSkill->IsTempSkill() ) { // 2Â÷ÀüÁ÷À» À§ÇÑ ÀÓ½ÃÀûÀÎ ±â´ÉÀ̹ǷΠMASkillUser °¡ ¾Æ´Ñ ¿©±â¼­ Á÷Á¢ // ½ºÅ³ °´Ã¼ »èÁ¦ 󸮸¦ ÇÔ. ÃßÈÄ¿¡ ÀÌÂʰü·Ã Ãß°¡ ¿äûÀÌ ÀÖ´Â °æ¿ì // MASkillUser::RemoveSkill() ¸¦ »ç¿ëÇØ¾ßÇÒ ¼öµµ ÀÖÀ½. int iSkillID = hSkill->GetClassID(); OnRemoveSkill( hSkill ); iter = m_vlhSkillList.erase( iter ); // Ŭ¶ó·Î Àӽà ½ºÅ³ Á¦°Å º¸³¿. BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &iSkillID, sizeof(int) ); Send( eActor::SC_REMOVE_TEMP_SKILL, &Stream ); } else ++iter; } #else vector vlTempSkills; for( DWORD i = 0; i < GetSkillCount(); ++i ) { DnSkillHandle hSkill = GetSkillFromIndex( i ); if( hSkill->IsTempSkill() ) { vlTempSkills.push_back( hSkill->GetClassID() ); } } for( int i = 0; i < (int)vlTempSkills.size(); ++i ) { int iSkillID = vlTempSkills.at( i ); RemoveSkill( iSkillID ); // Ŭ¶ó·Î Àӽà ½ºÅ³ Á¦°Å º¸³¿. BYTE pBuffer[ 32 ] = { 0 }; CPacketCompressStream Stream( pBuffer, 32 ); Stream.Write( &iSkillID, sizeof(int) ); Send( eActor::SC_REMOVE_TEMP_SKILL, &Stream ); } #endif // #ifndef PRE_FIX_SKILLLIST m_bTempSkillAdded = false; } #ifdef PRE_ADD_48714 #include "DNMailSender.h" #endif //#ifdef PRE_ADD_48714 void CDnPlayerActor::OnInvalidPlayerChecker( int nValue ) { m_nInvalidPlayerCheckCounter += nValue; OutputDebug( "OnInvalidPlayerChecker : %d, (%d)\n", m_nInvalidPlayerCheckCounter, nValue ); if( m_pSession && m_pSession->GetHackPlayRestraintValue() > 0 ) { #if defined (PRE_ADD_ABUSE_ACCOUNT_RESTRAINT) //Á¦Àç°¡ µé¾î°¥°æ¿ì ²÷´Â ÆÇ´Ü¿¡ *2 Á¦¿Ü if( m_nInvalidPlayerCheckCounter >= m_pSession->GetHackPlayRestraintValue() ) { //ÀÏ´ÜÀº Çѱ¹¿¡¸¸ 󸮵ǾîÁø´Ù if (m_pSession->GetHackCharacterCntWithoutMe() > 0) { //Áö±ÝÇöÀç ij¸¯Å͸¦ Á¦¿ÜÇÑ Ä³¸¯ÅͰ¡ Çϳª Àִµ¥ Çϳª ´õ °É·È´Ù 36080À̽´¿¡ ÀÇÇÏ¿© Á¦Àçó¸®ÇÑ´Ù. #if defined(PRE_ADD_MULTILANGUAGE) std::wstring wszRestraintReason = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 100070, m_pSession->m_eSelectedLanguage); std::wstring wszRestraintReasonForDolis = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 100071, m_pSession->m_eSelectedLanguage); #else //#if defined(PRE_ADD_MULTILANGUAGE) std::wstring wszRestraintReason = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 100070); std::wstring wszRestraintReasonForDolis = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 100071); #endif //#if defined(PRE_ADD_MULTILANGUAGE) m_pSession->GetDBConnection()->QueryAddRestraint(m_pSession, DBDNWorldDef::RestraintTargetCode::Account, DBDNWorldDef::RestraintTypeCode::ConnectRestraint, wszRestraintReason.c_str(), wszRestraintReasonForDolis.c_str(), 9999, DBDNWorldDef::RestraintDolisReasonCode::AbuseRestraintCode); } m_pSession->DetachConnection( L"InvalidPlayerCheckCounter" ); } #else #ifdef PRE_ADD_48714 if(m_nInvalidPlayerCheckCounter >= m_pSession->GetHackPlayRestraintValue()) { if (m_pSession->GetDBConnection()) { #if defined (_TW) WCHAR wszBuf[100]; wsprintf( wszBuf, L"Invalidcount Reached limit Value"); m_pSession->GetDBConnection()->QueryAddAbuseLog(m_pSession, ABUSE_TWN_EXTENDLOG, wszBuf); #if defined(PRE_ADD_MULTILANGUAGE) std::wstring wszRestraintReason = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 109049, m_pSession->m_eSelectedLanguage); #else //#if defined(PRE_ADD_MULTILANGUAGE) std::wstring wszRestraintReason = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 109049); #endif //#if defined(PRE_ADD_MULTILANGUAGE) m_pSession->GetDBConnection()->QueryAddRestraint(m_pSession, DBDNWorldDef::RestraintTargetCode::Character, DBDNWorldDef::RestraintTypeCode::TradeRestraint, wszRestraintReason.c_str(), wszRestraintReason.c_str(), 9999, DBDNWorldDef::RestraintDolisReasonCode::AbuseTradeRestraintCode); #endif //#if defined (_TW) CDNMailSender::Process(m_pSession, AbuseLog::Common::AbuseLog_Reached_MailID); } } #endif //#ifdef PRE_ADD_48714 if( m_nInvalidPlayerCheckCounter >= m_pSession->GetHackPlayRestraintValue()*2 ) { m_pSession->DetachConnection( L"InvalidPlayerCheckCounter" ); } #endif //#if defined (PRE_ADD_ABUSE_ACCOUNT_RESTRAINT) } } void CDnPlayerActor::OrderUseSkillToMySummonedMonster( OrderMySummonedMonsterStruct* pStruct ) { if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_215 ) ) { DNVector( DnBlowHandle ) vlhBlows; GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_215, vlhBlows ); _ASSERT( 1 == (int)vlhBlows.size() ); if( false == vlhBlows.empty() ) { // Á¤ÀÇµÈ ¹Ý°æ ¾È¿¡ ³»°¡ ¼ÒȯÇÑ ¸ó½ºÅͰ¡ ÀÖ´ÂÁö È®ÀÎ. float fRangeSQ = pStruct->fOrderRange * pStruct->fOrderRange; DNVector( DnMonsterActorHandle ) vlhMonsters; for( list::const_iterator iter = m_listSummonMonster.begin(); iter != m_listSummonMonster.end(); ++iter ) { DnMonsterActorHandle hMonster = *iter; if( hMonster && false == hMonster->IsDie() ) { float fDistanceWithThisMonsterSQ = EtVec3LengthSq( &EtVector3(*GetPosition() - *hMonster->GetPosition()) ); if( fDistanceWithThisMonsterSQ < fRangeSQ ) { vlhMonsters.push_back( hMonster ); } } } map >::iterator iterMap = m_mapSummonMonsterByGroup.begin(); for( iterMap; iterMap != m_mapSummonMonsterByGroup.end(); ++iterMap ) { const list& listSummonMonster = iterMap->second; for( list::const_iterator iterList = listSummonMonster.begin(); iterList != listSummonMonster.end(); ++iterList ) { DnMonsterActorHandle hMonster = *iterList; if( hMonster && false == hMonster->IsDie() ) { float fDistanceWithThisMonsterSQ = EtVec3LengthSq( &EtVector3(*GetPosition() - *hMonster->GetPosition()) ); if( fDistanceWithThisMonsterSQ < fRangeSQ ) { vlhMonsters.push_back( hMonster ); } } } } if( false == vlhMonsters.empty() ) { CDnOrderMySummonedMonsterBlow* pBlow = static_cast( vlhBlows.front().GetPointer() ); int iSkillID = pBlow->GetSkillID(); for( int i = 0; i < (int)vlhMonsters.size(); ++i ) { DnMonsterActorHandle hMonster = vlhMonsters.at( i ); if( hMonster->GetMonsterClassID() == pStruct->nMonsterID ) { // TODO: AI ÂÊ¿¡ ¹®ÀÇÇØ¼­ ½ºÅ³ »ç¿ë ¿¹¾àÀ» ÇØµÖ¾ß ÇÔ. if( hMonster->IsExistSkill( iSkillID ) ) { MAAiScript* pScript = static_cast(hMonster->GetAIBase()); if( hMonster->GetAggroTarget() ) pScript->GetMonsterSkillAI()->AddWaitOrderCount( hMonster, iSkillID ); } } } } } } } bool CDnPlayerActor::CheckSkipAirCondition(int iSkill) { if(IsAir()) { bool bHaveGroundCheck = false; DnSkillHandle hSkill = FindSkill(iSkill); if(hSkill) { if(hSkill->IsExistUsableChecker(IDnSkillUsableChecker::GROUNDMOVABLE_CHECKER)) bHaveGroundCheck = true; } if(bHaveGroundCheck) { return true; } } return false; } bool CDnPlayerActor::HasSameGlobalIDSkill( int iSkillID ) { bool bResult = false; DNTableFileFormat* pSkillTable = GetDNTable( CDnTableDB::TSKILL ); int iGlobalSkillGroupID = pSkillTable->GetFieldFromLablePtr( iSkillID, "_GlobalSkillGroup" )->GetInteger(); if( 0 < iGlobalSkillGroupID ) { for( DWORD i = 0; i < GetSkillCount(); ++i ) { DnSkillHandle hExistSkill = GetSkillFromIndex( i ); if( hExistSkill && hExistSkill->GetGlobalSkillGroupID() == iGlobalSkillGroupID ) { bResult = true; break; } } } return bResult; } #ifdef PRE_FIX_GAMESERVER_PERFOMANCE bool CDnPlayerActor::IsAllowCallSkillProcess( float fDelta ) { return m_FrameSkipCallSkillProcess.Update( fDelta ); } #endif // #ifdef PRE_FIX_GAMESERVER_PERFOMANCE void CDnPlayerActor::RemoveAllBubbles( bool bRemoveEvent ) { if( m_pBubbleSystem ) m_pBubbleSystem->RemoveAllBubbles( bRemoveEvent ); } void CDnPlayerActor::ApplyEnchantSkillOnceFromBubble( int iTargetSkillID, int iEnchantSkillID ) { DnSkillHandle hEnchantSkill; map::iterator iter = m_mapEnchantSkillFromBubble.find( iEnchantSkillID ); if( m_mapEnchantSkillFromBubble.end() != iter ) { hEnchantSkill = iter->second; } else { // pvp/pve ¸ðµÎ µ¥ÀÌÅͰ¡ ÀÖ¾î¾ß Á¦´ë·Î »ý¼ºµÊ. hEnchantSkill = CDnSkill::CreateSkill( GetMySmartPtr(), iEnchantSkillID, 1 ); m_mapEnchantSkillFromBubble.insert( make_pair(iEnchantSkillID, hEnchantSkill) ); } DnSkillHandle hTargetSkill = FindSkill( iTargetSkillID ); _ASSERT( hTargetSkill ); _ASSERT( hEnchantSkill ); if( hTargetSkill && hEnchantSkill ) { // ÀÌ¹Ì °­È­µÈ ½ºÅ³ÀÌ ´ë»óÀÌ µÉ ¼ö´Â ¾øÀ½. bool bIsEnchantedAlready = hTargetSkill->IsEnchantedSkill(); _ASSERT( false == bIsEnchantedAlready ); if( false == bIsEnchantedAlready ) { hTargetSkill->ApplyEnchantSkillOnceFromBubble( hEnchantSkill ); } } } bool CDnPlayerActor::OnApplySpectator(bool bEnable) { CDNGameRoom* pGameRoom = GetGameRoom(); if( pGameRoom == NULL || pGameRoom->bIsPvPRoom() == false || pGameRoom->GetPvPGameMode()->bIsAllKillMode() == false ) return false; if( bEnable ) { if( IsProcessSkill() ) CancelUsingSkill(); if(IsBattleMode()) SetBattleMode(false); } return true; } bool CDnPlayerActor::IsSpectatorMode() { return IsAppliedThisStateBlow(STATE_BLOW::BLOW_230); } void CDnPlayerActor::ChangeSkillLevelUp(int nSkillID, int nOrigLevel) { if( IsProcessSkill() ) return; DnSkillHandle hSkill = FindSkill(nSkillID); if( hSkill ) { if (hSkill->GetElapsedDelayTime() > 0.0f || hSkill->IsToggleOn()) return; } __super::ChangeSkillLevelUp(nSkillID, nOrigLevel); DnSkillHandle hChangedSkill = FindSkill( nSkillID ); if( hChangedSkill ) { ReplacementGlyph( hChangedSkill ); } } #if defined(PRE_ADD_TOTAL_LEVEL_SKILL) void CDnPlayerActor::UpdateTotalLevel(int nLevel) { if (m_pTotalLevelSkillSystem) { m_pTotalLevelSkillSystem->SetTotalLevel(nLevel); } } void CDnPlayerActor::UpdateTotalLevelByCharLevel() { if (m_pTotalLevelSkillSystem) m_pTotalLevelSkillSystem->UpdateTotalLevel(); } void CDnPlayerActor::AddTotalLevelSkill(int nSlotIndex, int nSkillID, bool isInitialize/* = false*/) { if (m_pTotalLevelSkillSystem) { DnSkillHandle hSkill = m_pTotalLevelSkillSystem->FindTotalLevelSkill(nSkillID); if (!hSkill) { RemoveTotalLevelSkill(nSlotIndex); return; } //¸¸¾à ÇØ´ç ½½·ÔÀÌ È°¼ºÈ­°¡ µÇÁö ¾ÊÀº °æ¿ì´Â Ãß°¡ ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù.. bool isActivateSlot = m_pTotalLevelSkillSystem->IsActivateSlot(nSlotIndex); if (isActivateSlot == false) return; //PVE/PVP¼³Á¤.. // ½ºÅ³ ·¹º§ µ¥ÀÌÅ͸¦ pve/pvp ÀÎ °æ¿ì¿Í ³ª´²¼­ ¼ÂÆÃÇØÁØ´Ù. int iSkillLevelDataType = CDnSkill::PVE; if( GetGameRoom()->bIsPvPRoom() ) iSkillLevelDataType = CDnSkill::PVP; hSkill->SelectLevelDataType( iSkillLevelDataType ); m_pTotalLevelSkillSystem->AddTotalLevelSkill(nSlotIndex, hSkill, isInitialize); } } void CDnPlayerActor::RemoveTotalLevelSkill(int nSlotIndex) { if (m_pTotalLevelSkillSystem) { m_pTotalLevelSkillSystem->RemoveTotallevelSkill(nSlotIndex); } } void CDnPlayerActor::ActivateTotalLevelSkillSlot(int nSlotIndex, bool bActivate) { if (m_pTotalLevelSkillSystem) m_pTotalLevelSkillSystem->ActivateTotalLevelSkillSlot(nSlotIndex, bActivate); } void CDnPlayerActor::ActivateTotalLevelSkillCashSlot(int nSlotIndex, bool bActivate, __time64_t tExpireDate) { if (m_pTotalLevelSkillSystem) m_pTotalLevelSkillSystem->ActivateTotalLevelSkillCashSlot(nSlotIndex, bActivate, tExpireDate); } void CDnPlayerActor::OnLevelChange() { UpdateTotalLevelByCharLevel(); } #endif // PRE_ADD_TOTAL_LEVEL_SKILL void CDnPlayerActor::ApplyEventStateBlow() { int nAddStateEffectIndex = -1; DnBlowHandle hBlow; #ifdef PRE_ADD_WEEKLYEVENT if (CDnWorld::GetInstance(GetRoom()).GetMapSubType() != EWorldEnum::MapSubTypeNest && !GetGameRoom()->bIsPvPRoom() ) { bool bRfreshHP = false; float fCurrentHpRatio = (float)GetHP() / (float)GetMaxHP(); int nThreadID = GetGameRoom()->GetServerID(); float fEventHp = g_pDataManager->GetWeeklyEventValuef(WeeklyEvent::Player, GetClassID(), WeeklyEvent::Event_1, nThreadID); if (fEventHp != 0.f) { std::string strValue; strValue.append(boost::lexical_cast(fEventHp)); nAddStateEffectIndex = CmdAddStateEffect(NULL, STATE_BLOW::BLOW_058, -1, strValue.c_str(), false, true , true ); m_vecEventEffectList.push_back( nAddStateEffectIndex ); bRfreshHP = true; } float fEventAttack = g_pDataManager->GetWeeklyEventValuef(WeeklyEvent::Player, GetClassID(), WeeklyEvent::Event_2, nThreadID); if (fEventAttack != 0.f) { std::string strValue; strValue.append(boost::lexical_cast(fEventAttack)); nAddStateEffectIndex = CmdAddStateEffect(NULL, STATE_BLOW::BLOW_002, -1, strValue.c_str(), false, true , true ); m_vecEventEffectList.push_back( nAddStateEffectIndex ); nAddStateEffectIndex = CmdAddStateEffect(NULL, STATE_BLOW::BLOW_029, -1, strValue.c_str(), false, true , true ); m_vecEventEffectList.push_back( nAddStateEffectIndex ); } float fEventDefense = g_pDataManager->GetWeeklyEventValuef(WeeklyEvent::Player, GetClassID(), WeeklyEvent::Event_3, nThreadID); if (fEventDefense != 0.f) { std::string strValue; strValue.append(boost::lexical_cast(fEventDefense)); nAddStateEffectIndex = CmdAddStateEffect(NULL, STATE_BLOW::BLOW_004, -1, strValue.c_str(), false, true , true ); m_vecEventEffectList.push_back( nAddStateEffectIndex ); nAddStateEffectIndex = CmdAddStateEffect(NULL, STATE_BLOW::BLOW_094, -1, strValue.c_str(), false, true , true ); m_vecEventEffectList.push_back( nAddStateEffectIndex ); } if( bRfreshHP ) { GetStateBlow()->Process( 0 , 0 ); CmdRefreshHPSP( (INT64)(GetMaxHP() * fCurrentHpRatio) , GetSP() ); } } #endif } void CDnPlayerActor::RemoveEventStateBlow() { for( DWORD index = 0; index < m_vecEventEffectList.size() ; ++index ) { CmdRemoveStateEffectFromID( m_vecEventEffectList[index] ); } m_vecEventEffectList.clear(); } bool CDnPlayerActor::CheckSkillAction( const char *szActionName ) { if( strstr( szActionName, "Skill_" ) || strstr( szActionName, "ChargeShoot_" ) || strstr( szActionName, "GuildSkill_" ) || strstr( szActionName, "Throw_" ) || strstr( szActionName, "Tumble_" ) || strstr( szActionName, "AerialEvasion" ) ) { return true; } return false; } void CDnPlayerActor::MakeEquipAndPassiveState( CDnState &State ) { State.ResetState(); State = MakeEquipState(); CDnState BUFF_STATE; BUFF_STATE.ResetState(); if( m_pStateBlow ) { int nSize = m_pStateBlow->GetNumStateBlow(); for ( int i = 0 ; i < nSize ; i++ ) { DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i); if( hBlow && CDnCreateBlow::IsBasicBlow( hBlow->GetBlowIndex() ) == true && hBlow->GetParentSkillInfo() && hBlow->GetParentSkillInfo()->eSkillType == CDnSkill::SkillTypeEnum::Passive && hBlow->GetParentSkillInfo()->eDurationType == CDnSkill::DurationTypeEnum::Buff ) { CDnBasicBlow *pBlow = static_cast(hBlow.GetPointer()); if( pBlow ) { CDnState *pState = const_cast(pBlow->GetState()); BUFF_STATE.MergeState( *pState, pState->GetValueType() ); } } } } State.MergeState( BUFF_STATE, ValueTypeAbsolute ); State.CalculateRatioValue( BUFF_STATE ); } #ifdef PRE_ADD_COSTUME_SKILL void CDnPlayerActor::RefreshCostumeSkill( int nSkillIndex, int nSkillLevel ) { if( m_nCostumeSkillID == nSkillIndex ) return; if( m_nCostumeSkillID > 0 ) RemoveSkill( m_nCostumeSkillID ); if( nSkillIndex > 0 ) { AddSkill( nSkillIndex, nSkillLevel ); DnSkillHandle hSkill = FindSkill( nSkillIndex ); if( hSkill ) { if( hSkill->GetSkillType() != CDnSkill::SkillTypeEnum::Active ) { RemoveSkill( nSkillIndex ); return; } hSkill->OnBeginCoolTime(); } } m_nCostumeSkillID = nSkillIndex; } #endif // PRE_ADD_COSTUME_SKILL #ifdef PRE_ADD_VEHICLE_SPECIAL_ACTION void CDnPlayerActor::ReportInvalidAction() { if( m_pPlayerActionChecker ) ((CDnPlayerActionChecker*)m_pPlayerActionChecker)->OnInvalidAction(); } #endif