DragonNest/Server/DNGameServer/MAAiMultipleTarget.cpp

292 lines
8.4 KiB
C++
Raw Permalink Normal View History

#include "stdafx.h"
#include "MAAiMultipleTarget.h"
#include "MAAiScript.h"
#include "DnMonsterActor.h"
#include "DnProjectile.h"
#include "MAScanner.h"
#include "DnPlayerActor.h"
#if defined (PRE_MOD_AIMULTITARGET)
#include "DNAggroSystem.h"
#endif
CMAAiMultipleTarget::CMAAiMultipleTarget()
:m_eType(MultipleTargetType::Max)
{
Reset();
}
CMAAiMultipleTarget::~CMAAiMultipleTarget()
{
}
void CMAAiMultipleTarget::Reset()
{
#if defined (PRE_MOD_AIMULTITARGET)
m_nMultipleTarget = 0;
m_nSummonerTarget =0;
#else
m_bIsMultipleTarget = false;
#endif
m_iMaxMultipleTargetCount = 0;
m_bIsAnyMultipleTarget = false;
m_bIsExceptCannonPlayer = false;
m_pActionTable = NULL;
m_pSkillTable = NULL;
}
void CMAAiMultipleTarget::SetMultipleTargetAction( ActionTable* pActionTable )
{
#if defined (PRE_MOD_AIMULTITARGET)
m_nMultipleTarget = pActionTable->nMultipleTarget;
if( m_nMultipleTarget <= 0 )
return;
m_nSummonerTarget = pActionTable->nSummonerTarget;
#else
m_bIsMultipleTarget = pActionTable->bMultipleTarget;
if( !m_bIsMultipleTarget )
return;
#endif
m_eType = MultipleTargetType::Action;
m_pActionTable = pActionTable;
m_iMaxMultipleTargetCount = pActionTable->iMaxMultipleTargetCount;
m_bIsAnyMultipleTarget = pActionTable->bIsAnyMultipleTarget;
m_bIsExceptCannonPlayer = pActionTable->bIsExceptCannonPlayer;
}
void CMAAiMultipleTarget::SetMultipleTargetSkill( MonsterSkillTable* pSkillTable )
{
#if defined (PRE_MOD_AIMULTITARGET)
m_nMultipleTarget = pSkillTable->nMultipleTarget;
if( m_nMultipleTarget <= 0 )
return;
m_nSummonerTarget = pSkillTable->nSummonerTarget;
#else
m_bIsMultipleTarget = pSkillTable->bMultipleTarget;
if( !m_bIsMultipleTarget )
return;
#endif
m_eType = MultipleTargetType::Skill;
m_pSkillTable = pSkillTable;
m_iMaxMultipleTargetCount = pSkillTable->iMaxMultipleTargetCount;
m_bIsAnyMultipleTarget = pSkillTable->bIsAnyMultipleTarget;
m_bIsExceptCannonPlayer = pSkillTable->bIsExceptCannonPlayer;
}
void CMAAiMultipleTarget::CalcTarget( DnActorHandle hActor, MAAiScript* pScript )
{
m_vTargetPos.clear();
m_vTargetActor.clear();
#if defined (PRE_MOD_AIMULTITARGET)
if( m_nMultipleTarget <= 0)
return;
#else
if( !m_bIsMultipleTarget )
return;
#endif
DNVector(DnActorHandle) vTarget;
CMAAiCheckerManager* pCheckerManager = NULL;
if( m_eType == MultipleTargetType::Action )
{
DN_ASSERT( m_pActionTable != NULL, "m_pActionTable == NULL" );
float fMaxRange = pScript->GetScriptData().m_AITable[m_pActionTable->nDistanceState].fNearValue;
if( m_bIsAnyMultipleTarget )
GetMAScanner().Scan( MAScanner::eType::MonsterSkillOpponentTeam, hActor, 0.f, fMaxRange, vTarget );
else
pScript->GetTargetDistance( m_pActionTable->nDistanceState, vTarget, false );
pCheckerManager = m_pActionTable->pMAAiCheckerManager;
}
else if( m_eType == MultipleTargetType::Skill )
{
DN_ASSERT( m_pSkillTable != NULL, "m_pSkillTable == NULL" );
if( m_bIsAnyMultipleTarget )
GetMAScanner().Scan( MAScanner::eType::MonsterSkillOpponentTeam, hActor, 0.f, static_cast<float>(m_pSkillTable->nRangeMax), vTarget );
else
pScript->GetTargetDistance( m_pSkillTable->nRangeMin, m_pSkillTable->nRangeMax, vTarget, false );
if( vTarget.empty() )
return;
pCheckerManager = m_pSkillTable->pMAAiCheckerManager;
}
// AIChecker <20><> <20><><EFBFBD><EFBFBD> üũ
if( pCheckerManager )
{
for( UINT i=0 ; i<vTarget.size() ; ++i )
{
// CannonActor <20>˻<EFBFBD>
if( vTarget[i]->GetActorType() == CDnActorState::ActorTypeEnum::Cannon )
continue;
if( m_bIsExceptCannonPlayer && vTarget[i]->IsPlayerActor() )
{
if( static_cast<CDnPlayerActor*>(vTarget[i].GetPointer())->IsCannonMode() )
continue;
}
#if defined (PRE_MOD_AIMULTITARGET)
if (m_nSummonerTarget && vTarget[i]->IsMonsterActor())
{
DnActorHandle hSummonMasterPlayerActor = static_cast<CDnMonsterActor*>(vTarget[i].GetPointer())->GetSummonerPlayerActor();
if (hSummonMasterPlayerActor)
continue;
}
#endif
if( !pCheckerManager->bIsTargetActorChecker( hActor, vTarget[i] ) )
continue;
m_vTargetPos.push_back( *vTarget[i]->GetPosition() );
m_vTargetActor.push_back( vTarget[i] );
}
}
// <20><> <20><><EFBFBD><EFBFBD> 0<≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ÿ<><C5B8>
if( m_iMaxMultipleTargetCount == 0 )
return;
#if defined (PRE_MOD_AIMULTITARGET)
// Type = 1 <20>Ϲ<EFBFBD>
if (m_nMultipleTarget == 2) // Type = 2 <20><><EFBFBD>׷<EFBFBD> 1<><31><EFBFBD><EFBFBD> -> <20><><EFBFBD><EFBFBD>
{
if (true == CalcTargetByAggro(hActor))
return;
}
// MultipleTarget <20>ִ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
if( m_vTargetPos.size() <= static_cast<size_t>(m_iMaxMultipleTargetCount) )
return;
do
{
size_t RandVal = _rand( hActor->GetRoom() )%m_vTargetPos.size();
m_vTargetPos.erase( m_vTargetPos.begin()+RandVal );
m_vTargetActor.erase( m_vTargetActor.begin()+RandVal );
}while( m_vTargetPos.size() > static_cast<size_t>(m_iMaxMultipleTargetCount) );
#else // #if defined (PRE_MOD_AIMULTITARGET)
// MultipleTarget <20>ִ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
if( m_vTargetPos.size() <= static_cast<size_t>(m_iMaxMultipleTargetCount-1) )
return;
do
{
size_t RandVal = _rand( hActor->GetRoom() )%m_vTargetPos.size();
m_vTargetPos.erase( m_vTargetPos.begin()+RandVal );
m_vTargetActor.erase( m_vTargetActor.begin()+RandVal );
}while( m_vTargetPos.size() > static_cast<size_t>(m_iMaxMultipleTargetCount-1) );
#endif // #if defined (PRE_MOD_AIMULTITARGET)
}
#if defined (PRE_MOD_AIMULTITARGET)
bool CMAAiMultipleTarget::CalcTargetByAggro(DnActorHandle hActor)
{
if( m_iMaxMultipleTargetCount <= 0 )
return true;
bool bIsProvocationTarget;
DnActorHandle hTarget = hActor->GetAggroSystem()->OnGetAggroTarget (bIsProvocationTarget, CDnActor::Identity(), &m_vTargetActor);
// TargetPos<6F><73> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>
int nIndex = -1;
for (UINT i=0; i<m_vTargetActor.size(); i++)
{
if (m_vTargetActor[i] == hTarget)
{
nIndex = i;
break;
}
}
if (m_vTargetActor.size() <= 1)
return true;
// MultipleTarget <20>ִ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
if( m_vTargetPos.size() <= static_cast<size_t>(m_iMaxMultipleTargetCount) )
return true;
EtVector3 vTargetPos;
if (nIndex >= 0) // <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> ã<>Ҵ<EFBFBD>.
{
if (nIndex >= m_vTargetPos.size())
return false;
vTargetPos = m_vTargetPos[nIndex];
m_vTargetPos.erase(m_vTargetPos.begin()+nIndex);
m_vTargetActor.erase(m_vTargetActor.begin()+nIndex);
}
else // <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><>ã<EFBFBD><C3A3> <20><><EFBFBD><EFBFBD>
return false;
if (m_vTargetActor.size() == 0)
{
m_vTargetActor.push_back(hTarget);
m_vTargetPos.push_back(vTargetPos);
return true;
}
//<2F><><EFBFBD>׷<EFBFBD> Ÿ<><C5B8> hTarget<65><74> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
do
{
size_t RandVal = _rand( hActor->GetRoom() )%m_vTargetPos.size();
m_vTargetPos.erase( m_vTargetPos.begin()+RandVal );
m_vTargetActor.erase( m_vTargetActor.begin()+RandVal );
}while( m_vTargetPos.size() > static_cast<size_t>(m_iMaxMultipleTargetCount-1) );
m_vTargetActor.push_back(hTarget);
m_vTargetPos.push_back(vTargetPos);
return true;
}
#endif
void CMAAiMultipleTarget::CreateProjectile( CDnMonsterActor* pMonsterActor, ProjectileStruct* pStruct, int iSignalIndex )
{
// TargetType == Target <20><> <20><><EFBFBD><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> MultipeŸ<65><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
if( pStruct->nTargetType == CDnProjectile::TargetTypeEnum::Target || pStruct->nTargetType == CDnProjectile::TargetTypeEnum::TargetPosition )
{
CalcTarget( pMonsterActor->GetActorHandle(), static_cast<MAAiScript*>(pMonsterActor->GetAIBase()) );
}
DN_ASSERT( m_vTargetPos.size() == m_vTargetActor.size(), "m_vTargetPos.size() != m_vTargetActor.size()" );
MatrixEx OrgLocalCross = *pMonsterActor->GetMatEx();
for( UINT i=0 ; i<m_vTargetPos.size() ; ++i )
{
// Projectile <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
MatrixEx LocalCross = OrgLocalCross;
// Homing/Terrain Homing <20><> <20><><EFBFBD><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LocalCross <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD> <20>߻<EFBFBD>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> ȸ<><C8B8><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ǹǷ<C7B9>
// <20>׼<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߻<EFBFBD>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD> ȸ<><C8B8><EFBFBD>ϰ<EFBFBD> <20>ȴ<EFBFBD>. <20><20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20>߻<EFBFBD>ü Ÿ<>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ƶд<C6B5>. #26226
if( false == (CDnProjectile::Homing == pStruct->nOrbitType ||
CDnProjectile::TerrainHoming == pStruct->nOrbitType) )
{
LocalCross.Look( &m_vTargetPos[i] );
}
CDnProjectile* pProjectile = CDnProjectile::CreateProjectile( pMonsterActor->GetRoom(), pMonsterActor->GetActorHandle(), LocalCross, pStruct, &m_vTargetPos[i], m_vTargetActor[i] );
if( pProjectile == NULL )
return;
pProjectile->SetShooterType( pMonsterActor->GetMySmartPtr(), pMonsterActor->GetCurrentActionIndex(), iSignalIndex );
pMonsterActor->SendProjectile( pProjectile, pStruct, LocalCross, iSignalIndex );
pMonsterActor->OnProjectile( pProjectile, pStruct, LocalCross, iSignalIndex );
pMonsterActor->OnSkillProjectile( pProjectile );
}
}