#include "StdAfx.h" #include "DnProbInvincibleAtBlow.h" #include "DnProjectile.h" #ifdef _GAMESERVER #include "DnMonsterActor.h" #include "DnProjectile.h" #else #include "DnStateBlow.h" #endif // #ifdef _GAMESERVER #if !defined( USE_BOOST_MEMPOOL ) #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif #endif // #if !defined( USE_BOOST_MEMPOOL ) CDnProbInvincibleAtBlow::CDnProbInvincibleAtBlow( DnActorHandle hActor, const char* szValue ) : CDnBlow( hActor ) { m_StateBlow.emBlowIndex = STATE_BLOW::BLOW_226; SetValue( szValue ); #ifdef _GAMESERVER AddCallBackType( SB_ONCALCDAMAGE ); AddInvincibleAt(szValue); m_pNowMapSelectedSkillInfos = NULL; m_bNowSelectedSkillUsedProjectile = false; #else m_pEffectOutputInfo = CDnStateBlow::GetEffectOutputInfo( 100 ); // StateEffectTable ¿¡ ±Ù¿ø ¾ÆÀÌÅÛÀÇ »óÅÂÈ¿°ú´Â 100 À¸·Î ÁöÁ¤µÊ. #endif // #ifdef _GAMESERVER m_fValue = 0.0f; } CDnProbInvincibleAtBlow::~CDnProbInvincibleAtBlow(void) { } void CDnProbInvincibleAtBlow::OnBegin( LOCAL_TIME LocalTime, float fDelta ) { OutputDebug( "%s\n", __FUNCTION__); } void CDnProbInvincibleAtBlow::Process( LOCAL_TIME LocalTime, float fDelta ) { __super::Process( LocalTime, fDelta ); #ifdef _GAMESERVER CheckAllTargetSkillState(); CheckProbFailedSkillState(); #endif // #ifdef _GAMESERVER } void CDnProbInvincibleAtBlow::OnEnd( LOCAL_TIME LocalTime, float fDelta ) { OutputDebug( "%s\n", __FUNCTION__); } #ifdef _GAMESERVER void CDnProbInvincibleAtBlow::AddInvincibleAt(const char* szValue) { string str = szValue; vector vlTokens; string delimiters = ";"; // ȸÇÇ´ë»ó ¸ó½ºÅÍ ID;[ȸÇÇ ´ë»ó ½ºÅ³ ID1][ȸÇÇ ´ë»ó ½ºÅ³ È®·ü1][ȸÇÇ ´ë»ó ½ºÅ³ ID2][ȸÇÇ ´ë»ó ½ºÅ³ È®·ü2];... TokenizeA( str, vlTokens, delimiters ); _ASSERT( vlTokens.size()%2 == 0 ); for( int i = 0; i < (int)vlTokens.size(); i += 2 ) { int iMonsterID = atoi( vlTokens.at(i).c_str() ); S_INVINCIBLE_INFO& Info = m_mapInvincibleAt[ iMonsterID ]; // ¸ó½ºÅÍ ID ¸¦ Áߺ¹À¸·Î ½áµµ µÇ°Ô ÇØ´Þ¶ó´Â ¿äûÀ¸·Î.. Info.iMonsterID = iMonsterID; vector vlSkillInfos; TokenizeA( vlTokens.at(i+1), vlSkillInfos, string("["), string("]"), false ); for( int k = 0; k < (int)vlSkillInfos.size(); k += 2 ) { int iSkillID = atoi( vlSkillInfos.at( k ).c_str() ); float fProb = (float)atof( vlSkillInfos.at( k+1 ).c_str() ) * 100.0f; Info.mapSkillInfos.insert( make_pair(iSkillID, fProb) ); } } } void CDnProbInvincibleAtBlow::BeginInvincibleAt( DnSkillHandle hTargetSkill ) { if( !hTargetSkill ) return; int iSkillID = hTargetSkill->GetClassID(); if( false == IsBeginInvincible(iSkillID) ) { int iSkillID = hTargetSkill->GetClassID(); if( 0 < m_pNowMapSelectedSkillInfos->count( iSkillID ) ) { // È®·ü üũ. int iProb = int((*m_pNowMapSelectedSkillInfos)[ iSkillID ] * 100.0f); if( _rand(m_hActor->GetRoom()) % 10000 <= iProb ) { // ÀÌ ½ºÅ³ ´ë»óÀ¸·Î ¹«½Ã ½ÃÀÛ. //m_hTargetSkill = hTargetSkill; S_SKILL_INFO TargetSkillInfo; TargetSkillInfo.hTargetSkill = hTargetSkill; TargetSkillInfo.bTargetSkillUsedProjectile = m_bNowSelectedSkillUsedProjectile; m_mapTargetSkillUsedProjectile[ iSkillID ] = m_bNowSelectedSkillUsedProjectile; m_listTargetSkills.push_back( TargetSkillInfo ); } else { // È®·ü üũ¿¡ ½ÇÆÐÇϸé ÇØ´ç ½ºÅ³ÀÌ Á¾·áµÇ±â Àü±îÁø ´Ù½Ã È®·ü üũÇÏÁö ¾Ê´Â´Ù. m_mapTargetSkillUsedProjectile[ iSkillID ] = m_bNowSelectedSkillUsedProjectile; m_dqProbInvincibleFailedSkills.push_back( hTargetSkill ); } } } } void CDnProbInvincibleAtBlow::EndInvincibleAt( DnSkillHandle hTargetSkill ) { if( !hTargetSkill ) return; for( list::iterator iter = m_listTargetSkills.begin(); m_listTargetSkills.end() != iter; ) { S_SKILL_INFO& TargetSkillInfo = (*iter); if( (!TargetSkillInfo.hTargetSkill) || (TargetSkillInfo.hTargetSkill == hTargetSkill) ) { m_mapTargetSkillUsedProjectile.erase( hTargetSkill->GetClassID() ); iter = m_listTargetSkills.erase( iter ); } else { ++iter; } } } bool CDnProbInvincibleAtBlow::IsBeginInvincible( int iSkillID ) { bool bResult = false; bResult = (FindInvincibleTargetSkill(iSkillID) != NULL); return bResult; } CDnProbInvincibleAtBlow::S_SKILL_INFO* CDnProbInvincibleAtBlow::FindInvincibleTargetSkill( int iSkillID ) { S_SKILL_INFO* pResult = NULL; for( list::iterator iter = m_listTargetSkills.begin(); m_listTargetSkills.end() != iter; ) { S_SKILL_INFO& TargetSkillInfo = (*iter); if( TargetSkillInfo.hTargetSkill && TargetSkillInfo.hTargetSkill->GetClassID() == iSkillID ) { pResult = &TargetSkillInfo; break; } else if( !TargetSkillInfo.hTargetSkill ) { m_mapTargetSkillUsedProjectile.erase( iSkillID ); iter = m_listTargetSkills.erase( iter ); continue; } ++iter; } return pResult; } bool CDnProbInvincibleAtBlow::IsInvincibleAt( DnSkillHandle hTargetSkill ) { if( NULL == m_pNowMapSelectedSkillInfos ) return false; if( !hTargetSkill ) return false; bool bResult = false; int iSkillID = hTargetSkill->GetClassID(); if( false == IsProbFailedSkillObject( hTargetSkill ) ) { CheckTargetSkillStateAndDoEnd( hTargetSkill ); if( false == IsBeginInvincible( iSkillID ) ) BeginInvincibleAt( hTargetSkill ); S_SKILL_INFO* pResult = FindInvincibleTargetSkill( iSkillID ); if( pResult ) { if( pResult->hTargetSkill == hTargetSkill ) bResult = true; } } return bResult; } bool CDnProbInvincibleAtBlow::IsProbFailedSkillObject( DnSkillHandle hSkill ) { bool bResult = false; // Çѹø È®·ü Ã¼Å©ÇØ¼­ ½ÇÆÐÇÑ ½ºÅ³Àº ÇØ´ç ½ºÅ³ÀÌ Á¾·áµÉ ¶§ ±îÁö ¹«Àû ¿©ºÎ È®·ü üũ¸¦ ´Ù½Ã ÇÏÁö ¾Ê´Â´Ù. deque::iterator iter = find( m_dqProbInvincibleFailedSkills.begin(), m_dqProbInvincibleFailedSkills.end(), hSkill ); if( iter != m_dqProbInvincibleFailedSkills.end() ) { if( IsSkillFinished( hSkill ) ) { m_dqProbInvincibleFailedSkills.erase( iter ); } else { bResult = true; } } return bResult; } void CDnProbInvincibleAtBlow::CheckAllTargetSkillState( void ) { vector vlhEndedTargetSkills; GatherEndTargetState( vlhEndedTargetSkills ); for( int i = 0; i < (int)vlhEndedTargetSkills.size(); ++i ) { EndInvincibleAt( vlhEndedTargetSkills.at( i ) ); } } void CDnProbInvincibleAtBlow::GatherEndTargetState( /*IN OUT*/ vector& vlhEndedTargetSkill ) { for( list::iterator iter = m_listTargetSkills.begin(); m_listTargetSkills.end() != iter; ++iter ) { if( IsSkillFinished(iter->hTargetSkill) ) { vlhEndedTargetSkill.push_back( iter->hTargetSkill ); } } } void CDnProbInvincibleAtBlow::CheckTargetSkillStateAndDoEnd( DnSkillHandle hTargetSkill ) { if( !hTargetSkill ) return; if( IsSkillFinished( hTargetSkill ) ) { EndInvincibleAt( hTargetSkill ); } } void CDnProbInvincibleAtBlow::CheckProbFailedSkillState( void ) { deque::iterator iter = m_dqProbInvincibleFailedSkills.begin(); for( iter; iter != m_dqProbInvincibleFailedSkills.end(); ) { if( IsSkillFinished( *iter ) ) { iter = m_dqProbInvincibleFailedSkills.erase( iter ); } else { ++iter; } } } bool CDnProbInvincibleAtBlow::IsSkillFinished( DnSkillHandle hSkill ) { bool bResult = false; if( hSkill && hSkill->GetActor() && hSkill->GetActor()->IsMonsterActor() ) { bool bSkillObjectFinished = hSkill->IsFinished(); bResult = bSkillObjectFinished; bool bSkillProjectileExist = false; bool bTargetSkillUsedProjectile = false; map::iterator iter = m_mapTargetSkillUsedProjectile.find( hSkill->GetClassID() ); if( m_mapTargetSkillUsedProjectile.end() != iter ) { bTargetSkillUsedProjectile = iter->second; } if( bTargetSkillUsedProjectile) { // ½ºÅ³ °´Ã¼´Â ³¡³µ´õ¶óµµ ½ºÅ³·Î ½ú´ø ¹ß»çü°¡ ³²¾ÆÀÖ´ÂÁö È®ÀÎ... ¸ðµÎ È®ÀÎÇÏ´Â ¼ö ¹Û¿£ ¾øÀ½. bResult = false; for( int i = 0; i < CDnWeapon::GetItemCount( m_hActor->GetRoom() ); ++i ) { DnWeaponHandle hWeapon = CDnWeapon::GetItem( m_hActor->GetRoom(), i ); if( hWeapon && CDnWeapon::Projectile == hWeapon->GetWeaponType() ) { CDnProjectile* pProjectile = static_cast(hWeapon.GetPointer()); DnSkillHandle hSkillFromProjectile = pProjectile->GetParentSkill(); if( hSkillFromProjectile && hSkillFromProjectile->GetClassID() == hSkill->GetClassID() ) { if( hSkillFromProjectile->GetActor()->IsMonsterActor() ) { CDnMonsterActor* pSkillUserMonsterActor = static_cast(hSkill->GetActor().GetPointer()); CDnMonsterActor* pNowMonsterActor = static_cast(hSkillFromProjectile->GetActor().GetPointer()); if( pNowMonsterActor->GetMonsterClassID() == pSkillUserMonsterActor->GetMonsterClassID() ) { bSkillProjectileExist = true; break; } } } } } bResult = (bSkillObjectFinished && !bSkillProjectileExist); } } return bResult; } bool CDnProbInvincibleAtBlow::CanAddThisSkillsStateBlow( int iSkillID ) { bool bResult = true; //if( IsBeginInvincible() ) S_SKILL_INFO* pResult = FindInvincibleTargetSkill( iSkillID ); if( pResult ) { if( iSkillID == pResult->hTargetSkill->GetClassID() ) bResult = false; } return bResult; } float CDnProbInvincibleAtBlow::OnCalcDamage( float fOriginalDamage, CDnDamageBase::SHitParam& HitParam ) { float fResult = 0.0f; if( HitParam.hHitter || HitParam.hWeapon ) { DnSkillHandle hHitterSkill; bool bSkillUseProjectile = false; if( HitParam.hWeapon && CDnWeapon::Projectile == HitParam.hWeapon->GetWeaponType() ) { CDnProjectile* pProjectile = static_cast( HitParam.hWeapon.GetPointer() ); hHitterSkill = pProjectile->GetParentSkill(); bSkillUseProjectile = true; } else if( HitParam.hHitter ) { hHitterSkill = HitParam.hHitter->GetProcessSkill(); } if( hHitterSkill ) { // ¸ó½ºÅÍ ID ¸¦ ±¸ºÐÇØ´Þ¶ó°í ÇØ¼­ ¸ó½ºÅÍÀÎ °æ¿ì¸¸ Àû¿ëµÇµµ·Ï ÇÑ´Ù.. DnActorHandle hSkillUser = hHitterSkill->GetActor(); if( hSkillUser && hSkillUser->IsMonsterActor() ) { int iMonsterID = static_cast(hSkillUser.GetPointer())->GetMonsterClassID(); map::iterator iter = m_mapInvincibleAt.find( iMonsterID ); if( m_mapInvincibleAt.end() != iter ) { if( bSkillUseProjectile ) { m_bNowSelectedSkillUsedProjectile = true; // #46112 óÀ½¿£ hit ½Ã±×³Î·Î Á÷Á¢ ¶§¸®´Ù°¡ ÃßÈÄ¿¡ ¹ß»çü¸¦ ±ò¾Æ³õ´Â °æ¿ìµµ Àֱ⠶§¹®¿¡ ÇöÀç ¹ß»çü·Î È÷Æ® µÈ °ÍÀÎÁö ¿©ºÎ¿¡ µû¶ó ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù. m_mapTargetSkillUsedProjectile[ hHitterSkill->GetClassID() ] = true; } m_pNowMapSelectedSkillInfos = &((iter->second).mapSkillInfos); bool bInvincible = IsInvincibleAt( hHitterSkill ); if( bInvincible ) { fResult = -fOriginalDamage; m_hActor->SendProbInvincibleSuccess(); // Ŭ¶ó·Î µ¥¹ÌÁö ¹«È¿È­ ¼º°øÇß´Ù°í ÆÐŶ º¸³¿. } m_pNowMapSelectedSkillInfos = NULL; m_bNowSelectedSkillUsedProjectile = false; } } } } return fResult; } #else void CDnProbInvincibleAtBlow::OnSuccess( void ) { if( m_hEtcObjectEffect ) { m_hEtcObjectEffect->SetActionQueue( "Activate" ); } } #endif // #ifdef _GAMESERVER //#if defined(PRE_ADD_PREFIX_SYSTE_RENEW) //void CDnProbInvincibleAtBlow::AddStateEffectValue(const char* szOrigValue, const char* szAddValue, std::string& szNewValue) //{ // char szBuff[128] = {0, }; // // szNewValue = szOrigValue; // //szOrigValue ¸¶Áö¸·¿¡ ";"°¡ ¾øÀ¸¸é Ãß°¡ ÇØ¼­ szAddValue¸¦ Ãß°¡ ÇÑ´Ù. // int nLength = (int)strlen(szOrigValue); // // if (nLength == 0 || szOrigValue[nLength - 1] == ';') // szNewValue += szAddValue; // else // { // szNewValue += ";"; // szNewValue += szAddValue; // } //} // //void CDnProbInvincibleAtBlow::RemoveStateEffectValue(const char* szOrigValue, const char* szAddValue, std::string& szNewValue) //{ // char szBuff[128] = {0, }; // // //"###;###;###;###;....;##;##;##" // //|<--ÀÌÀü ¹®ÀÚ¿­----->|<-AddValue->| // // //szOrigValue¿¡¼­ szAddValue ¹®ÀÚ¿­±æÀÌ ¸¸Å­ µÚ¿¡¼­ ÀÚ¸¥´Ù. // int nOrigLength = (int)strlen(szOrigValue); // int nAddLength = (int)strlen(szAddValue); // int nCount = nOrigLength - nAddLength; // // sprintf_s(szBuff, "%s", szOrigValue); // szBuff[nCount] = 0; // // szNewValue = szBuff; //} //#endif // PRE_ADD_PREFIX_SYSTE_RENEW