#include "StdAfx.h" #include "DnPartsMonsterActor.h" #include "MAAiCommand.h" #include "MAAiScript.h" #include "DnStateBlow.h" const int g_nNaviUpdateDelta = 1000; CDnPartsMonsterActor::CDnPartsMonsterActor( CMultiRoom *pRoom, int nClassID ) : TDnMonsterActor( pRoom, nClassID ) { m_nLastUpdateNaviTime = 0; } CDnPartsMonsterActor::~CDnPartsMonsterActor() { } MAMovementBase* CDnPartsMonsterActor::CreateMovement() { MAMovementBase* pMovement = new MAWalkMovementNav(); return pMovement; } bool CDnPartsMonsterActor::Initialize() { TDnMonsterActor< MASingleBody, MAMultiDamage >::Initialize(); LoadMultiDamageInfo(); return true; } #if defined( PRE_ADD_LOTUSGOLEM ) void CDnPartsMonsterActor::ProcessPartsAI( const std::vector& vData ) { for( UINT i=0 ; i vData[i].iMaxHP ) continue; // CheckAction if( vData[i].strCheckActionName.empty() == false ) { if( strcmp( GetCurrentAction(), vData[i].strCheckActionName.c_str() ) != 0 ) continue; } // CheckSkill if( vData[i].iCheckSkillIndex > 0 ) { if( !GetProcessSkill() ) continue; if( m_hActor->GetProcessSkill()->GetClassID() != vData[i].iCheckSkillIndex ) continue; } // CheckBlow if( vData[i].iCheckBlowIndex > 0 ) { if( m_hActor->GetStateBlow() && m_hActor->GetStateBlow()->IsApplied( static_cast(vData[i].iCheckBlowIndex) ) == false ) continue; } // Ignore for( UINT j=0 ; jSetIgnore( true ); } // NoDamage for( UINT j=0 ; jSetNoDamage( true ); } // Active for( UINT j=0 ; jSetIgnore( false ); pParts->SetNoDamage( false ); } } bPrev = true; } // PartsProcessor °¡ ¾ø´Ù¸é ÆÐŶ º¸³¾ÇÊ¿ä ¾øÀ½ if( vData.empty() ) return; for( UINT i=0 ; iIsScript() ); // ¼¼Æ®ÆÄÃ÷ ºÎȰ MAAiScript* pScript = static_cast(m_pAi); const ScriptData& data = pScript->GetScriptData(); for( std::list>::iterator itor=m_listDestroySetParts.begin() ; itor!=m_listDestroySetParts.end() ; ) { (*itor).second -= fDelta; if( (*itor).second > 0.f ) { ++itor; continue; } UINT uiSetID = (*itor).first; _ASSERT( uiSetID < data.m_vSetPartsRebirthTable.size() ); for( UINT i=0 ; i::iterator itor2=m_listDestroyParts.begin() ; itor2!=m_listDestroyParts.end() ; ) { if( (*itor2)->GetPartsOriginalInfo().uiMonsterPartsTableID == data.m_vSetPartsRebirthTable[uiSetID].vPartsTableID[i] ) { _OnRefreshParts( *itor2 ); itor2 = m_listDestroyParts.erase( itor2 ); break; } ++itor2; } } itor = m_listDestroySetParts.erase( itor ); } // °³º°ÆÄÃ÷ ºÎȰ for( std::list::iterator itor=m_listDestroyParts.begin() ; itor!=m_listDestroyParts.end() ; ) { if( (*itor)->Process( fDelta ) ) { _OnRefreshParts( *itor ); itor = m_listDestroyParts.erase( itor ); } else { ++itor; } } } void CDnPartsMonsterActor::Process( LOCAL_TIME LocalTime, float fDelta ) { _ProcessParts( fDelta ); TDnMonsterActor< MASingleBody, MAMultiDamage >::Process( LocalTime, fDelta ); if( IsNaviMode() && GetNaviType() == MAMovementBase::NaviType::eTarget ) { m_nLastUpdateNaviTime -= static_cast(fDelta*1000.0f); if( m_nLastUpdateNaviTime < 0 ) UpdateNaviMode(); } } void CDnPartsMonsterActor::UpdateNaviMode() { if( !IsNaviMode() ) return; if ( !GetNaviTarget() || GetNaviTarget()->IsDie() ) { ResetNaviMode(); return; } CmdMoveNavi(GetNaviTarget(), GetNaviTargetMinDistance(), GetNaviTargetActionName(), -1); } void CDnPartsMonsterActor::CmdMoveNavi( DnActorHandle hActor, float fMinDistance, const char *szActionName, int nLoopCount, float fBlendFrame ) { TDnMonsterActor< MASingleBody, MAMultiDamage >::CmdMoveNavi( hActor, fMinDistance, szActionName, nLoopCount, fBlendFrame ); if( m_hActor->IsNaviMode() ) m_nLastUpdateNaviTime = g_nNaviUpdateDelta; } void CDnPartsMonsterActor::OnDamage( CDnDamageBase *pHitter, SHitParam &HitParam, HitStruct* pStruct ) { TDnMonsterActor< MASingleBody, MAMultiDamage >::OnDamage(pHitter, HitParam, pStruct ); } float CDnPartsMonsterActor::CalcDamage( CDnDamageBase* pHitter, SHitParam& HitParam ) { float fDamage = PreCalcDamage( pHitter, HitParam ); float fAddDamage = 0.f; bool bBreak = false; for( UINT i=0 ; i 0 && m_Parts[i].CheckPartsState( MonsterParts::eIgnore ) == false ) #else // ÆÄÃ÷°¡ »ì¾ÆÀÖÀ¸¸é... if( m_Parts[i].GetHP() > 0 ) #endif // #if defined( PRE_ADD_LOTUSGOLEM ) { // º»Ã¼ µ¥¹ÌÁö ºñÀ² °è»ê float fMainDamageRate = m_Parts[i].GetMainDamageRate(); fAddDamage += (fDamage*(fMainDamageRate-1.f)); } for( UINT j=0 ; j m_Parts[i].GetPartsInfo().vHitCondition[k].iRequiredPartsUnderHP ) { bHitCondition = false; break; } } } if( bHitCondition == false ) break; } if( bHitCondition == false ) continue; #if defined( PRE_ADD_LOTUSGOLEM ) if( m_Parts[i].CheckPartsState( MonsterParts::eNoDamage ) == true ) return 0.f; if( m_Parts[i].CheckPartsState( MonsterParts::eIgnore ) == true ) { bBreak = true; break; } #endif // #if defined( PRE_ADD_LOTUSGOLEM ) _OnPartsDamage( pHitter, HitParam, m_Parts[i] ); _SendPartsHP( &m_Parts[i], pHitter->GetActorHandle() ? pHitter->GetActorHandle()->GetUniqueID() : 0 ); bBreak = true; break; } } if( bBreak ) break; } #if defined( PRE_ADD_LOTUSGOLEM ) if( static_cast(GetAIBase())->GetScriptData().m_iOnlyPartsDamage > 0 ) { if( bBreak == false ) { // 2¹ø ŸÀÔÀº À¯È¿ÇÑ ÆÄÃ÷°¡ ¾Æ´Ñ°÷Àº Çê¹æÄ¡°Ô ÇÑ´Ù. if( static_cast(GetAIBase())->GetScriptData().m_iOnlyPartsDamage == 2 ) HitParam.bIgnoreShowDamage = true; return 0.f; } } #endif // #if defined( PRE_ADD_LOTUSGOLEM ) fDamage += fAddDamage; if( fDamage <= 0.f ) fDamage = 0.f; SetHP( static_cast(GetHP()-fDamage) ); return fDamage; } bool CDnPartsMonsterActor::IsLimitAction( const char* pszActionName ) { if( m_listDestroyParts.empty() ) return false; for( std::list::iterator itor=m_listDestroyParts.begin() ; itor!=m_listDestroyParts.end() ; ++itor ) { if( (*itor)->IsLimitAction( pszActionName ) ) { //g_Log.LogA( "CDnPartsMonsterActor::IsLimitAction() Action=%s Á¦ÇÑ ¾×¼Ç!\r\n", pszActionName ); return true; } } return false; } bool CDnPartsMonsterActor::IsLimitAction( DnSkillHandle hSkill ) { std::set setLimitAction; for( std::list::iterator itor=m_listDestroyParts.begin() ; itor!=m_listDestroyParts.end() ; ++itor ) { for( size_t i=0 ; i<(*itor)->GetPartsInfo().vLimitAction.size() ; ++i ) setLimitAction.insert( (*itor)->GetPartsInfo().vLimitAction[i] ); } bool bRet = hSkill->IsUseActionNames( setLimitAction ); //if( bRet ) // g_Log.LogA( "CDnPartsMonsterActor::IsLimitAction() SkillID=%d Á¦ÇÑ ¾×¼Ç!\r\n", hSkill->GetClassID() ); return bRet; } bool CDnPartsMonsterActor::bIsDestroyParts( const UINT uiTableID ) { for( std::list::iterator itor=m_listDestroyParts.begin() ; itor!=m_listDestroyParts.end() ; ++itor ) { if( (*itor)->GetPartsInfo().uiMonsterPartsTableID == uiTableID ) return true; } return false; } bool CDnPartsMonsterActor::bIsDestroySetParts( const UINT uiSetID ) { for( std::list>::iterator itor=m_listDestroySetParts.begin() ; itor!=m_listDestroySetParts.end() ; ++itor ) { if( (*itor).first == uiSetID ) return true; } return false; } void CDnPartsMonsterActor::_OnPartsDamage( CDnDamageBase* pHitter, SHitParam& HitParam, MonsterParts& Parts ) { int nCurHP = Parts.GetHP(); if( nCurHP <= 0 ) return; int nPartsDamage = static_cast(PreCalcDamage( pHitter, HitParam, Parts.GetDefenseRate() )); // ÆÄÃ÷ ÆÄ±« if( nCurHP <= nPartsDamage ) { _OnDestroyParts( &Parts ); } else { Parts.SetHP( nCurHP-nPartsDamage ); } } void CDnPartsMonsterActor::_OnRefreshParts( MonsterParts* pParts ) { pParts->SetRefresh( GetActorHandle() ); _SendPartsHP( pParts ); // _PartsHPLink for( UINT i=0 ; iGetPartsInfo().vRebirthPartsTableID.size() ; ++i ) { MonsterParts* pRebirthParts = GetParts( pParts->GetPartsInfo().vRebirthPartsTableID[i] ); if( pRebirthParts ) { if( pRebirthParts->GetHP() <= 0 ) pRebirthParts->ResetDestoryDelta(); else { pRebirthParts->SetHP( pRebirthParts->GetPartsOriginalInfo().nHP ); _SendPartsHP( pRebirthParts ); } } } } void CDnPartsMonsterActor::_OnDestroyParts( MonsterParts* pParts ) { pParts->SetDestroy( GetActorHandle() ); m_listDestroyParts.push_back( pParts ); // ¼¼Æ®ÆÄÃ÷ ÆÄ±« °Ë»ç MAAiScript* pScript = static_cast(m_pAi); const ScriptData& data = pScript->GetScriptData(); for( UINT i=0 ; i(data.m_vSetPartsRebirthTable[i].uiRebirthTick/1000.f) )); } } // ÇöÀç ¾×¼ÇÀÌ LimitActionÀΰæ¿ì DnActorHandle hActor = GetActorHandle(); if( hActor ) { const char* pszAction = hActor->GetCurrentAction(); if( pszAction && strlen( pszAction ) ) { if( pParts->IsLimitAction( pszAction ) ) { //g_Log.LogA( "Á¦ÇÑ ¾×¼ÇÀ̾ ¸ØÃã %s\r\n", pszAction ); hActor->CmdStop( "Stand" ); } //g_Log.LogA( "ÆÄÃ÷ÆÄ±« ¾×¼Ç %s\r\n", pszAction ); } } if( m_pAi ) { // ÆÄÃ÷ ÆÄ±« µÇ¾úÀ» ¶§ ½ºÅ³ »óÅÂÈ¿°ú ¾ø¾Ú bool bDeadAction = false; if( !pParts->GetPartsInfo().szDeadActName.empty() ) { bDeadAction = true; SetActionQueue( pParts->GetPartsInfo().szDeadActName.c_str() ); } DnSkillHandle hSkill = pParts->GetSkillHandle(); if( hSkill ) { AICommand::SRemoveBlowBySkillIndex sCommand; sCommand.iSkillIndex = hSkill->GetClassID(); m_pAi->AICmdMsgProc( AICommand::CMD_REMOVEBLOW_BYSKILLINDEX, &sCommand ); } // ÆÄÃ÷ ÆÄ±« µÇ¾úÀ» ¶§ »ç¿ëÇÒ ½ºÅ³ int iSkillIndex = pParts->GetDestroySkillIndex(); if( iSkillIndex > 0 && bDeadAction == false ) { AICommand::SUseSkill sCommand; sCommand.iSkillIndex = iSkillIndex; m_pAi->AICmdMsgProc( AICommand::CMD_USESKILL, &sCommand ); } } } void CDnPartsMonsterActor::_SendPartsHP( MonsterParts* pParts, UINT uiSessionID/*=0*/ ) { BYTE pBuffer[128]; CPacketCompressStream Stream( pBuffer, 128 ); UINT uiPartsTableID = pParts->GetPartsTableID(); int iHP = pParts->GetHP(); Stream.Write( &uiPartsTableID, sizeof(UINT) ); Stream.Write( &iHP, sizeof(int) ); Stream.Write( &uiSessionID, sizeof(UINT) ); Send( eActor::SC_PARTSDAMAGE, &Stream ); } #if defined(PRE_FIX_59347) void CDnPartsMonsterActor::ApplyPartsDamage(float& fDamage, DnActorHandle hHitterActor) { float fAddDamage = 0.f; std::list activateParts; for( UINT i=0 ; i monsterParts.GetPartsInfo().vHitCondition[k].iRequiredPartsUnderHP ) { bHitCondition = false; break; } } } if( bHitCondition == false ) break; } if( bHitCondition == false ) continue; #if defined( PRE_ADD_LOTUSGOLEM ) if( monsterParts.CheckPartsState( MonsterParts::eNoDamage ) == true ) continue; if( monsterParts.CheckPartsState( MonsterParts::eIgnore ) == true ) continue; #endif activateParts.push_back(&monsterParts); } if( activateParts.empty() == false ) { #ifdef PRE_FIX_67656 float m_fMainDamageRatio = 0.f; std::list::iterator iter = activateParts.begin(); for ( iter = activateParts.begin() ; iter != activateParts.end(); ++iter) { MonsterParts* pMonsterParts = (*iter); if( pMonsterParts ) { int nCurHP = pMonsterParts->GetHP(); if( nCurHP <= 0 ) continue; // ÆÄÃ÷ ÆÄ±« if( nCurHP <= fDamage ) { _OnDestroyParts( pMonsterParts ); } else { pMonsterParts->SetHP( nCurHP - (int)fDamage ); } _SendPartsHP( pMonsterParts, hHitterActor ? hHitterActor->GetUniqueID() : 0 ); if( m_fMainDamageRatio < pMonsterParts->GetMainDamageRate() ) m_fMainDamageRatio = pMonsterParts->GetMainDamageRate(); } } #endif //½ÇÁ¦ ¸ó½ºÅÍ HP´Â °¨¼Ò µÇ¸é ¾ÈµÇ¹Ç·Î fDamage°ªÀº 0.0À¸·Î ¼³Á¤.. #ifdef PRE_FIX_67656 fDamage = fDamage * m_fMainDamageRatio; #else fDamage = 0.f; #endif } } #endif // PRE_FIX_59347 #if defined(PRE_FIX_66687) void CDnPartsMonsterActor::ApplyPartsHP(float fRate) { for( UINT i=0 ; i