DragonNest/Server/DNGameServer/MAAiBase.cpp

321 lines
6.9 KiB
C++
Raw Permalink Normal View History

#include "StdAfx.h"
#include "MAAiBase.h"
#include "DnTableDB.h"
#include "DNTableFile.h"
#include "DnPartyTask.h"
#include "TaskManager.h"
#include "MATransAction.h"
#include "DnMonsterActor.h"
#include "DnSkill.h"
#include "DnBlow.h"
#include "MultiRoom.h"
#include "DNUserSession.h"
#include "DnStateBlow.h"
#include "MAScanner.h"
#include "DNAggroSystem.h"
MAAiBase::MAAiBase( DnActorHandle hActor, MAAiReceiver *pReceiver )
{
m_hActor = hActor;
m_pMonsterActor = NULL;
if ( m_hActor && m_hActor->IsMonsterActor())
{
m_pMonsterActor = static_cast<CDnMonsterActor*>(m_hActor.GetPointer());
}
m_pReceiver = pReceiver;
m_bEnableAggroProcess = true;
m_PrevLocalTime = 0;
// Delay <20>ʱ<EFBFBD>ȭ
m_nVecDelay.reserve( AIDelayType::Max );
for( int i=0 ; i<AIDelayType::Max ; ++i )
m_nVecDelay.push_back( 0 );
ResetAILook();
ResetNotifyDieAnnounce();
}
MAAiBase::~MAAiBase()
{
}
void MAAiBase::ResetAILook()
{
m_bIsAILook = false;
m_vAILook = EtVector2( 0.f, 0.f );
m_vProjectileTarget = EtVector3( 0.f, 0.f, 0.f );
}
bool MAAiBase::bIsProjectileTargetSignal()
{
if( m_bIsAILook )
return ( EtVec3LengthSq( &m_vProjectileTarget ) > 0.f ) ? true : false;
return false;
}
bool MAAiBase::Initialize()
{
return true;
}
void MAAiBase::ProcessDelay( const LOCAL_TIME LocalTime )
{
if( m_PrevLocalTime == 0 )
m_PrevLocalTime = LocalTime;
const LOCAL_TIME ElapsedTime = LocalTime - m_PrevLocalTime;
for( int i=0 ; i<AIDelayType::Max ; ++i )
{
if( m_nVecDelay[i] > ElapsedTime )
m_nVecDelay[i] -= ElapsedTime;
else
m_nVecDelay[i] = 0;
}
m_PrevLocalTime = LocalTime;
}
void MAAiBase::SetDelay( const AIDelayType Type, const int nDelay )
{
if( Type >= AIDelayType::Max )
return;
m_nVecDelay[Type] = nDelay;
}
bool MAAiBase::IsDelay( const AIDelayType Type ) const
{
if( Type >= AIDelayType::Max )
return false;
return (m_nVecDelay[Type] > 0) ? true : false;
}
void MAAiBase::ResetDelay()
{
for( int i=0 ; i<AIDelayType::Max ; ++i )
m_nVecDelay[i] = 0;
}
void MAAiBase::Process( LOCAL_TIME LocalTime, float fDelta )
{
ProcessDelay( LocalTime );
ProcessAggro( LocalTime, fDelta );
}
void MAAiBase::ProcessAggro( const LOCAL_TIME LocalTime, const float fDelta )
{
if( !m_bEnableAggroProcess )
return;
_ASSERT( m_hActor->GetAggroSystem() != NULL );
m_hActor->GetAggroSystem()->OnProcessAggro( LocalTime, fDelta );
}
void MAAiBase::ChangeTarget( DnActorHandle hActor, bool bStop/*=true*/ )
{
DnActorHandle hPrevTarget = m_hTarget;
SetTarget( hActor );
// <20>׼<EFBFBD><D7BC><EFBFBD>Ʈ <20>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD> Target <20><> <20>ٲ<EFBFBD><D9B2><EFBFBD><EFBFBD><EFBFBD> <20><> ó<><C3B3><EFBFBD><EFBFBD> <20>ٲ㺾<D9B2>ϴ<EFBFBD>.
if( m_hTarget )
{
if( !hPrevTarget )
{
if( m_hActor->IsMove() && bStop )
m_hActor->CmdStop( "Stand" );
}
if( m_hActor->GetLookTarget() != m_hTarget )
m_hActor->CmdLook(m_hTarget);
}
}
int MAAiBase::_CalcAdditionalAggro( const int nAggro, const float fValue )
{
if( fValue <= 0.f )
return -nAggro;
else if( fValue >= 1.f )
{
return static_cast<int>(nAggro*(fValue-1.f));
}
return static_cast<int>(-nAggro*(1.f-fValue));
}
void MAAiBase::FindTarget()
{
/*
// <20>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Target <20><> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><C9B6><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϱ<CFB1><E2B6A7><EFBFBD><EFBFBD>...
if( m_hActor->IsProcessSkill() )
{
if( m_hTarget && !m_hTarget->IsDie() && m_hTarget->GetTeam() == m_hActor->GetTeam() )
return;
}
*/
// <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Target <20><> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><C9B6><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϱ<CFB1><E2B6A7><EFBFBD><EFBFBD>...
if( m_hActor->IsProcessSkill() )
return;
CDNAggroSystem* pAggroSystem = m_hActor->GetAggroSystem();
bool bIsProvocationTarget;
DnActorHandle hNewTarget = m_bEnableAggroProcess ? pAggroSystem->OnGetAggroTarget( bIsProvocationTarget ) : CDnActor::Identity();
// Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> ã<>´<EFBFBD>.
if( !m_hTarget )
{
ChangeTarget( hNewTarget );
}
// Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD><D8BA><EFBFBD>.
else
{
if( m_hTarget == hNewTarget )
return;
if( hNewTarget && bIsProvocationTarget )
{
ChangeTarget( hNewTarget );
return;
}
if( m_hActor->GetStateBlow()->IsApplied( STATE_BLOW::BLOW_148) )
{
ChangeTarget( hNewTarget );
return;
}
CDNAggroSystem::AggroStruct* pTargetStruct = pAggroSystem->GetAggroStruct( m_hTarget );
CDNAggroSystem::AggroStruct* pNewTargetStruct = pAggroSystem->GetAggroStruct( hNewTarget );
if( pTargetStruct == NULL && pNewTargetStruct )
{
ChangeTarget( hNewTarget );
}
else if( pTargetStruct == NULL && pNewTargetStruct == NULL )
{
ChangeTarget( CDnActor::Identity() );
}
else if( pTargetStruct && pNewTargetStruct )
{
if( hNewTarget && hNewTarget->GetStateBlow() )
{
// <20><><EFBFBD>κ<EFBFBD>ũ <20><><EFBFBD><EFBFBD> ó<><C3B3>
if( hNewTarget->GetStateBlow()->IsApplied( STATE_BLOW::BLOW_132 ) )
{
ChangeTarget( hNewTarget );
return;
}
}
// <20><><EFBFBD><EFBFBD> Ÿ<>ٺ<EFBFBD><D9BA><EFBFBD> 120% <20><><EFBFBD>׷<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8> <20><><EFBFBD><EFBFBD>
if( static_cast<int>(pTargetStruct->iModifierAggro*g_fAggroChangeTragetRate) <= pNewTargetStruct->iModifierAggro )
ChangeTarget( hNewTarget );
}
}
}
void MAAiBase::SetTarget( DnActorHandle hActor, int nAggroValue )
{
if( m_hTarget == hActor )
return;
m_hTarget = hActor;
if( !m_hActor )
return;
MATransAction *pTrans = static_cast<MATransAction *>(m_hActor.GetPointer());
if( pTrans )
{
m_hActor->ResetMove();
BYTE pBuffer[128];
CMemoryStream Stream( pBuffer, 128 );
DWORD dwUniqueID = ( m_hTarget ) ? m_hTarget->GetUniqueID() : -1;
Stream.Write( &dwUniqueID, sizeof(DWORD) );
pTrans->Send( eActor::SC_AGGROTARGET, &Stream );
}
if( m_hTarget && nAggroValue )
{
if( m_hActor->IsMove() )
m_hActor->CmdStop( "Stand" );
if( m_hActor->GetLookTarget() != m_hTarget )
m_hActor->CmdLook(m_hTarget);
CDNAggroSystem::AggroStruct* pStruct = m_hActor->GetAggroSystem()->GetAggroStruct( m_hTarget );
if( pStruct )
pStruct->iAggro = nAggroValue;
else
m_hActor->GetAggroSystem()->AddAggro( hActor, nAggroValue );
}
}
void MAAiBase::SetProjectileTarget()
{
if( m_hTarget && m_hActor )
{
m_bIsAILook = true;
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
EtVector3 vTargetPosition = m_hTarget->FindAutoTargetPos();
m_vAILook = EtVec3toVec2( vTargetPosition - *m_hActor->GetPosition() );
#else
m_vAILook = EtVec3toVec2( *m_hTarget->GetPosition() - *m_hActor->GetPosition() );
#endif
m_vProjectileTarget = vTargetPosition;
EtVec2Normalize( &m_vAILook, &m_vAILook );
_OnSetProjectileTarget();
}
}
void MAAiBase::EnableAggorProcess( bool bEnable )
{
m_bEnableAggroProcess = bEnable;
if( bEnable == false )
{
ResetAggro();
SetTarget( CDnActor::Identity() );
m_hActor->ResetMove();
}
}
void MAAiBase::ResetAggro()
{
m_hActor->GetAggroSystem()->ResetAggro();
}
void MAAiBase::ResetNotifyDieAnnounce()
{
m_bNotifyDieAnnounce = false;
m_dwNotifyDieAnnounceTick = 0;
}
void MAAiBase::NotifyDieAnnounce()
{
m_bNotifyDieAnnounce = true;
m_dwNotifyDieAnnounceTick = timeGetTime();
}
bool MAAiBase::bIsNotifyDieAnnounce( DWORD dwGap )
{
if( !m_bNotifyDieAnnounce )
return false;
if( timeGetTime()-m_dwNotifyDieAnnounceTick <= dwGap )
return true;
return false;
}