#include "StdAfx.h" #include "MAAiChecker.h" #include "DnActor.h" #include "MAAiScript.h" #include "DnBlow.h" #include "DNAggroSystem.h" #include "DnMonsterActor.h" #include "DnStateBlow.h" #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif /*##################################################################################################################### ActorChecker #####################################################################################################################*/ // ¹«±â°Ë»ç // ¹«±â°¡ ÀÖÀ¸¸é return true, ¹«±â°¡ ¾øÀ¸¸é return false; bool CMAAiActorWeaponChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor ) return false; return hActor->GetWeapon(m_uiWeaponIndex) ? true : false; } // ºÎÀ§ÆÄ±«°Ë»ç // ÇØ´çºÎÀ§ ÆÄ±« µÇ¾úÀ¸¸é return true; ¾Æ´Ï¸é return false; bool CMAAiActorPartsDestroyChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor ) return false; for( UINT i=0 ; ibIsDestroyParts(m_vPartsTableID[i]) ) return false; } return true; } // ºÎÀ§Á¸Àç°Ë»ç // ÇØ´çºÎÀ§ Á¸ÀçÇϸé return true; ¾Æ´Ï¸é return false; bool CMAAiActorPartsExistChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor ) return false; for( UINT i=0 ; ibIsDestroyParts(m_vPartsTableID[i]) ) return false; } return true; } // Fly»óŰ˻ç bool CMAAiActorFlyStateChecker::bIsCheck( DnActorHandle hActor, int iParam ) { return (hActor->IsFly()&&!hActor->IsFly2()); } bool CMAAiActorFly2StateChecker::bIsCheck( DnActorHandle hActor, int iParam ) { return hActor->IsFly2(); } // Ground»óŰ˻ç bool CMAAiActorGroundStateChecker::bIsCheck( DnActorHandle hActor, int iParam ) { return hActor->IsGround(); } // UnderGround»óŰ˻ç bool CMAAiActorUnderGroundStateChecker::bIsCheck( DnActorHandle hActor, int iParam ) { return hActor->IsUnderGround(); } // HPPercent °Ë»ç bool CMAAiActorHPPercentChecker::bIsCheck( DnActorHandle hActor, int iParam ) { return m_iHPPercent >= hActor->GetHPPercent(); } // HPPercent Range°Ë»ç(MinÀÌ»ó~MaxÀÌÇÏ) bool CMAAiActorHPPercentCheckerRange::bIsCheck( DnActorHandle hActor, int iParam ) { int iHPPercent = hActor->GetHPPercent(); return (iHPPercent >= m_iHPMinPercent && iHPPercent <= m_iHPMaxPercent); } // SP°Ë»ç bool CMAAiActorSPChecker::bIsCheck( DnActorHandle hActor, int iParam ) { return m_iSP <= hActor->GetSP(); } // ÇöÀç »ç¿ëÁßÀÎ ½ºÅ³ üũ bool CMAAiActorUsedSkillChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor->GetStateBlow() ) return false; std::vector vCheckTableID = m_vSkillTableID; for( int i=0 ; iGetStateBlow()->GetNumStateBlow() ; ++i ) { DnBlowHandle hBlow = hActor->GetStateBlow()->GetStateBlow(i); if( !hBlow ) continue; const CDnSkill::SkillInfo* pSkillinfo = hBlow->GetParentSkillInfo(); if ( pSkillinfo ) { vCheckTableID.erase( remove( vCheckTableID.begin(), vCheckTableID.end(), pSkillinfo->iSkillID), vCheckTableID.end() ); if( vCheckTableID.empty() ) return true; } } return false; } // ÇöÀç »ç¿ëÁßÀÌÁö ¾ÊÀº ½ºÅ³ üũ bool CMAAiActorNotUsedSkillChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor->GetStateBlow() ) return true; for( int i=0 ; iGetStateBlow()->GetNumStateBlow() ; ++i ) { DnBlowHandle hBlow = hActor->GetStateBlow()->GetStateBlow(i); if( !hBlow ) continue; const CDnSkill::SkillInfo* pSkillinfo = hBlow->GetParentSkillInfo(); if ( pSkillinfo ) { if( std::find( m_vSkillTableID.begin(), m_vSkillTableID.end(), pSkillinfo->iSkillID ) != m_vSkillTableID.end() ) return false; } } return true; } // rate bool CMAAiActorSkillRateChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( m_iRate < (_rand(hActor->GetRoom())%100) ) return false; return true; } // LimitCount bool CMAAiActorSkillLimitCountChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( hActor->IsMonsterActor() ) { CDnMonsterActor* pMonsterActor = static_cast(hActor.GetPointer()); if( pMonsterActor->GetUseSkillCount( iParam ) < m_iLimitCount ) return true; } return false; } bool CMAAiActorEncounterTickChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor || !hActor->GetAggroSystem() ) return false; bool bIsProvocationTarget; DnActorHandle hTarget = hActor->GetAggroSystem()->OnGetAggroTarget( bIsProvocationTarget ); if( !hTarget ) return false; if( static_cast(timeGetTime()-hActor->GetGenTick()) >= m_iCheckTick ) return true; return false; } bool CMAAiActorLimitTickChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor ) return false; if( static_cast(timeGetTime()-hActor->GetGenTick()) >= m_iCheckTick ) return false; return true; } bool CMAAiActorNotifyAnnounceChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor || !hActor->IsMonsterActor() ) return false; CDnMonsterActor* pMonster = static_cast(hActor.GetPointer()); bool bNotify = pMonster->GetAIBase()->bIsNotifyDieAnnounce( m_iTickGap ); if( !bNotify ) return false; pMonster->GetAIBase()->ResetNotifyDieAnnounce(); if( m_iRate > (_rand(hActor->GetRoom())%100) ) return true; return false; } bool CMAAiActorGlobalCoolTimeChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor || !hActor->IsMonsterActor() ) return false; CDnMonsterActor* pMonster = static_cast(hActor.GetPointer()); MAAiScript* pScript = static_cast(pMonster->GetAIBase()); if( m_iCoolTimeIndex >= static_cast(pScript->GetScriptData().m_AIGlobalCoolTime.size()) ) { _ASSERT(0); return false; } DWORD dwRet = pScript->m_GlobalCoolTime.Update( m_iCoolTimeIndex, timeGetTime() ); return ( dwRet == 0 ); } bool CMAAiActorNoAggroChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor || !hActor->IsMonsterActor() ) return false; CDnMonsterActor* pMonster = static_cast(hActor.GetPointer()); DnActorHandle hTarget = pMonster->GetAIBase()->GetTarget(); return hTarget ? false : true; } bool CMAAiActorWaitOrderChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( !hActor || !hActor->IsMonsterActor() ) return false; CDnMonsterActor* pMonster = static_cast(hActor.GetPointer()); MAAiScript* pScript = static_cast(pMonster->GetAIBase()); int iSkillIndex = pScript->GetMonsterSkillAI()->GetSkillIndexFromLuaSkillIndex( iParam ); return pMonster->GetWaitOrderCount( iSkillIndex ) > 0; } // SkillToggle bool CMAAiActorSkillToggleChecker::bIsCheck( DnActorHandle hActor, int iParam ) { if( hActor->IsMonsterActor() == false ) return false; CDnMonsterActor* pMonster = static_cast(hActor.GetPointer()); DnActorHandle hSummoner = pMonster->GetSummonerPlayerActor(); if( !hSummoner ) return false; MAAiScript* pScript = static_cast(pMonster->GetAIBase()); int iSkillIndex = pScript->GetMonsterSkillAI()->GetSkillIndexFromLuaSkillIndex( iParam ); DnSkillHandle hMonsterSkill = pMonster->FindSkill( iSkillIndex ); if( !hMonsterSkill ) return false; DnSkillHandle hSkill = hSummoner->FindSkill( m_iSkillID ); if( !hSkill ) return false; //RLKT FIX Alfredo if( hSkill->GetDurationType() == CDnSkill::ActiveToggleForSummon && hSkill->IsToggleOn() == true && m_iSkillLevel == -1 ) { if( hSummoner->GetSP() >= hSkill->GetDecreaseMP() ) { #if defined( PRE_ADD_ACADEMIC ) hMonsterSkill->SetSummonerDecreaseSP( m_iSkillID, hSkill->GetDecreaseMP() ); #endif // #if defined( PRE_ADD_ACADEMIC ) return true; } } if( hSkill->GetDurationType() == CDnSkill::ActiveToggleForSummon && hSkill->IsToggleOn() == true && hSkill->GetLevel() == m_iSkillLevel ) { if( hSummoner->GetSP() >= hSkill->GetDecreaseMP() ) { #if defined( PRE_ADD_ACADEMIC ) hMonsterSkill->SetSummonerDecreaseSP( m_iSkillID, hSkill->GetDecreaseMP() ); #endif // #if defined( PRE_ADD_ACADEMIC ) return true; } } return false; } // PassiveSkill bool CMAAiActorPassiveSkillChecker::bIsCheck( DnActorHandle hActor, int iParam ) { CDnMonsterActor* pMonster = static_cast(hActor.GetPointer()); DnActorHandle hSummoner = pMonster->GetSummonerPlayerActor(); if( !hSummoner ) return false; DnSkillHandle hSkill = hSummoner->FindSkill( m_iSkillID ); if( !hSkill ) return false; //RLKT FIX if( (hSkill->GetSkillType() == CDnSkill::Passive || hSkill->GetSkillType() == CDnSkill::EnchantPassive) && m_iSkillLevel == -1) return true; if( (hSkill->GetSkillType() == CDnSkill::Passive || hSkill->GetSkillType() == CDnSkill::EnchantPassive) && hSkill->GetLevel() == m_iSkillLevel ) return true; return false; } /*##################################################################################################################### TargetActorChecker #####################################################################################################################*/ int CMAAiTargetActorChecker::GetTargetDegree( DnActorHandle hActor, DnActorHandle hTarget, const EtVector3& AxisVector ) { EtVector3 vec = *hActor->GetPosition() - *hTarget->GetPosition(); vec.y = 0.f; EtVec3Normalize( &vec, &vec ); float fDot = EtVec3Dot( &vec, &AxisVector ); return static_cast(EtToDegree( acosf( min( fDot, 1.0f) ) )); } // LF bool CMAAi_LF_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); if( iDegree >= 135 && iDegree2 <= 90 ) return true; return false; } // LB bool CMAAi_LB_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); if( iDegree >= 135 && iDegree2 >= 90 ) return true; return false; } // FL bool CMAAi_FL_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); if( iDegree <= 45 && iDegree2 >= 90 ) return true; return false; } // FR bool CMAAi_FR_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); if( iDegree <= 45 && iDegree2 <= 90 ) return true; return false; } // RF bool CMAAi_RF_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); if( iDegree <= 45 && iDegree2 <= 90 ) return true; return false; } // RB bool CMAAi_RB_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); if( iDegree <= 45 && iDegree2 >= 90 ) return true; return false; } // BR bool CMAAi_BR_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); if( iDegree >= 135 && iDegree2 <= 90 ) return true; return false; } // BL bool CMAAi_BL_DirectionChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { int iDegree = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vZAxis) ); int iDegree2 = GetTargetDegree( hActor, hTarget, -(hActor->GetMatEx()->m_vXAxis) ); if( iDegree >= 135 && iDegree2 >= 90 ) return true; return false; } // TargetHPPercent bool CMAAiTargetActorHPPercentChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { return m_iHPPercent >= hTarget->GetHPPercent(); } // TargetBuff bool CMAAiTargetActorBuffChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { for( int i=0 ; iGetNumAppliedStateBlow() ; ++i ) { DnBlowHandle hBlow = hTarget->GetAppliedStateBlow( i ); if( hBlow ) { const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo(); if( !pSkillInfo ) continue; if( pSkillInfo->eDurationType == CDnSkill::DurationTypeEnum::Buff ) return true; } } return false; } // TargetDeBuff bool CMAAiTargetActorDeBuffChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { for( int i=0 ; iGetNumAppliedStateBlow() ; ++i ) { DnBlowHandle hBlow = hTarget->GetAppliedStateBlow( i ); if( hBlow ) { const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo(); if( !pSkillInfo ) continue; if( pSkillInfo->eDurationType == CDnSkill::DurationTypeEnum::Debuff ) return true; } } return false; } // Blow bool CMAAiTargetActorBlowChecker::bIsCheck( DnActorHandle hActor, DnActorHandle hTarget ) { for( UINT i=0 ; i ´ë»óÀÌ ÇØ´ç »óÅÂÈ¿°ú¿¡ °É·ÁÀÖÀ¸¸é ½ºÅ³À» »ç¿ëÇÏÁö ¾Ê´Â´Ù. // m_bIsNoBlowCheck == false ÀÎ °æ¿ì => ´ë»óÀÌ ÇØ´ç »óÅÂÈ¿°ú¿¡ °É·ÁÀÖÁö ¾ÊÀ¸¸é ½ºÅ³À» »ç¿ëÇÏÁö ¾Ê´Â´Ù. if( hTarget->IsAppliedThisStateBlow( static_cast(m_vTableID[i]) ) == m_bIsNoBlowCheck ) return false; } return true; } /*##################################################################################################################### CheckerManager #####################################################################################################################*/ CMAAiCheckerManager::~CMAAiCheckerManager() { SAFE_DELETE_PVEC( m_vTargetActorChecker ); SAFE_DELETE_PVEC( m_vTargetActorDirectionChecker ); SAFE_DELETE_PVEC( m_vActorChecker ); } bool CMAAiCheckerManager::bIsActorChecker( DnActorHandle hActor, int iParam/*=0*/ ) const { for( UINT i=0 ; ibIsRateChecker() ) continue; } if( !m_vActorChecker[i]->bIsCheck( hActor, iParam ) ) return false; } return true; } bool CMAAiCheckerManager::bIsTargetActorChecker( DnActorHandle hActor, DnActorHandle hTarget ) const { if( !hTarget ) return false; // TargetDirection üũ if( !m_vTargetActorDirectionChecker.empty() ) { bool bOK = false; for( UINT i=0 ; ibIsCheck( hActor, hTarget ) ) { bOK = true; break; } } if( !bOK ) return false; } // Target üũ for( UINT i=0 ; ibIsCheck( hActor, hTarget ) ) return false; } return true; } bool CMAAiCheckerManager::bLoadChecker( lua_tinker::table& t ) { // ¹«±âüũ switch( t.get("checkweapon") ) { case 1: { m_vActorChecker.push_back( new CMAAiActorWeaponChecker( 0 ) ); break; } case 2: { m_vActorChecker.push_back( new CMAAiActorWeaponChecker( 1 ) ); break; } } // ºÎÀ§ÆÄ±« const char* pszDestroyParts = t.get("destroyparts" ); if( pszDestroyParts ) { std::string strString(pszDestroyParts); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("existparts" ); if( pszExistParts ) { std::string strString(pszExistParts); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("td"); if( pszTD ) { std::string strString(pszTD); std::vector vSplit; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i(szBuf); if( pszState ) { if( stricmp( pszState, "custom_fly" ) == 0 ) m_vActorChecker.push_back( new CMAAiActorFlyStateChecker() ); else if( stricmp( pszState, "custom_ground" ) == 0 ) m_vActorChecker.push_back( new CMAAiActorGroundStateChecker() ); else if( stricmp( pszState, "custom_underground" ) == 0 ) m_vActorChecker.push_back( new CMAAiActorUnderGroundStateChecker() ); else if( stricmp( pszState, "custom_fly2" ) == 0 ) m_vActorChecker.push_back( new CMAAiActorFly2StateChecker() ); } } // selfhppercent int iHPPercent = t.get("selfhppercent"); if( iHPPercent > 0 ) // ÀԷµǾî ÀÖÀ¸¸é Checker »ý¼º m_vActorChecker.push_back( new CMAAiActorHPPercentChecker(iHPPercent) ); // selfhppercentrange const char* pszHPPercentRange = t.get("selfhppercentrange"); if( pszHPPercentRange ) { std::string strString(pszHPPercentRange); std::vector vSplit; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); if( vSplit.size() != 2 ) return false; boost::trim( vSplit[0]); boost::trim( vSplit[1]); int iMin = boost::lexical_cast( vSplit[0] ); int iMax = boost::lexical_cast( vSplit[1] ); if( iMin<0 || iMax<0 || iMin > iMax ) return false; m_vActorChecker.push_back( new CMAAiActorHPPercentCheckerRange(iMin,iMax) ); } // targethppercent int iTargetHPPercent = t.get("hppercent"); if( iTargetHPPercent > 0 ) m_vTargetActorChecker.push_back( new CMAAiTargetActorHPPercentChecker( iTargetHPPercent ) ); // SP int iSP = t.get("sp"); if( iSP > 0 ) m_vActorChecker.push_back( new CMAAiActorSPChecker(iSP) ); // Buff int iBuffCheck = t.get("buffcheck"); if( iBuffCheck > 0 ) m_vTargetActorChecker.push_back( new CMAAiTargetActorBuffChecker() ); // DeBuff int iDeBuffCheck = t.get("debuffcheck"); if( iDeBuffCheck > 0 ) m_vTargetActorChecker.push_back( new CMAAiTargetActorDeBuffChecker() ); // BlowCheck const char* pszBlowCheck = t.get("blowcheck"); if( pszBlowCheck ) { std::string strString(pszBlowCheck); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("noblowcheck"); if( pszNoBlowCheck ) { std::string strString(pszNoBlowCheck); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("usedskill"); if( pszUsedSkill ) { std::string strString(pszUsedSkill); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("notusedskill"); if( pszNotUsedSkill ) { std::string strString(pszNotUsedSkill); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("encountertime"); if( iEnCounterTime > 0 ) m_vActorChecker.push_back( new CMAAiActorEncounterTickChecker( iEnCounterTime ) ); // limittime int iLimitTime = t.get("limittime"); if( iLimitTime > 0 ) m_vActorChecker.push_back( new CMAAiActorLimitTickChecker( iLimitTime ) ); // DieAnnounce const char* pszAnnounce = t.get("announce"); if( pszAnnounce ) { std::string strString(pszAnnounce); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("globalcooltime"); if( iGlobalCoolTimeIndex > 0 ) m_vActorChecker.push_back( new CMAAiActorGlobalCoolTimeChecker(iGlobalCoolTimeIndex-1) ); for( int i=1 ; i(szBuf); if( nGlobalCoolTimeIndex > 0 ) m_vActorChecker.push_back( new CMAAiActorGlobalCoolTimeChecker(nGlobalCoolTimeIndex-1) ); else break; } #else int iGlobalCoolTimeIndex = t.get("globalcooltime"); if( iGlobalCoolTimeIndex > 0 ) m_vActorChecker.push_back( new CMAAiActorGlobalCoolTimeChecker(iGlobalCoolTimeIndex-1) ); #endif // noaggro int iNoAggro = t.get("noaggro"); if( iEnCounterTime > 0 ) m_vActorChecker.push_back( new CMAAiActorEncounterTickChecker( iEnCounterTime ) ); // checkpassiveskill const char* pszCheckPassiveSkill = t.get("checkpassiveskill"); if( pszCheckPassiveSkill ) { std::string strString(pszCheckPassiveSkill); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; i("rate"); // ½ºÅ³ÂÊ¿¡¼­ rate °ªÀ» ÀÔ·ÂÇÏÁö ¾Ê¾ÒÀ» °æ¿ì DefaultValue ´Â 100% ÀÌ´Ù. if( iRate == 0 ) iRate = 100; m_vActorChecker.push_back( new CMAAiActorSkillRateChecker( iRate ) ); int iLimitCount = t.get("limitcount"); if( iLimitCount > 0 ) m_vActorChecker.push_back( new CMAAiActorSkillLimitCountChecker( iLimitCount ) ); int iWaitOrder = t.get("waitorder"); if( iWaitOrder > 0 ) m_vActorChecker.push_back( new CMAAiActorWaitOrderChecker(iWaitOrder) ); // checkskilltoggle const char* pszCheckSkillToggle = t.get("checkskilltoggle"); if( pszCheckSkillToggle ) { std::string strString(pszCheckSkillToggle); std::vector vSplit; std::vector vTableID; boost::algorithm::split( vSplit, strString, boost::algorithm::is_any_of(",") ); for( UINT i=0 ; ibIsAnnounceSkill() ) return true; } return false; }