DragonNest/Server/DNGameServer/DnPartsMonsterActor.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

626 lines
No EOL
15 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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<AIPartsProcessor>& vData )
{
for( UINT i=0 ; i<m_Parts.size() ; ++i )
{
m_Parts[i].SetIgnore( false );
m_Parts[i].SetNoDamage( false );
}
int iHP = GetHPPercent();
bool bPrev = false;
for( UINT i=0 ; i<vData.size() ; ++i )
{
// HP
if( iHP < vData[i].iMinHP || iHP > 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<STATE_BLOW::emBLOW_INDEX>(vData[i].iCheckBlowIndex) ) == false )
continue;
}
// Ignore
for( UINT j=0 ; j<vData[i].vIgnorePartsIndex.size() ; ++j )
{
MonsterParts* pParts = GetParts( vData[i].vIgnorePartsIndex[j] );
if( pParts )
pParts->SetIgnore( true );
}
// NoDamage
for( UINT j=0 ; j<vData[i].vNoDamagePartsIndex.size() ; ++j )
{
MonsterParts* pParts = GetParts( vData[i].vNoDamagePartsIndex[j] );
if( pParts )
pParts->SetNoDamage( true );
}
// Active
for( UINT j=0 ; j<vData[i].vActivePartsIndex.size() ; ++j )
{
MonsterParts* pParts = GetParts( vData[i].vActivePartsIndex[j] );
if( pParts )
{
pParts->SetIgnore( false );
pParts->SetNoDamage( false );
}
}
bPrev = true;
}
// PartsProcessor <20><> <20><><EFBFBD>ٸ<EFBFBD> <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD>
if( vData.empty() )
return;
for( UINT i=0 ; i<m_Parts.size() ; ++i )
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
int iPartsTableID = m_Parts[i].GetPartsTableID();
int iState = m_Parts[i].GetPartsInfo().PartsState;;
int nIndex = (int)i;
Stream.Write( &nIndex, sizeof(int) ); // Parts <20>ε<EFBFBD><CEB5><EFBFBD> <20>߰<EFBFBD> [2011/05/11 semozz]
Stream.Write( &iPartsTableID, sizeof(int) );
Stream.Write( &iState, sizeof(int) );
Send( eActor::SC_MONSTERPARTS_STATE, &Stream );
}
}
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
void CDnPartsMonsterActor::_ProcessParts( const float fDelta )
{
if( m_listDestroyParts.empty() )
return;
_ASSERT( m_pAi );
_ASSERT( m_pAi->IsScript() );
// <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><>Ȱ
MAAiScript* pScript = static_cast<MAAiScript*>(m_pAi);
const ScriptData& data = pScript->GetScriptData();
for( std::list<std::pair<UINT,float>>::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<data.m_vSetPartsRebirthTable[uiSetID].vPartsTableID.size() ; ++i )
{
for( std::list<MonsterParts*>::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 );
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ȱ
for( std::list<MonsterParts*>::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<LOCAL_TIME>(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<m_Parts.size() ; ++i )
{
#if defined( PRE_ADD_LOTUSGOLEM )
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD>..ignore <20><><EFBFBD>°<EFBFBD> <20>ƴ϶<C6B4><CFB6><EFBFBD>..
if( m_Parts[i].GetHP() > 0 && m_Parts[i].CheckPartsState( MonsterParts::eIgnore ) == false )
#else
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
if( m_Parts[i].GetHP() > 0 )
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
{
// <20><>ü <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
float fMainDamageRate = m_Parts[i].GetMainDamageRate();
fAddDamage += (fDamage*(fMainDamageRate-1.f));
}
for( UINT j=0 ; j<HitParam.vBoneIndex.size() ; ++j )
{
std::string strBoneName = GetBoneName( HitParam.vBoneIndex[j] );
if( m_Parts[i].HasBone( strBoneName.c_str() ) )
{
bool bHitCondition = true;
for( UINT k=0 ; k<m_Parts[i].GetPartsInfo().vHitCondition.size() ; ++k )
{
for( UINT ii=0 ; ii<m_Parts.size() ; ++ii )
{
if( m_Parts[i].GetPartsInfo().vHitCondition[k].iRequiredPartsID == m_Parts[ii].GetPartsInfo().uiMonsterPartsTableID )
{
if( m_Parts[ii].GetHP() > 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<MAAiScript*>(GetAIBase())->GetScriptData().m_iOnlyPartsDamage > 0 )
{
if( bBreak == false )
{
// 2<><32> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><>ȿ<EFBFBD><C8BF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴѰ<C6B4><D1B0><EFBFBD> <20><><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20>Ѵ<EFBFBD>.
if( static_cast<MAAiScript*>(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<INT64>(GetHP()-fDamage) );
return fDamage;
}
bool CDnPartsMonsterActor::IsLimitAction( const char* pszActionName )
{
if( m_listDestroyParts.empty() )
return false;
for( std::list<MonsterParts*>::iterator itor=m_listDestroyParts.begin() ; itor!=m_listDestroyParts.end() ; ++itor )
{
if( (*itor)->IsLimitAction( pszActionName ) )
{
//g_Log.LogA( "CDnPartsMonsterActor::IsLimitAction() Action=%s <20><><EFBFBD><EFBFBD> <20>׼<EFBFBD>!\r\n", pszActionName );
return true;
}
}
return false;
}
bool CDnPartsMonsterActor::IsLimitAction( DnSkillHandle hSkill )
{
std::set<std::string> setLimitAction;
for( std::list<MonsterParts*>::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 <20><><EFBFBD><EFBFBD> <20>׼<EFBFBD>!\r\n", hSkill->GetClassID() );
return bRet;
}
bool CDnPartsMonsterActor::bIsDestroyParts( const UINT uiTableID )
{
for( std::list<MonsterParts*>::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<std::pair<UINT,float>>::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<int>(PreCalcDamage( pHitter, HitParam, Parts.GetDefenseRate() ));
// <20><><EFBFBD><EFBFBD> <20>ı<EFBFBD>
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 ; i<pParts->GetPartsInfo().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 );
// <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20>ı<EFBFBD> <20>˻<EFBFBD>
MAAiScript* pScript = static_cast<MAAiScript*>(m_pAi);
const ScriptData& data = pScript->GetScriptData();
for( UINT i=0 ; i<data.m_vSetPartsRebirthTable.size() ; ++i )
{
if( bIsDestroySetParts(i) )
continue;
UINT uiDestroyCount = 0;
for( UINT j=0 ; j<data.m_vSetPartsRebirthTable[i].vPartsTableID.size() ; ++j )
{
UINT uiPartsID = data.m_vSetPartsRebirthTable[i].vPartsTableID[j];
if( !bIsDestroyParts( uiPartsID ) )
break;
++uiDestroyCount;
}
if( uiDestroyCount == data.m_vSetPartsRebirthTable[i].vPartsTableID.size() )
{
m_listDestroySetParts.push_back( std::make_pair(i,static_cast<float>(data.m_vSetPartsRebirthTable[i].uiRebirthTick/1000.f) ));
}
}
// <20><><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD> LimitAction<6F>ΰ<EFBFBD><CEB0><EFBFBD>
DnActorHandle hActor = GetActorHandle();
if( hActor )
{
const char* pszAction = hActor->GetCurrentAction();
if( pszAction && strlen( pszAction ) )
{
if( pParts->IsLimitAction( pszAction ) )
{
//g_Log.LogA( "<22><><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC>̾ <20><><EFBFBD><EFBFBD> %s\r\n", pszAction );
hActor->CmdStop( "Stand" );
}
//g_Log.LogA( "<22><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD> <20>׼<EFBFBD> %s\r\n", pszAction );
}
}
if( m_pAi )
{
// <20><><EFBFBD><EFBFBD> <20>ı<EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20><>ų <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> <20><><EFBFBD><EFBFBD>
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 );
}
// <20><><EFBFBD><EFBFBD> <20>ı<EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų
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<MonsterParts*> activateParts;
for( UINT i=0 ; i<m_Parts.size() ; ++i )
{
MonsterParts& monsterParts = m_Parts[i];
bool bHitCondition = true;
for( UINT k=0 ; k<monsterParts.GetPartsInfo().vHitCondition.size() ; ++k )
{
for( UINT n=0 ; n<m_Parts.size() ; ++n )
{
if( monsterParts.GetPartsInfo().vHitCondition[k].iRequiredPartsID == m_Parts[n].GetPartsInfo().uiMonsterPartsTableID )
{
if( m_Parts[n].GetHP() > 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<MonsterParts*>::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;
// <20><><EFBFBD><EFBFBD> <20>ı<EFBFBD>
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
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HP<48><50> <20><><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20>ȵǹǷ<C7B9> fDamage<67><65><EFBFBD><EFBFBD> 0.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
#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<m_Parts.size() ; ++i )
{
int iHP = m_Parts[i].GetHP();
int iMaxHP = m_Parts[i].GetMaxHP();
int iDelta = int((float)iMaxHP * fRate);
int iResult = iHP + iDelta;
if( iMaxHP < iResult )
{
iResult = iMaxHP;
iDelta = iMaxHP - iHP;
}
else if( iResult <= 0 )
{
iResult = 0;
iDelta = 0 - iHP;
// # 68809 - [<5B><><EFBFBD><EFBFBD>Ʈ <20><EFBFBD><E5B7A1>] HP_RATIO<49><4F> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ı<EFBFBD><C4B1><EFBFBD> destroyparts(Lua <20><><EFBFBD>ɾ<EFBFBD>) <20><> <20>۵<EFBFBD><DBB5><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>.
_OnDestroyParts( &(m_Parts[i]) );
}
m_Parts[i].SetHP( iResult );
_SendPartsHP( &m_Parts[i] );
}
}
#endif // PRE_FIX_66687