#include "StdAfx.h" #include "DnWorldMultiDurabilityProp.h" #include "DnStateBlow.h" #include "DnTableDB.h" #include "DnPlayerActor.h" #include "DnProjectile.h" #include "TaskManager.h" #include "DnGameTask.h" #include "DnPropState.h" #include "DnPropCondition.h" #include "DnPropStateDoAction.h" #include "DnPropStateTrigger.h" #include "DnPropCondiDurability.h" #include "DnPropActionCondition.h" #include "DnPropCondiSubDurability.h" #include "DnMonsterActor.h" CDnWorldMultiDurabilityProp::CDnWorldMultiDurabilityProp( CMultiRoom* pRoom ) : CDnWorldBrokenProp( pRoom ), m_iNowStateIndex( 0 ), m_pActivateState( NULL ) { } CDnWorldMultiDurabilityProp::~CDnWorldMultiDurabilityProp(void) { ReleasePostCustomParam(); } bool CDnWorldMultiDurabilityProp::Initialize( CEtWorldSector *pParentSector, const char *szPropName, EtVector3 &vPos, EtVector3 &vRotate, EtVector3 &vScale ) { // µðÆúÆ®ÀÇ BrokenProp ÀÇ Initialize ¸¦ È£ÃâÇÏÁö ¾Ê°í °¢ phase º°·Î fsm À» ±¸¼ºÇØÁØ´Ù. if( m_hMonster ) *m_hMonster->GetMatEx() = *GetMatEx(); bool bResult = CDnWorldActProp::Initialize( pParentSector, szPropName, vPos, vRotate, vScale ); if( !bResult ) return false; // ÀÏ´Ü Å×½ºÆ® SetActionQueue( "Activate", 0, 3.0f, 0.0f ); return true; } void CDnWorldMultiDurabilityProp::_InitializeFSM( void ) { // Ãʱ⿣ idle »óÅÂ. Activate »óŰ¡ µÇ¸é ¹ßµ¿ÇÑ °ÍÀ¸·Î ÆÇ´Ü. CDnPropState* pIdleState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::NORMAL ); m_pFSM->AddState( pIdleState ); // ¿ÜºÎ Æ®¸®°Å¿¡¼­ Activate ¾×¼ÇÀ» ½ÇÇàÇØ¼­ ÀÛµ¿À» ½ÃÀÛÇÑ °æ¿ì CDnPropState* pActivateState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::NORMAL ); m_pFSM->AddState( pActivateState ); m_pActivateState = pActivateState; // ¸ÞÀÎ ³»±¸µµ°¡ ´Ù µÇ¾î ºÎ¼­Á³À» ¶§´Â ÁöÁ¤µÈ Æ®¸®°Å¸¦ ½ÇÇàÇϰí Broken ¾×¼ÇÀ» ¼öÇà. CDnPropState* pTriggerState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::TRIGGER ); m_pFSM->AddState( pTriggerState ); CDnPropState* pBrokenActionState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::DO_ACTION ); m_pFSM->AddState( pBrokenActionState ); m_pBrokenActionState = static_cast( pBrokenActionState ); m_pTriggerActionState = static_cast( pTriggerState ); m_pTriggerActionState->SetFuncName( "CDnWorldProp::OnBrokenProp" ); // Á¶°Ç »ý¼º CDnPropCondition* pToActivate = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::ACTION_CHECK ); // ÀÛµ¿ ½ÃÀÛ static_cast(pToActivate)->SetActionName( "Activate" ); m_pFSM->AddCondition( pToActivate ); CDnPropCondition* pToIdle = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::ACTION_CHECK ); // idle ¾×¼ÇÀ̸é idle »óÅ·Î. static_cast(pToIdle)->SetActionName( "Idle" ); m_pFSM->AddCondition( pToIdle ); // ¿ÜºÎ Æ®¸®°Å¿¡¼­ Activate ¾×¼ÇÀ» ½ÇÇàÇØ¼­ ÀÛµ¿À» ½ÃÀÛÇÑ °æ¿ì, µÎ¹øÂ° »óÅ·ΠÀüÀÌÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. pIdleState->AddTransitState( pActivateState, pToActivate ); // ¸ÞÀÎ ³»±¸µµ°¡ ´Ù µÇ¾ú´ÂÁö üũÇÏ´Â °´Ã¼. -> Æ®¸®°Å ±¸µ¿ »óÅ·ΠÀüÀÌ. CDnPropCondition* pDurabilityCondition = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::COMPARE_DURABILITY ); m_pFSM->AddCondition( pDurabilityCondition ); static_cast(pDurabilityCondition)->Initialize( 0, CDnPropCondiDurability::LESS_EQUAL ); // Æ®¸®°Å »óÅ¿¡¼­ Broken ¾×¼ÇÀ» ½ÇÇàÇÏ´Â »óÅ·ΠÀüÀÌ. ¾Æ¹« Á¶°ÇÀÌ ¾ø´Â NULL Á¶°Ç °´Ã¼. CDnPropCondition* pNULLCondition = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::NULL_CONDITION ); m_pFSM->AddCondition( pNULLCondition ); // Æ®¸®°Å »óÅ¿¡¼­´Â °ð¹Ù·Î ¾Æ¹« Á¶°Ç¾øÀÌ brokenstate ·Î ³Ñ¾î°£´Ù. m_pTriggerActionState->AddTransitState( m_pBrokenActionState, pNULLCondition ); for( int i = 0; i < (int)m_vlStateInfos.size(); ++i ) { S_STATE_INFO& StateInfo = m_vlStateInfos.at( i ); //// ³»±¸µµ üũ À妽º´Â ÀÌÀü »óÅ¿¡¼­ ÀüÀÌÇϱâ À§ÇÑ Á¶°ÇÀ̹ǷΠÀÌÀü »óÅ ±âÁØÀÇ ³»±¸µµ À妽ºÀÓ. //int iSubDurCheckIndex = i - 1; //if( iSubDurCheckIndex < 0 ) // iSubDurCheckIndex = (int)m_vlStateInfos.size() - 1; // »óÅ »ý¼º ¹× Á¶°Ç°ú À̾îÁÖ±â. CDnPropState* pState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::DO_ACTION ); m_pFSM->AddState( pState ); static_cast(pState)->AddActionName( StateInfo.pActionNameWhenSubDurabilityZero ); // ºñȰ¼º »óÅ·Π°¡´Â Á¶°ÇÀ¸·Î ÀüÀÌµÇ°Ô ¼ÂÆÃ. pState->AddTransitState( pIdleState, pToIdle ); // ¸ÞÀÎ ³»±¸µµ°¡ ´Ù µÇ¾î ºÎ¼­Áö¸é °ð¹Ù·Î ºÎ¼­Áö´Â 󸮸¦ À§ÇÑ Æ®¸®°Å »óÅ·ΠÀüÀÌ. pState->AddTransitState( m_pTriggerActionState, pDurabilityCondition );; if( 1 == i ) { // ¿ÜºÎ Æ®¸®°Å¿¡¼­ Activate ¾×¼ÇÀ» ½ÇÇàÇØ¼­ ÀÛµ¿À» ½ÃÀÛÇÑ °æ¿ì, ÇöÀç ÀÌ¹Ì Activate »óÅÂÀ̹ǷΠ// ´ÙÀ½¿¡ ÀüÀÌµÉ ´ë»óÀÎ µÎ¹øÂ° »óÅ·ΠÀüÀÌÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. // ÇÁ¶øÀÇ »óŰ¡ ÇѹÙÄû µ¹°Ô µÇ¸é ±×¶§ºÎÅÏ °è¼Ó ¸ÞÀÎ ³»±¸µµ°¡ ´Ù ´â¶§ ±îÁö °è¼Ó ÀÌ º¤ÅÍ¿¡ ÀÖ´Â »óź°·Î ·ÎÅ×À̼ÇÀ» µ¹°Ô µÈ´Ù. // ³»±¸µµ Á¶°Ç »ý¼º. CDnPropCondiSubDurability* pSubDurabilityCondition = static_cast(CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::COMPARE_SUB_DURABILITY )); m_pFSM->AddCondition( pSubDurabilityCondition ); pSubDurabilityCondition->Initialize( 0, 0, CDnPropCondiSubDurability::LESS_EQUAL ); pActivateState->AddTransitState( pState, pSubDurabilityCondition ); } if( 0 < i ) { // ÀÌÀü »óÅ¿¡°Ô ÇöÀç »óÅ·ΠÀüÀÌÇÒ ¼ö ÀÖµµ·Ï Ãß°¡. CDnPropState* pPrevState = m_vlStateInfos.at( i-1 ).pState; // ³»±¸µµ Á¶°Ç »ý¼º. CDnPropCondiSubDurability* pSubDurabilityCondition = static_cast(CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::COMPARE_SUB_DURABILITY )); m_pFSM->AddCondition( pSubDurabilityCondition ); pSubDurabilityCondition->Initialize( 0, i-1, CDnPropCondiSubDurability::LESS_EQUAL ); pPrevState->AddTransitState( pState, pSubDurabilityCondition ); } // ¸Ç ³¡ÀÎ °æ¿ì ´Ù½Ã »óÅ 1·Î ÀüÀÌÇÒ ¼ö ÀÖµµ·Ï Ãß°¡. if( i == (int)m_vlStateInfos.size()-1 ) { CDnPropState* pFirstState = m_vlStateInfos.front().pState; CDnPropCondiSubDurability* pSubDurabilityCondition = static_cast(CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::COMPARE_SUB_DURABILITY )); m_pFSM->AddCondition( pSubDurabilityCondition ); pSubDurabilityCondition->Initialize( 0, i, CDnPropCondiSubDurability::LESS_EQUAL ); pState->AddTransitState( pFirstState, pSubDurabilityCondition ); } StateInfo.pState = pState; } m_pFSM->SetEntryState( pIdleState ); } bool CDnWorldMultiDurabilityProp::InitializeTable( int nTableID ) { if( CDnWorldActProp::InitializeTable(nTableID) == false ) return false; bool bResult = false; if( GetData() ) { MultiDurabilityBrokenPropStruct* pStruct = (MultiDurabilityBrokenPropStruct*)GetData(); int nMainDurability = pStruct->nMainDurability; int nItemDropGroupTableID = pStruct->nItemDropGroupTableID; int nMonsterTableID = pStruct->nMonsterTableID; int nSkillTableID = pStruct->nSkillTableID; int nSkillLevel = pStruct->nSkillLevel; bResult = InitializeMonsterActorProp( nMonsterTableID ); if( bResult ) { m_SkillComponent.Initialize( nSkillTableID, nSkillLevel ); m_nDurability = nMainDurability; // ÀÏ´Ü ¾×¼ÇÀ» ÃëÇÏÁö ¾Êµµ·ÏÇÑ´Ù. ½´ÅÍ ÇÁ¶øÀº Ŭ¶ó¿Í ½ÃÀÛ ½Ã°£À» ¸ÂÃçÁà¾ß ÇÑ´Ù.. SetAction( "Idle", 0.0f, 0.0f ); if( -1 != m_nDurability ) { if( 0 == m_nDurability ) m_nDurability = 1; m_nItemDropGroupTableID = pStruct->nItemDropGroupTableID; if( m_nItemDropGroupTableID > 0 ) { CDnDropItem::CalcDropItemList( GetRoom(), Dungeon::Difficulty::Max, m_nItemDropGroupTableID, m_VecDropItemList ); if (m_VecDropItemList.empty()){ // ÇÁ¶ø·Î±× // g_pLogConnection->QueryLogStage(GetRoom()->GetRoomID(), pTask->GetMapTableID(), 0, 0, nTableID); // ½ºÅ×ÀÌÁö ·Î±× 090226 } else { for( DWORD i=0; iQueryLogStage(GetRoom()->GetRoomID(), pTask->GetMapTableID(), 0, m_VecDropItemList[i].nItemID, nTableID); // ½ºÅ×ÀÌÁö ·Î±× 090226 } } } } S_STATE_INFO StateInfo; StateInfo.pActionNameWhenSubDurabilityZero = pStruct->szActionName_SubDurabilityOne; StateInfo.iOriginalDurability = StateInfo.iNowDurability = pStruct->nSubDurability_One; m_vlStateInfos.push_back( StateInfo ); StateInfo.pActionNameWhenSubDurabilityZero = pStruct->szActionName_SubDurabilityTwo; StateInfo.iOriginalDurability = StateInfo.iNowDurability = pStruct->nSubDurability_Two; m_vlStateInfos.push_back( StateInfo ); StateInfo.pActionNameWhenSubDurabilityZero = pStruct->szActionName_SubDurabilityThree; StateInfo.iOriginalDurability = StateInfo.iNowDurability = pStruct->nSubDurability_Three; m_vlStateInfos.push_back( StateInfo ); StateInfo.pActionNameWhenSubDurabilityZero = pStruct->szActionName_SubDurabilityFour; StateInfo.iOriginalDurability = StateInfo.iNowDurability = pStruct->nSubDurability_Four; m_vlStateInfos.push_back( StateInfo ); // µðÆúÆ®ÀÇ BrokenProp ÀÇ Initialize ¸¦ È£ÃâÇÏÁö ¾Ê°í °¢ »óź°·Î fsm À» ±¸¼ºÇØÁØ´Ù. _InitializeFSM(); } } return bResult; } int CDnWorldMultiDurabilityProp::GetSubDurability( int iIndex ) { int iResult = 0; if( iIndex < (int)m_vlStateInfos.size() ) { iResult = m_vlStateInfos.at( iIndex ).iNowDurability; } return iResult; } void CDnWorldMultiDurabilityProp::OnFSMStateEntry( const TDnFSMState* pState ) { for( int i = 0; i < (int)m_vlStateInfos.size(); ++i ) { const S_STATE_INFO& StateInfo = m_vlStateInfos.at( i ); if( StateInfo.pState == pState ) { m_iNowStateIndex = i; break; } } } void CDnWorldMultiDurabilityProp::CalcDamage( CDnDamageBase *pHitter, CDnDamageBase::SHitParam &HitParam ) { if( m_bDestroy == true ) return; if( m_bBroken ) return; m_pLastHitObject = pHitter; m_LastDamageTime = HitParam.RemainTime; m_nLastHitUniqueID = HitParam.iUniqueID; // ¸ÞÀÎ ³»±¸µµ¿Í ¼­ºê ³»±¸µµ¸¦ °°ÀÌ Â÷°¨. int iDurabilityAttack = (int)( HitParam.fDurability * 100.f ); _ASSERT( 0 <= m_iNowStateIndex && m_iNowStateIndex < (int)m_vlStateInfos.size() ); S_STATE_INFO& StateInfo = m_vlStateInfos.at( m_iNowStateIndex ); StateInfo.iNowDurability -= iDurabilityAttack; m_nDurability -= iDurabilityAttack; // NOTE: Æ®¸®°Å¿¡¼­ IsBroken() »ç¿ëÇÔ.. ´Ù¸¥ ÇÔ¼öµéµµ Ã¼Å©ÇØºÁ¾ß ÇÒµí. // Æ®¸®°Å °ü·ÃÇØ¼± »óȲÀÌ º¯°æµÇÀÚ¸¶ÀÚ °ð¹Ù·Î ÀüÀÌ Ã¼Å©¸¦ µ¹·Á¾ß ÇÑ´Ù. if( m_nDurability <= 0 ) { m_bBroken = true; //¼Òȯ ¸ó½ºÅÍÀÏ °æ¿ì ÁÖÀÎ ¾×Å͸¦ ã¾Æ¼­ ¼³Á¤ ÇØ¾ß ÇÔ. DnActorHandle hHitterActor; if (pHitter) hHitterActor = pHitter->GetActorHandle(); //¸ó½ºÅÍ ¾×ÅÍÀÎ °æ¿ì if (hHitterActor && hHitterActor->IsMonsterActor()) { DnActorHandle hMasterActor; CDnMonsterActor* pMonsterActor = NULL; pMonsterActor = static_cast(hHitterActor.GetPointer()); if (pMonsterActor) hMasterActor = pMonsterActor->GetSummonerPlayerActor(); //Á¤»óÀûÀÎ ÁÖÀÎ ¾×Å͸¦ ã¾ÒÀ¸¸é, hHitterActor¸¦ ÁÖÀÎ ¾×ÅÍ·Î º¯°æÇÑ´Ù. if (hMasterActor) hHitterActor = hMasterActor; } m_pTriggerActionState->AddFuncParam( "LastBrokenPropActor", hHitterActor ? hHitterActor->GetUniqueID() : -1 ); m_pFSM->Process( 0, 0.0f ); UpdatePropBreakToHitter( pHitter ); } else if( StateInfo.iNowDurability <= 0 ) { // ¼­ºê ³»±¸µµ°¡ ºüÁø »óŶó¸é FSM À» ÁøÇà½ÃŰ°í ºÎ¼­Áø »óÅÂÀÇ ¼­ºê ³»±¸µµ¸¦ ¸®¼Â½ÃÄÑÁØ´Ù. m_pFSM->Process( 0, 0.0f ); StateInfo.RestoreDurability(); } if( HitParam.hWeapon ) { if( HitParam.hWeapon->GetWeaponType() & CDnWeapon::Projectile ) { CDnProjectile *pProjectile = static_cast(HitParam.hWeapon.GetPointer()); if( pProjectile ) pProjectile->OnDamageSuccess( CDnActor::Identity(), HitParam ); else HitParam.hWeapon->SetDestroy(); } } } void CDnWorldMultiDurabilityProp::SetActionQueue( const char *szActionName, int nLoopCount , float fBlendFrame , float fStartFrame ) { //// °¢ »óź° ¾×¼ÇÀ̶ó¸é ¼­ºê ³»±¸µµ¸¦ ä¿öÁØ´Ù. //for( int i = 0; i < (int)m_vlStateInfos.size(); ++i ) //{ // S_STATE_INFO& StateInfo = m_vlStateInfos.at( i ); // if( 0 == strcmp( StateInfo.pActionNameWhenSubDurabilityZero, szActionName ) ) // { // StateInfo.RestoreDurability(); // // ÇöÀç »óÅÂÀÇ À妽º¸¦ ¼ÂÆÃ. ¾×¼Ç À̸§Àº ¼­ºê ³»±¸µµ°¡ ºÎ¼ÅÁ³À» ¶§ ÇàÇÒ ¾×¼ÇÀ̹ǷΠ// // ÇöÀç À妽ºÀÇ ´ÙÀ½ »óŰ¡ ÇöÀç »óŰ¡ µÈ´Ù. // m_iNowStateIndex = (i+1) % (int)m_vlStateInfos.size(); // } //} CDnWorldActProp::SetActionQueue( szActionName, nLoopCount, fBlendFrame, fStartFrame ); } void CDnWorldMultiDurabilityProp::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex ) { if( m_hMonster ) { *(m_hMonster->GetMatEx()) = m_Cross; m_SkillComponent.OnSignal( m_hMonster, GetMySmartPtr(), Type, pPtr, LocalTime, SignalStartTime, SignalEndTime, nSignalIndex ); } CDnWorldBrokenProp::OnSignal( Type, pPtr, LocalTime, SignalStartTime, SignalEndTime, nSignalIndex ); //// ¸¶Áö¸·À¸·Î ¸Â¾Ò´ø ¾×¼ÇÀ» ±â¾ïÇØ¼­ Normal »óÅÂÀÏ ¶§ ´Ù½Ã º¹±¸ ½ÃÄÑ ÁÜ. //if( STE_Projectile == Type ) //{ // const char* pCurrentAttackAction = GetCurrentAction(); // if( strlen( pCurrentAttackAction ) ) // m_strLastActionName.assign( pCurrentAttackAction ); //} } void CDnWorldMultiDurabilityProp::OnSyncComplete( CDNUserSession* pBreakIntoGameSession/*=NULL*/ ) { if( pBreakIntoGameSession ) CmdAction( GetCurrentAction(), pBreakIntoGameSession ); else CmdAction( m_szDefaultActionName.c_str(), pBreakIntoGameSession ); } void CDnWorldMultiDurabilityProp::OnChangeAction( const char *szPrevAction ) { //// ¾îÂ÷ÇÇ ´Ù¸¥ ¾×¼ÇÀ¸·Î ¹Ù²îÁö ¾Ê´Â ÀÌ»ó idle ÀÌ ¹Ýº¹µÇ±â ¶§¹®¿¡ //// idle ¾×¼ÇÀÎ °æ¿ì¿£ idle ·Î º¯°æµÇ¾úÀ» ¶§ Çѹø¸¸ º¸³½´Ù. //// Idle ¾×¼ÇÀÌ ÂªÀº °æ¿ì °è¼Ó ÆÐŶ ³ª°¡´Â ¹®Á¦¸¦ °¨¾È, ¼öÁ¤. (#17409) //const char* pCurrentAction = GetCurrentAction(); //if( strcmp(pCurrentAction, "Idle") == 0 ) //{ // if( strcmp(szPrevAction, "Idle") != 0 ) // { // ActionSync( pCurrentAction ); // } //} //else // ActionSync( pCurrentAction ); ////if( strcmp( szPrevAction, "Hit" ) ) ////{ //// if( !m_strLastActionName.empty() ) //// SetActionQueue( m_strLastActionName.c_str() ); ////} // ¾×¼ÇÀÌ º¯°æµÇ¾úÀ» ¶§¸¸ ÆÐŶ º¸³¿. if( m_nActionIndex != m_nPrevActionIndex ) ActionSync( GetCurrentAction() ); }