2564 lines
No EOL
81 KiB
C++
2564 lines
No EOL
81 KiB
C++
|
||
#include "StdAfx.h"
|
||
#include "DnMonsterActor.h"
|
||
#include "DnWorld.h"
|
||
#include "DnWeapon.h"
|
||
#include "MAAiBase.h"
|
||
#include "DnTableDB.h"
|
||
#include "DnDropItem.h"
|
||
#include "DnPartyTask.h"
|
||
#include "DnGameTask.h"
|
||
#include "TaskManager.h"
|
||
#include "DnItemTask.h"
|
||
#include "DnBlow.h"
|
||
#include "DNGameRoom.h"
|
||
#include "DNUserSession.h"
|
||
#include "DnWorldTrapProp.h"
|
||
#include "DnStateBlow.h"
|
||
#include "navigationcell.h"
|
||
#include "navigationmesh.h"
|
||
#include "navigationpath.h"
|
||
#include "DnPlayerActor.h"
|
||
#include "DNLogConnection.h"
|
||
#include "MAWalkMovementNav.h"
|
||
#include "DNMissionSystem.h"
|
||
#include "DnProjectile.h"
|
||
#include "MAAiScript.h"
|
||
#include "DNMonsterAggroSystem.h"
|
||
#include "GameSendPacket.h"
|
||
#include "MAScanner.h"
|
||
#include "MasterRewardSystem.h"
|
||
#include "DnBlockBlow.h"
|
||
#include "DnParryBlow.h"
|
||
#include "DnCannonMonsterActor.h"
|
||
#if defined(PRE_ADD_WEEKLYEVENT)
|
||
#include "DNGameDataManager.h"
|
||
#endif
|
||
|
||
int CDnMonsterActor::s_nPositionRevisionTime = 3000;
|
||
|
||
CDnMonsterActor::CDnMonsterActor( CMultiRoom *pRoom, int nClassID )
|
||
:CDnActor( pRoom, nClassID )
|
||
,m_nMonsterClassID(0)
|
||
,m_AIDifficult( Dungeon::Difficulty::Easy )
|
||
,m_pszCanBumpActionName(NULL)
|
||
{
|
||
CDnActionBase::Initialize( this );
|
||
m_nDestroyTime = 0;
|
||
m_bTimeMonster = false;
|
||
m_fScale = 1.f;
|
||
m_nMonsterWeightTableID = -1;
|
||
m_eElementType = ElementEnum_Amount;
|
||
m_bNoDamage = false;
|
||
m_LastSendMoveMsg = 0;
|
||
m_fRotateResistance = 1.f;
|
||
m_nPartyComboCount = 0;
|
||
m_nPartyComboDelay = 0;
|
||
m_bIsTriggerMonster = false;
|
||
m_iTriggerRandomSeed = 0;
|
||
m_hProp = CDnWorldProp::Identity();
|
||
m_uiForcePositionRevisionTick = 0;
|
||
m_uiPrevForcePositionRevisionTick = 0;
|
||
m_bEnableDropItem = true;
|
||
m_nBirthAreaHandle = -1;
|
||
m_dwSummonerActorID = 0;
|
||
m_bSuicideWhenSummonerDie = false;
|
||
m_bFollowSummonerStage = false;
|
||
m_iSummonGroupID = 0;
|
||
m_fLimitSummonerDistanceSQ = 0.0f;
|
||
m_bSummoned = false;
|
||
m_bReCreatedFollowStageMonster = false;
|
||
|
||
#ifdef PRE_ADD_MONSTER_CATCH
|
||
m_iCatchedActorActionIndex = 0;
|
||
#endif // #ifdef PRE_ADD_MONSTER_CATCH
|
||
|
||
#if defined( PRE_FIX_MOVEBACK )
|
||
m_bNearMoveBack = false;
|
||
m_bPrevMoveBack = false;
|
||
#endif
|
||
|
||
m_nAutoRecallRange = 0;
|
||
|
||
#if defined(PRE_FIX_51048)
|
||
m_EnablePassiveStateEffect = false;
|
||
#endif // PRE_FIX_51048
|
||
|
||
m_bChangeAxisOnFinishAction = false;
|
||
m_isPuppetSummonMonster = false;
|
||
#ifdef PRE_MOD_DARKLAIR_RECONNECT
|
||
m_nEventAreaUniqueID = -1;
|
||
#endif // PRE_MOD_DARKLAIR_RECONNECT
|
||
#ifdef PRE_ADD_TRANSFORM_MONSTER_ACTOR
|
||
m_nSwapActorID = -1;
|
||
#endif
|
||
}
|
||
|
||
CDnMonsterActor::~CDnMonsterActor()
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD>.
|
||
if( IsEnabledAuraSkill() )
|
||
OnSkillAura( m_hAuraSkill, false );
|
||
|
||
SAFE_DELETE_VEC( m_VecDropItemList );
|
||
}
|
||
|
||
bool CDnMonsterActor::Initialize()
|
||
{
|
||
CalcMonsterWeightIndex();
|
||
|
||
CDnMonsterState::Initialize( m_nClassID );
|
||
MAAiReceiver::Initialize( m_nMonsterClassID, GetAIFileName().c_str() );
|
||
CDnActor::Initialize();
|
||
|
||
if( m_fWeight == 0.f ) m_fRevisionWeight = 0.f;
|
||
else m_fRevisionWeight = m_fWeight + ( ( m_fScale - 1.f ) * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ScaleWeightValue ) );
|
||
|
||
GenerationDropItem();
|
||
|
||
if( m_hObject ) {
|
||
m_hObject->SetCollisionGroup( COLLISION_GROUP_DYNAMIC( 1 ) );
|
||
m_hObject->SetTargetCollisionGroup( COLLISION_GROUP_STATIC( 1 ) | COLLISION_GROUP_DYNAMIC( 2 ) );
|
||
}
|
||
|
||
DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TMONSTER );
|
||
int nStrElementType = pSox->GetFieldFromLablePtr( m_nMonsterClassID, "_Element_Str_Type" )->GetInteger();
|
||
if( nStrElementType != -1 )
|
||
m_eElementType = (ElementEnum)nStrElementType;
|
||
|
||
_ASSERT( m_pAggroSystem == NULL );
|
||
m_pAggroSystem = new CDNMonsterAggroSystem( GetActorHandle() );
|
||
_ASSERT( m_pAggroSystem != NULL );
|
||
|
||
return true;
|
||
}
|
||
|
||
void CDnMonsterActor::ProcessLook( LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
if( bIsAILook() && bIsTurnOnAILook() )
|
||
{
|
||
Look( *m_pAi->GetAILook() );
|
||
}
|
||
else
|
||
{
|
||
bool bNaviMode = IsNaviMode();
|
||
// bool bLockTarget = IsSignalRange( STE_LockTargetLook );
|
||
|
||
#if defined( PRE_MOD_LOCK_TARGET_LOOK )
|
||
if( false == bNaviMode && 0 != m_nLockLookEventArea && true == m_bLockLookTarget )
|
||
{
|
||
if( GetLookTarget() )
|
||
ResetLook();
|
||
if( NULL != GetGameRoom() && NULL != GetGameRoom()->GetWorld() )
|
||
{
|
||
std::vector<CEtWorldEventArea *> vecArea;
|
||
GetGameRoom()->GetWorld()->FindEventAreaFromCreateUniqueID( m_nLockLookEventArea, &vecArea );
|
||
|
||
if( false == vecArea.empty() )
|
||
{
|
||
EtVector3 vAreaPosition = vecArea[0]->GetOBB()->Center;
|
||
EtVector3 * vMonsterPosition = GetPosition();
|
||
|
||
EtVector2 vDir;
|
||
vDir.x = vAreaPosition.x - vMonsterPosition->x;
|
||
vDir.y = vAreaPosition.z - vMonsterPosition->z;
|
||
EtVec2Normalize( &vDir, &vDir );
|
||
|
||
CmdLook( vDir );
|
||
}
|
||
}
|
||
}
|
||
else
|
||
#endif // #if defined( PRE_MOD_LOCK_TARGET_LOOK )
|
||
if( !bNaviMode && m_bLockLookTarget && GetAggroTarget() )
|
||
{
|
||
if( !GetLookTarget() && GetLookTarget() != GetAggroTarget() )
|
||
LookTarget( GetAggroTarget() );
|
||
}
|
||
else
|
||
{
|
||
if( GetLookTarget() )
|
||
ResetLook();
|
||
}
|
||
}
|
||
if( !IsSignalRange( STE_RotateResistance ) ) m_fRotateResistance = 1.f;
|
||
}
|
||
|
||
void CDnMonsterActor::Process( LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
m_bLockLookTarget = false;
|
||
m_pszCanBumpActionName = NULL;
|
||
m_uiPrevForcePositionRevisionTick = m_uiForcePositionRevisionTick;
|
||
m_uiForcePositionRevisionTick = 0;
|
||
|
||
#if defined( PRE_MOD_LOCK_TARGET_LOOK )
|
||
m_nLockLookEventArea = 0;
|
||
#endif // #if defined( PRE_MOD_LOCK_TARGET_LOOK )
|
||
|
||
CDnActor::Process( LocalTime, fDelta );
|
||
PROFILE_TIME_TEST_BLOCK_START( "CDnMonsterActor::Process" );
|
||
ProcessLook( LocalTime, fDelta );
|
||
SetMoveVectorX( m_Cross.m_vXAxis );
|
||
SetMoveVectorZ( m_Cross.m_vZAxis );
|
||
|
||
if ( m_bTimeMonster && !IsDie() )
|
||
{
|
||
m_nDestroyTime -= (LOCAL_TIME)(fDelta*1000.0f);
|
||
|
||
if( m_nDestroyTime <= 0 )
|
||
CmdSuicide( false, false );
|
||
}
|
||
|
||
// <20><>ȯ<EFBFBD>ڰ<EFBFBD> <20><EFBFBD><D7BE><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7B5><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִٸ<D6B4> üũ<C3BC>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>״´<D7B4>.
|
||
if( m_bSuicideWhenSummonerDie )
|
||
{
|
||
// <20><>ȯ<EFBFBD><C8AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD> <20><EFBFBD><D7BE><EFBFBD> <20><>..
|
||
if( !m_hSummonerPlayerActor ||
|
||
m_hSummonerPlayerActor->IsDie() )
|
||
{
|
||
CmdSuicide( false, false );
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD> <20>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>װ<EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִٸ<D6B4> <20><EFBFBD><D7B7><EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||
if( 0.0f < m_fLimitSummonerDistanceSQ )
|
||
{
|
||
if( m_hSummonerPlayerActor && false == m_hSummonerPlayerActor->IsDie() )
|
||
{
|
||
EtVector3 vSummonerPos = *m_hSummonerPlayerActor->GetPosition();
|
||
float fNowDistanceSQ = EtVec3LengthSq( &(vSummonerPos - *GetPosition()) );
|
||
if( m_fLimitSummonerDistanceSQ < fNowDistanceSQ )
|
||
{
|
||
CmdSuicide( false, false );
|
||
}
|
||
}
|
||
}
|
||
|
||
ProcessPositionRevision( fDelta );
|
||
ProcessPartyCombo( LocalTime, fDelta );
|
||
|
||
#ifdef PRE_ADD_MONSTER_CATCH
|
||
ProcessCatchActor( LocalTime, fDelta );
|
||
#endif // #ifdef PRE_ADD_MONSTER_CATCH
|
||
|
||
Process_AutoRecallRange();
|
||
|
||
PROFILE_TIME_TEST_BLOCK_END();
|
||
}
|
||
|
||
void CDnMonsterActor::ProcessAI(LOCAL_TIME LocalTime, float fDelta)
|
||
{
|
||
if( MATransAction::GetGameRoom() )
|
||
{
|
||
MAAiReceiver::Process( LocalTime, fDelta );
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::OnDamage( CDnDamageBase *pHitter, SHitParam &HitParam, HitStruct *pHitStruct )
|
||
{
|
||
int nSeed = CRandom::Seed(GetRoom());
|
||
_srand( GetRoom(), nSeed );
|
||
INT64 nTemp = GetHP();
|
||
|
||
CDnActor::OnDamage( pHitter, HitParam, pHitStruct );
|
||
INT64 nDamage = nTemp - GetHP();
|
||
|
||
switch( pHitter->GetDamageObjectType() )
|
||
{
|
||
case DamageObjectTypeEnum::Actor:
|
||
{
|
||
// Aggro Process
|
||
//DnActorHandle hActor = dynamic_cast<CDnActor*>(pHitter)->GetMySmartPtr();
|
||
DnActorHandle hActor = pHitter->GetActorHandle();
|
||
|
||
if( m_pAggroSystem )
|
||
m_pAggroSystem->OnDamageAggro( hActor, HitParam, (int)nDamage );
|
||
|
||
ResetCustomAction();
|
||
// ȭ<>찰<EFBFBD><ECB0B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ⱑ <20>ÿ<EFBFBD><C3BF>̵Ǹ鼭 <20><EFBFBD><DFBB>DZ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Hit <20><> Idle <20><> <20><><EFBFBD>ش<EFBFBD>.
|
||
if( GetWeapon() ) {
|
||
if( GetWeapon()->GetElementIndex( "Idle" ) != -1 )
|
||
GetWeapon()->SetActionQueue( "Idle" );
|
||
}
|
||
if( HitParam.HitType != CDnWeapon::Defense )
|
||
OnPartyCombo( hActor, pHitStruct->nPartyComboDelay );
|
||
}
|
||
break;
|
||
case DamageObjectTypeEnum::Prop:
|
||
break;
|
||
}
|
||
RequestDamage( pHitter, nSeed, nDamage );
|
||
}
|
||
|
||
void CDnMonsterActor::OnDie( DnActorHandle hHitter )
|
||
{
|
||
CDnActor::OnDie( hHitter );
|
||
CDnPartyTask *pTask = (CDnPartyTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "PartyTask" );
|
||
if( !pTask ) return;
|
||
|
||
#ifdef PRE_FIX_REMOVE_AURA_ONDIE
|
||
if (IsEnabledAuraSkill())
|
||
OnSkillAura(m_hAuraSkill, false);
|
||
#endif
|
||
|
||
if( m_hSummonerPlayerActor )
|
||
{
|
||
_ASSERT( m_hSummonerPlayerActor->IsPlayerActor() );
|
||
if( m_hSummonerPlayerActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(m_hSummonerPlayerActor.GetPointer());
|
||
pPlayerActor->OnDieSummonedMonster( GetMySmartPtr() );
|
||
}
|
||
}
|
||
|
||
CDnPlayerActor* pMasterPlayerActor = NULL;
|
||
if (hHitter)
|
||
{
|
||
if (hHitter->IsPlayerActor())
|
||
pMasterPlayerActor = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
|
||
else if (hHitter->IsMonsterActor())
|
||
{
|
||
CDnMonsterActor* pMonster = static_cast<CDnMonsterActor*>(hHitter.GetPointer());
|
||
if (pMonster && pMonster->IsCannonMonsterActor())
|
||
{
|
||
CDnCannonMonsterActor* pCannonMonster = static_cast<CDnCannonMonsterActor*>(hHitter.GetPointer());
|
||
if (pCannonMonster && pCannonMonster->GetMasterPlayerActor() && pCannonMonster->GetMasterPlayerActor()->IsPlayerActor())
|
||
pMasterPlayerActor = static_cast<CDnPlayerActor*>(pCannonMonster->GetMasterPlayerActor().GetPointer());
|
||
}
|
||
}
|
||
}
|
||
|
||
int nPartyCount = pTask->GetRoom()->GetUserCount() - pTask->GetRoom()->GetGMCount();
|
||
|
||
// <20><><EFBFBD><EFBFBD>ġ <20>й<EFBFBD><D0B9><EFBFBD><EFBFBD>ֽð<D6BD>. <20><><EFBFBD><EFBFBD> Add <20><><EFBFBD>ֽð<D6BD>..
|
||
// float fValue = ( ( 1.f + ( 0.9f * ( nPartyCount - 1 ) ) ) / nPartyCount );
|
||
float fExpPenalty;
|
||
float fExp;
|
||
int nValue;
|
||
float fCompleteExp;
|
||
float fItemExp = 0.f;
|
||
float fGuildRewardExp = 0.f;
|
||
|
||
float fDeadDurabilityRevision = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::MonsterDeadDurabilityRevision );
|
||
int nDeadDurability = (int)( ( GetDeadDurability() * ( 1.f + ( fDeadDurabilityRevision * ( nPartyCount - 1 ) ) ) ) / nPartyCount );
|
||
int nFinalDeadDurability = nDeadDurability;
|
||
for( int i=0; i<nPartyCount; i++ )
|
||
{
|
||
CDNUserSession *pSession = pTask->GetRoom()->GetUserData(i);
|
||
if( !pSession )
|
||
continue;
|
||
// <20><EFBFBD>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD>ش<EFBFBD>.
|
||
if( pSession->bIsGMTrace() )
|
||
continue;
|
||
|
||
DnActorHandle hActor = pSession->GetActorHandle();
|
||
if( !hActor ) continue;
|
||
|
||
pSession->GetEventSystem()->OnEvent( EventSystem::OnKillMonster2, 1, EventSystem::MonsterID, GetMonsterClassID() );
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ
|
||
nValue = hActor->GetLevel() - GetLevel();
|
||
fExpPenalty = 1.f - ( ( pow( max( nValue - 1, 0.f ), CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ExpPenaltyValue1 ) ) ) *
|
||
CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ExpPenaltyValue2 ) );
|
||
fExpPenalty = max( fExpPenalty, CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ExpPenaltyMin ) );
|
||
|
||
float fExpPartyBonus = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ExpPartyBonus );
|
||
fExp = GetDeadExperience() * ( 1.f + ( fExpPartyBonus * ( nPartyCount - 1 ) ) ) / nPartyCount * fExpPenalty;
|
||
float fEventBonusExp = pTask->GetRoom()->GetEventExpWhenMonsterDie(fExp, pSession->GetFriendBonus(), pSession->GetClassID(), pSession->GetUserJob());
|
||
#ifdef PRE_ADD_BEGINNERGUILD
|
||
fEventBonusExp += (pTask->GetRoom()->GetPartyStructData().bPartyBeginnerGuild == true && pSession->CheckBegginerGuild()) ? (float)((fExp * (float)((float)(BeginnerGuild::Common::PartyBonusRate)/100)) + 0.5f) : 0;
|
||
#endif //#ifdef PRE_ADD_BEGINNERGUILD
|
||
|
||
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
|
||
float fIncExpRate = 0.0f;
|
||
if (hActor && hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_255))
|
||
{
|
||
DNVector(DnBlowHandle) vlBlows;
|
||
hActor->GatherAppliedStateBlowByBlowIndex(STATE_BLOW::BLOW_255, vlBlows);
|
||
{
|
||
int nCount = (int)vlBlows.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
DnBlowHandle hBlow = vlBlows[i];
|
||
if (hBlow && hBlow->IsEnd() == false)
|
||
{
|
||
fIncExpRate += hBlow->GetFloatValue();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
float fAddBlowExp = fExp * fIncExpRate;
|
||
fEventBonusExp += fAddBlowExp;
|
||
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
|
||
|
||
#if defined(PRE_ADD_WEEKLYEVENT)
|
||
if (CDnWorld::GetInstance(GetRoom()).GetMapSubType() != EWorldEnum::MapSubTypeNest){
|
||
int nThreadID = GetGameRoom()->GetServerID();
|
||
|
||
if (pTask->GetRoom()->GetPartyUpkeepCount() > 0){
|
||
float fEventValue = g_pDataManager->GetWeeklyEventValuef(WeeklyEvent::Player, pSession->GetClassID(), WeeklyEvent::Event_6, nThreadID);
|
||
if (fEventValue != 0)
|
||
fEventBonusExp += fEventValue;
|
||
}
|
||
|
||
if (pSession->GetFriendBonus()){
|
||
float fEventValue = g_pDataManager->GetWeeklyEventValuef(WeeklyEvent::Player, pSession->GetClassID(), WeeklyEvent::Event_7, nThreadID);
|
||
if (fEventValue != 0)
|
||
fEventBonusExp += fEventValue;
|
||
}
|
||
}
|
||
#endif // #if defined(PRE_ADD_WEEKLYEVENT)
|
||
|
||
// <20>Ϸ<EFBFBD><CFB7><EFBFBD> <20><><EFBFBD><EFBFBD>ġ ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
fCompleteExp = GetCompleteExperience() * ( 1.f + ( fExpPartyBonus * ( nPartyCount - 1 ) ) ) / nPartyCount * fExpPenalty;
|
||
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(hActor.GetPointer());
|
||
|
||
if( pPlayer->GetAddExp() > 0.f )
|
||
fItemExp = GetDeadExperience()*pPlayer->GetAddExp();
|
||
float fGuildCompleteExp = 0.f;
|
||
int nGuildRewardValue = pSession->GetGuildRewardItemValue(GUILDREWARDEFFECT_TYPE_EXTRAEXP);
|
||
if( nGuildRewardValue > 0 )
|
||
{
|
||
fGuildRewardExp = (float)(GetDeadExperience() * (nGuildRewardValue * 0.01));
|
||
fGuildCompleteExp = (float)(fCompleteExp * (nGuildRewardValue * 0.01));
|
||
}
|
||
else
|
||
fGuildRewardExp = 0;
|
||
|
||
fCompleteExp += ( (fCompleteExp*pPlayer->GetAddExp()) + fGuildCompleteExp );
|
||
pPlayer->AddCompleteExperience((int)fCompleteExp);
|
||
|
||
if (hActor->IsDie())
|
||
continue;
|
||
|
||
MasterSystem::CRewardSystem* pMasterRewardSystem = pSession->GetGameRoom()->GetMasterRewardSystem();
|
||
if( pMasterRewardSystem )
|
||
{
|
||
float fBonusRate = pMasterRewardSystem->GetExpRewardRate( pSession );
|
||
if( fBonusRate > 0.f )
|
||
{
|
||
fEventBonusExp += (fExp*fBonusRate);
|
||
int iMasterAddExp = 0;
|
||
iMasterAddExp = pMasterRewardSystem->GetMasterSystemAddExp(pSession, fExp, false);
|
||
fEventBonusExp += iMasterAddExp;
|
||
#if defined( _WORK )
|
||
WCHAR wszBuf[MAX_PATH];
|
||
wsprintf( wszBuf, L"[<5B><><EFBFBD><EFBFBD><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>] <20>߰<EFBFBD> <20><><EFBFBD><EFBFBD>ġ %d, <20><><EFBFBD><EFBFBD>:%d", static_cast<int>(fExp*fBonusRate), iMasterAddExp );
|
||
pSession->SendDebugChat( wszBuf );
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
}
|
||
if( pSession->GetPeriodExpItemRate() > 0 )
|
||
{
|
||
fEventBonusExp += (fExp* (float)(pSession->GetPeriodExpItemRate()/100.0f));
|
||
#if defined( _WORK )
|
||
WCHAR wszBuf[MAX_PATH];
|
||
wsprintf( wszBuf, L"[<5B><><EFBFBD><EFBFBD>ġ<EFBFBD>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>] <20>߰<EFBFBD> <20><><EFBFBD><EFBFBD>ġ %d", static_cast<int>(fExp* (float)(pSession->GetPeriodExpItemRate()/100.0f)) );
|
||
pSession->SendDebugChat( wszBuf );
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
float fPcBangExp = 0.0f;
|
||
if (pSession->IsPCBang() && pSession->GetPcBangBonusExp() > 0 && fExp > 0.f )
|
||
fPcBangExp = (float)((fExp * (float)((float)(pSession->GetPcBangBonusExp())/100)) + 0.5f);
|
||
|
||
float fPromotionBonusExp = 0.0f;
|
||
if( fExp > 0.f )
|
||
fPromotionBonusExp = (float)((fExp * (float)((float)(pSession->GetPromotionValue(PROMOTIONTYPE_MONSTERKILL))/100)) + 0.5f);
|
||
|
||
float fVIPExp = 0.0f;
|
||
#if defined(PRE_ADD_VIP)
|
||
if (pSession->IsVIP() && pSession->GetVIPBonusExp() > 0 && fExp > 0.f )
|
||
fVIPExp = (float)((fExp * (float)((float)(pSession->GetVIPBonusExp())/100)) + 0.5f);
|
||
#endif // #if defined(PRE_ADD_VIP)
|
||
|
||
TExpData ExpData;
|
||
ExpData.set( fExp, fEventBonusExp, fPcBangExp, fVIPExp, fPromotionBonusExp, fItemExp, fGuildRewardExp );
|
||
#if defined( PRE_USA_FATIGUE )
|
||
pPlayer->CmdAddExperience( ExpData, DBDNWorldDef::CharacterExpChangeCode::DungeonMonster, pPlayer->GetUserSession()->GetPartyID() );
|
||
#else
|
||
pPlayer->CmdAddExperience( ExpData, DBDNWorldDef::CharacterExpChangeCode::Dungeon, pPlayer->GetUserSession()->GetPartyID() );
|
||
#endif // #if defined( PRE_USA_FATIGUE )
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ʽ<EFBFBD> <20><><EFBFBD><EFBFBD>ġ<EFBFBD>Դϴ<D4B4>. <20>ݵ<EFBFBD><DDB5><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ǹ<EFBFBD> <20><><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD>.
|
||
pPlayer->UpdateMaxLevelGainExperience( (int)( fExp + fEventBonusExp + fPcBangExp ) );
|
||
|
||
int nGuildRewardItemValue = pSession->GetGuildRewardItemValue(GUILDREWARDEFFECT_TYPE_REDUCEDURABILITYRATIO);
|
||
if( nGuildRewardItemValue > 0 )
|
||
nFinalDeadDurability -= (int)(nFinalDeadDurability * nGuildRewardItemValue * 0.01);
|
||
// <20><>Ƽ<EFBFBD><C6BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
pPlayer->OnDecreaseEquipDurability( nFinalDeadDurability, false );
|
||
|
||
if (pMasterPlayerActor)
|
||
{
|
||
pSession->GetEventSystem()->OnEvent( EventSystem::OnKillMonster, 3,
|
||
EventSystem::MonsterID, GetMonsterClassID(),
|
||
EventSystem::MonsterGrade, GetGrade(),
|
||
EventSystem::MonsterRaceID, GetRaceID());
|
||
}
|
||
}
|
||
// pTask->GetRoom()->AddCompleteExperience( GetCompleteExperience() );
|
||
|
||
if( m_bEnableDropItem )
|
||
DropItems();
|
||
|
||
if( IsSlowByDie() ) {
|
||
CDnGameTask *pGameTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" );
|
||
if( pGameTask ) pGameTask->RequestChangeGameSpeed( 0.2f, 3000 );
|
||
}
|
||
|
||
if (m_pAggroSystem)
|
||
{
|
||
int wholeAggro = m_pAggroSystem->GetAggroSum();
|
||
|
||
std::list<CDNAggroSystem::AggroStruct>& aggroList = m_pAggroSystem->GetAggroList();
|
||
std::list<CDNAggroSystem::AggroStruct>::iterator iter = aggroList.begin();
|
||
for( ; iter!=aggroList.end() ; ++iter)
|
||
{
|
||
CDNAggroSystem::AggroStruct& curAggro = *iter;
|
||
if (curAggro.hActor && curAggro.hActor->IsPlayerActor())
|
||
{
|
||
CDnPlayerActor* pActor = static_cast<CDnPlayerActor*>(curAggro.hActor.GetPointer());
|
||
pActor->UpdateAssistScore(curAggro.iAggro, wholeAggro);
|
||
}
|
||
}
|
||
}
|
||
if (GetGameRoom())
|
||
{
|
||
GetGameRoom()->OnDie(GetActorHandle(), hHitter);
|
||
}
|
||
|
||
#ifdef PRE_ADD_MONSTER_CATCH
|
||
if( false == m_vlCatchedActors.empty() )
|
||
{
|
||
ReleaseAllActor();
|
||
}
|
||
#endif // #ifdef PRE_ADD_MONSTER_CATCH
|
||
}
|
||
|
||
void CDnMonsterActor::ProcessDie( LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
CDnActor::ProcessDie( LocalTime, fDelta );
|
||
}
|
||
|
||
void CDnMonsterActor::DropItems()
|
||
{
|
||
DNVector(CDnItem::RealDropItemStruct) vRealDropItemList;
|
||
vRealDropItemList.reserve( m_VecDropItemList.size() );
|
||
|
||
int iPercent = HackPenanty::Common::MaxRate - GetGameRoom()->GetHackPenalty();
|
||
for( DWORD i=0; i<m_VecDropItemList.size(); i++ )
|
||
{
|
||
CDnItem::DropItemStruct *pStruct = &m_VecDropItemList[i];
|
||
int nRotate = (int)( ( ( pStruct->nSeed % 360 ) / (float)m_VecDropItemList.size() ) * i );
|
||
|
||
if( _rand(GetRoom())%HackPenanty::Common::MaxRate < iPercent )
|
||
{
|
||
vRealDropItemList.push_back( CDnItem::RealDropItemStruct(*pStruct, nRotate) );
|
||
}
|
||
else
|
||
{
|
||
g_Log.Log(LogType::_DROPITEMPENALTY, L"[%d] RoomID=%d HackPenalty=%d ItemID=%d Miss!!!\n", g_Config.nManagedID, GetGameRoom()->GetRoomID(), GetGameRoom()->GetHackPenalty(), pStruct->nItemID );
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_FATIGUE_DROPITEM_PENALTY )
|
||
if( CDnWorld::GetInstance(GetRoom()).GetMapSubType() == EWorldEnum::MapSubTypeNone)
|
||
{
|
||
int iFatigueDropPercent = GetGameRoom()->GetFatigueDropRate();
|
||
if( iFatigueDropPercent < 100 )
|
||
{
|
||
for( UINT i=0 ; i<vRealDropItemList.size() ; ++i )
|
||
{
|
||
if( _roomrand(GetRoom())%100 >= iFatigueDropPercent )
|
||
{
|
||
vRealDropItemList.erase( vRealDropItemList.begin()+i );
|
||
--i;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif // #if defined( PRE_FATIGUE_DROPITEM_PENALTY )
|
||
|
||
EtVector3 vPos = *GetPosition();
|
||
|
||
for( DWORD i=0 ; i<vRealDropItemList.size() ; ++i )
|
||
{
|
||
CDnItem::RealDropItemStruct* pStruct = &vRealDropItemList[i];
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
CDnDropItem::DropItem( GetRoom(), vPos, pStruct->dwUniqueID, pStruct->nItemID, pStruct->nSeed, pStruct->cOption, pStruct->nCount, pStruct->nRotate, -1, pStruct->nEnchantID );
|
||
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
CDnDropItem::DropItem( GetRoom(), vPos, pStruct->dwUniqueID, pStruct->nItemID, pStruct->nSeed, pStruct->cOption, pStruct->nCount, pStruct->nRotate );
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
}
|
||
|
||
if( !vRealDropItemList.empty() )
|
||
{
|
||
for( DWORD i=0; i<GetGameRoom()->GetUserCount(); i++ )
|
||
{
|
||
CDNUserSession* pGameSession = GetGameRoom()->GetUserData(i);
|
||
if( pGameSession && pGameSession->GetState() == SESSION_STATE_GAME_PLAY )
|
||
SendGameDropItemList( pGameSession, vPos, vRealDropItemList );
|
||
}
|
||
}
|
||
|
||
SAFE_DELETE_VEC( m_VecDropItemList );
|
||
}
|
||
|
||
void CDnMonsterActor::OnDrop( float fCurVelocity )
|
||
{
|
||
if( IsAir() ) {
|
||
if( !IsHit() ) {
|
||
char szStr[64];
|
||
sprintf_s( szStr, "%s_Landing", GetCurrentAction() );
|
||
if( IsExistAction( szStr ) )
|
||
{
|
||
SetActionQueue( szStr, 0, 2.f, 0.f, true, false );
|
||
|
||
// <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD> ü<>ξ<CEBE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||
if( m_hProcessSkill )
|
||
{
|
||
m_hProcessSkill->AddUseActionName( szStr );
|
||
m_hProcessSkill->OnChainInput( szStr );
|
||
}
|
||
}
|
||
|
||
SetMovable( false );
|
||
}
|
||
else if( !IsDie() ) {
|
||
std::string szAction;
|
||
float fBlendFrame = 2.f;
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ӵ<EFBFBD><D3B5><EFBFBD> 10<31>̻<EFBFBD><CCBB≯<EFBFBD> bigBounce<63><65> <20>ѹ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||
if( fCurVelocity < -6.f && m_HitParam.vVelocity.y != 0.f && abs(m_HitParam.vVelocity.y) > 0.1f ) {
|
||
if( m_HitParam.vVelocity.y > 0.f ) {
|
||
m_HitParam.vVelocity.y *= 0.6f;
|
||
SetVelocityY( m_HitParam.vVelocity.y );
|
||
}
|
||
else { // <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٴ<EFBFBD><D9B4><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
m_HitParam.vVelocity.y *= -0.6f;
|
||
if( m_HitParam.vResistance.y > 0.f )
|
||
m_HitParam.vResistance.y *= -1.f;
|
||
SetVelocityY( m_HitParam.vVelocity.y );
|
||
|
||
if( m_HitParam.vVelocity.y > 0 && m_HitParam.vResistance.y <= 0 )
|
||
SetResistanceY( -15.0f );
|
||
else
|
||
SetResistanceY( m_HitParam.vResistance.y );
|
||
|
||
}
|
||
szAction = "Hit_AirBounce";
|
||
}
|
||
else {
|
||
szAction = "Down_SmallBounce";
|
||
fBlendFrame = 0.f;
|
||
}
|
||
SetActionQueue( szAction.c_str(), 0, fBlendFrame, 0.f, true, false );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::OnStop( EtVector3 &vPosition )
|
||
{
|
||
if( IsDie() ) return;
|
||
if( IsMove() ) CmdStop( "Stand" );
|
||
|
||
if( m_pAi ) m_pAi->OnStop(vPosition);
|
||
}
|
||
|
||
void CDnMonsterActor::OnBeginNaviMode()
|
||
{
|
||
if( IsDie() ) return;
|
||
std::string strPrevAction = m_hActor->GetCurrentAction();
|
||
|
||
bool bPrevIsMove = false;
|
||
if( IsMove() && !IsNaviMode() )
|
||
{
|
||
bPrevIsMove = true;
|
||
CmdStop( "Stand" );
|
||
}
|
||
|
||
if( m_pAi )
|
||
m_pAi->OnBeginNaviMode( strPrevAction.c_str(), bPrevIsMove );
|
||
}
|
||
|
||
void CDnMonsterActor::CmdMove( EtVector3 &vPos, const char *szActionName, int nLoopCount, float fBlendFrame )
|
||
{
|
||
if( !IsMovable() ) return;
|
||
|
||
MovePos( vPos, true );
|
||
if( SetActionQueue( szActionName, nLoopCount, fBlendFrame, 0.f, true ) == false ) return;
|
||
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
int nActionIndex = GetElementIndex( szActionName );
|
||
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &EtVec3toVec2( *GetMoveVectorZ() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( &EtVec3toVec2( *GetLookDir() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
|
||
Send( eActor::SC_CMDMOVE, &Stream );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
|
||
void CDnMonsterActor::CmdMove( DnActorHandle hActor, float fMinDistance, const char *szActionName, int nLoopCount, float fBlendFrame )
|
||
{
|
||
if( !IsMovable() )
|
||
return;
|
||
|
||
bool bIsNaviMode = m_hActor->IsNaviMode();
|
||
MoveTarget( hActor, fMinDistance );
|
||
if( SetActionQueue( szActionName, nLoopCount, fBlendFrame, 0.f, !bIsNaviMode ) == false )
|
||
return;
|
||
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
int nActionIndex = GetElementIndex( szActionName );
|
||
DWORD dwUniqueID = hActor->GetUniqueID();
|
||
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &dwUniqueID, sizeof(DWORD) );
|
||
Stream.Write( &fMinDistance, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 1.f );
|
||
Stream.Write( &EtVec3toVec2( *GetMoveVectorZ() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( &EtVec3toVec2( *GetLookDir() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
|
||
Send( eActor::SC_CMDMOVETARGET, &Stream );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
|
||
bool CDnMonsterActor::_bIsCheckVaildPosition( EtVector3& vTargetPos )
|
||
{
|
||
// Ÿ<><C5B8> <20><EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20><><EFBFBD><EFBFBD> <20>˻<EFBFBD>
|
||
CEtWorldGrid* pGrid = INSTANCE(CDnWorld).GetGrid();
|
||
if( IsMovable() && pGrid )
|
||
{
|
||
NavigationMesh* pNavMesh = pGrid->GetNavMesh( vTargetPos );
|
||
if( pNavMesh )
|
||
{
|
||
NavigationCell* pCurCell = pNavMesh->FindClosestCell( vTargetPos );
|
||
if( pCurCell && pCurCell->IsPointInCellCollumn( vTargetPos ) )
|
||
return true;
|
||
}
|
||
}
|
||
|
||
if( !IsDie() ) CmdStop( "Stand" );
|
||
return false;
|
||
}
|
||
|
||
void CDnMonsterActor::_SendCmdMoveNavi( EtVector3& vTargetPos, float fMinDistance, const char* szActionName, int nLoopCount )
|
||
{
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
int nActionIndex = GetElementIndex( szActionName );
|
||
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &vTargetPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &fMinDistance, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 1.f );
|
||
Stream.Write( &EtVec3toVec2( *GetMoveVectorZ() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( &EtVec3toVec2( *GetLookDir() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
|
||
Send( eActor::SC_CMDMOVETARGET_NAVI, &Stream );
|
||
}
|
||
|
||
void CDnMonsterActor::CmdMoveNavi( DnActorHandle hActor, float fMinDistance, const char *szActionName, int nLoopCount, float fBlendFrame )
|
||
{
|
||
// Ÿ<><C5B8><EFBFBD><EFBFBD> <20><EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20>ۿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>
|
||
if( !_bIsCheckVaildPosition( *hActor->GetPosition() ) )
|
||
return;
|
||
//
|
||
bool bAlreadyNaviMode = m_hActor->IsNaviMode();
|
||
MoveTargetNavi( hActor, fMinDistance, szActionName );
|
||
if( !m_hActor->IsNaviMode() )
|
||
return CmdStop( "Stand" );
|
||
if( (bAlreadyNaviMode && GetWayPointSize() <= 2) )
|
||
return CmdStop( "Stand" );
|
||
if( SetActionQueue( szActionName, -1, fBlendFrame, 0.f, !bAlreadyNaviMode ) == false )
|
||
return;
|
||
// <20><>Ŷ
|
||
_SendCmdMoveNavi( *hActor->GetPosition(), fMinDistance, szActionName, nLoopCount );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
|
||
void CDnMonsterActor::CmdMoveNavi( EtVector3& vTargetPos, float fMinDistance, const char *szActionName, int nLoopCount, float fBlendFrame )
|
||
{
|
||
// Ÿ<><C5B8><EFBFBD><EFBFBD> <20><EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20>ۿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>
|
||
if( !_bIsCheckVaildPosition( vTargetPos ) )
|
||
return;
|
||
//
|
||
bool bAlreadyNaviMode = m_hActor->IsNaviMode();
|
||
MoveTargetNavi( vTargetPos, fMinDistance, szActionName );
|
||
if( !m_hActor->IsNaviMode() )
|
||
return CmdStop( "Stand" );
|
||
if( SetActionQueue( szActionName, -1, fBlendFrame, 0.f, !bAlreadyNaviMode ) == false )
|
||
return;
|
||
// <20><>Ŷ
|
||
_SendCmdMoveNavi( vTargetPos, fMinDistance, szActionName, nLoopCount );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
|
||
void CDnMonsterActor::CmdStop( const char *szActionName, int nLoopCount, float fBlendFrame, float fStartFrame )
|
||
{
|
||
if( SetActionQueue( szActionName, nLoopCount, fBlendFrame, fStartFrame, true ) == false ) return;
|
||
|
||
ResetMove();
|
||
ResetLook();
|
||
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
int nActionIndex = GetElementIndex( szActionName );
|
||
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
|
||
Send( eActor::SC_CMDSTOP, &Stream );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
|
||
void CDnMonsterActor::CmdAction( const char *szActionName, int nLoopCount /*= 0*/, float fBlendFrame /*= 3.f*/,
|
||
bool bCheckOverlapAction /*= true*/, bool bFromStateBlow /*= false */, bool bSkillChain/* = false*/ )
|
||
{
|
||
// mp <20>Ҹ<EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD> <20>Ұ<EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ϳ<EFBFBD><CDBF>Դ<EFBFBD> attack state <20>ִ<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD>ġ <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD>. (#13032)
|
||
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_078 ) )
|
||
{
|
||
if( IsAttack( szActionName ) )
|
||
return;
|
||
}
|
||
|
||
if( SetActionQueue( szActionName, nLoopCount, fBlendFrame, 0.f, bCheckOverlapAction ) == false )
|
||
return;
|
||
|
||
int nActionIndex = GetElementIndex( szActionName );
|
||
bool bAILook = bIsAILook();
|
||
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &nLoopCount, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
Stream.Write( &fBlendFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 1.f );
|
||
Stream.Write( &bAILook, sizeof(bool) );
|
||
if( bAILook )
|
||
Stream.Write( m_pAi->GetAILook(), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
else
|
||
Stream.Write( &EtVec3toVec2( *GetLookDir() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &bFromStateBlow, sizeof(bool) );
|
||
|
||
#if defined( PRE_FIX_MOVEBACK )
|
||
bool bNearMoveBack = IsPrevMoveBack();
|
||
Stream.Write( &bNearMoveBack, sizeof(bool));
|
||
#endif
|
||
|
||
Send( eActor::SC_CMDACTION, &Stream );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
|
||
void CDnMonsterActor::CmdLook( EtVector2 &vVec, bool bForce )
|
||
{
|
||
Look( vVec, bForce );
|
||
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
Stream.Write( &vVec, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( &bForce, sizeof(bool) );
|
||
|
||
Send( eActor::SC_CMDLOOK, &Stream );
|
||
}
|
||
|
||
void CDnMonsterActor::CmdLook( DnActorHandle hActor, bool bLock )
|
||
{
|
||
if( bLock ) LookTarget( hActor );
|
||
else {
|
||
if( !hActor ) ResetLook();
|
||
else {
|
||
EtVector2 vVec;
|
||
vVec.x = hActor->GetPosition()->x - GetPosition()->x;
|
||
vVec.y = hActor->GetPosition()->z - GetPosition()->z;
|
||
EtVec2Normalize( &vVec, &vVec );
|
||
Look( vVec );
|
||
}
|
||
}
|
||
|
||
BYTE pBuffer[128];
|
||
CMemoryStream Stream( pBuffer, 128 );
|
||
|
||
DWORD dwUniqueID = ( hActor ) ? hActor->GetUniqueID() : -1;
|
||
Stream.Write( &dwUniqueID, sizeof(DWORD) );
|
||
Stream.Write( &bLock, sizeof(bool) );
|
||
|
||
Send( eActor::SC_CMDLOOKTARGET, &Stream );
|
||
}
|
||
|
||
int CDnMonsterActor::CmdAddStateEffect( const CDnSkill::SkillInfo* pParentSkill, STATE_BLOW::emBLOW_INDEX emBlowIndex, int nDurationTime,
|
||
const char *szParam, bool bOnPlayerInit/* = false*/, bool bCheckCanBegin/* = true*/ , bool bEternity /* = false */ )
|
||
{
|
||
int iID = CDnActor::CmdAddStateEffect( pParentSkill, emBlowIndex, nDurationTime, szParam, bOnPlayerInit, bCheckCanBegin , bEternity );
|
||
if( -1 == iID )
|
||
return -1;
|
||
|
||
DnBlowHandle hAddedBlow = m_pStateBlow->GetStateBlowFromID( iID );
|
||
|
||
const CPacketCompressStream* pPacketStream = hAddedBlow->GetPacketStream( szParam, false );
|
||
Send( eActor::SC_CMDADDSTATEEFFECT, const_cast<CPacketCompressStream*>(pPacketStream) );
|
||
|
||
return iID;
|
||
}
|
||
|
||
void CDnMonsterActor::CmdRemoveStateEffect( STATE_BLOW::emBLOW_INDEX emBlowIndex, bool bRemoveFromServerToo/* = true*/ )
|
||
{
|
||
if( m_pStateBlow->IsApplied( emBlowIndex ) )
|
||
{
|
||
if( bRemoveFromServerToo )
|
||
CDnActor::CmdRemoveStateEffect( emBlowIndex );
|
||
|
||
SendRemoveStateEffect( emBlowIndex );
|
||
}
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::SendRemoveStateEffect( STATE_BLOW::emBLOW_INDEX emBlowIndex )
|
||
{
|
||
BYTE pBuffer[32];
|
||
CPacketCompressStream Stream( pBuffer, 32 );
|
||
Stream.Write( &emBlowIndex, sizeof(STATE_BLOW::emBLOW_INDEX) );
|
||
|
||
Send( eActor::SC_CMDREMOVESTATEEFFECT, &Stream );
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::CmdSuicide( bool bDropItem, bool bDropExp )
|
||
{
|
||
if( IsDie() ) return;
|
||
SetDestroy();
|
||
|
||
if( m_hSummonerPlayerActor )
|
||
{
|
||
_ASSERT( m_hSummonerPlayerActor->IsPlayerActor() );
|
||
if( m_hSummonerPlayerActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(m_hSummonerPlayerActor.GetPointer());
|
||
pPlayerActor->OnDieSummonedMonster( GetMySmartPtr() );
|
||
}
|
||
}
|
||
|
||
if( bDropExp ) {
|
||
EnableDropItem( bDropItem );
|
||
OnDie( DnActorHandle() );
|
||
}
|
||
else {
|
||
if( bDropItem ) DropItems();
|
||
}
|
||
|
||
BYTE pBuffer[32];
|
||
CPacketCompressStream Stream( pBuffer, 32 );
|
||
Stream.Write( &bDropItem, sizeof(bool) );
|
||
Stream.Write( &bDropExp, sizeof(bool) );
|
||
Send( eActor::SC_CMDSUICIDE, &Stream );
|
||
}
|
||
|
||
void CDnMonsterActor::CmdMixedAction( const char *szActionBone, const char *szMaintenanceBone, const char *szActionName, float fFrame, float fBlendFrame )
|
||
{
|
||
int nActionIndex = GetElementIndex( szActionName );
|
||
int nMaintenanceBoneIndex = GetBoneIndex( szMaintenanceBone );
|
||
int nActionBoneIndex = GetBoneIndex( szActionBone );
|
||
|
||
int nBlendAniIndex = m_nAniIndex;
|
||
|
||
if( nActionIndex == -1 ) {
|
||
assert(0);
|
||
}
|
||
|
||
if( nActionBoneIndex == -1 || nMaintenanceBoneIndex == -1 )
|
||
return;
|
||
|
||
BYTE pBuffer[128] = {0,};
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &nActionBoneIndex, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
Stream.Write( &nMaintenanceBoneIndex, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
Stream.Write( &fFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.f );
|
||
Stream.Write( &fBlendFrame, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10.f );
|
||
|
||
Send( eActor::SC_CMDMIXEDACTION, &Stream );
|
||
|
||
|
||
}
|
||
|
||
void CDnMonsterActor::CmdWarp( EtVector3 &vPos, EtVector2 &vLook, CDNUserSession* pGameSession, bool bCheckPlayerFollowSummonedMonster/*=false*/ )
|
||
{
|
||
CDnActor::CmdWarp( vPos, vLook, pGameSession, bCheckPlayerFollowSummonedMonster );
|
||
|
||
MAWalkMovementNav *pMovement = dynamic_cast<MAWalkMovementNav *>(GetMovement());
|
||
if( pMovement ) pMovement->ValidateCurCell();
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::GenerationDropItem()
|
||
{
|
||
m_VecDropItemList.clear();
|
||
|
||
if( m_nItemDropGroupTableID < 1 ) return;
|
||
|
||
int nExtendDropRate = 0;
|
||
GetGameRoom()->GetExtendDropRateIgnoreTime(nExtendDropRate);
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
#else
|
||
#if defined(PRE_ADD_WEEKLYEVENT)
|
||
if (CDnWorld::GetInstance(GetRoom()).GetMapSubType() != EWorldEnum::MapSubTypeNest){
|
||
int nThreadID = GetGameRoom()->GetServerID();
|
||
|
||
int nEventValue = g_pDataManager->GetWeeklyEventValue(0, 0, WeeklyEvent::Event_10, nThreadID);
|
||
if (nEventValue != 0)
|
||
nExtendDropRate += nEventValue;
|
||
}
|
||
#endif // #if defined(PRE_ADD_WEEKLYEVENT)
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
#if defined( PRE_ADD_NEWCOMEBACK )
|
||
if( GetGameRoom() )
|
||
{
|
||
if( GetGameRoom()->GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetGameRoom()->GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
{
|
||
float fBlowValue = pPartyTask->GetPlayerDropUpBlowValue();
|
||
if( fBlowValue > 0 )
|
||
{
|
||
fBlowValue = fBlowValue * 100;
|
||
nExtendDropRate += (int)fBlowValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
#if defined( PRE_ADD_STAGE_WEIGHT )
|
||
if( GetGameRoom() && GetGameRoom()->GetTaskMng() )
|
||
{
|
||
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(GetGameRoom()->GetTaskMng()->GetTask("GameTask"));
|
||
if( pGameTask )
|
||
{
|
||
const TStageWeightData * pStageWeightData = pGameTask->GetStageWeightData();
|
||
if( pStageWeightData )
|
||
{
|
||
float fStageWeightBonus = pStageWeightData->fItemDropRate;
|
||
fStageWeightBonus = fStageWeightBonus * 100;
|
||
nExtendDropRate += (int)fStageWeightBonus;
|
||
}
|
||
}
|
||
}
|
||
#endif // #if defined( PRE_ADD_STAGE_WEIGHT )
|
||
|
||
float fCalcDropCount = ((float)((float)nExtendDropRate/100) + 1.0f);
|
||
for (int h = 0; 0 < fCalcDropCount; h++)
|
||
{
|
||
CDnDropItem::CalcDropItemList( GetRoom(), m_AIDifficult, m_nItemDropGroupTableID, m_VecDropItemList );
|
||
|
||
for( DWORD i=0; i<m_VecDropItemList.size(); i++ ) {
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
if( CDnDropItem::PreInitializeItem( GetRoom(), m_VecDropItemList[i].nItemID, m_VecDropItemList[i].nEnchantID ) == false )
|
||
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
if( CDnDropItem::PreInitializeItem( GetRoom(), m_VecDropItemList[i].nItemID ) == false )
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
{
|
||
m_VecDropItemList.erase( m_VecDropItemList.begin() + i );
|
||
i--;
|
||
}
|
||
}
|
||
|
||
fCalcDropCount -= 1.0f;
|
||
if (h >= 4 || (fCalcDropCount < 1.0f && ((float)(_rand(GetRoom())%100)/100) > fCalcDropCount))
|
||
break; //4<><34><EFBFBD>̻<EFBFBD>(<28>̺<EFBFBD>Ʈ3<C6AE><33>)<29><> <20>Ұ<EFBFBD><D2B0>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>, 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20>Ѵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD>
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::SetGenerationArea( SOBB &Box )
|
||
{
|
||
m_GenerationArea = Box;
|
||
}
|
||
|
||
SOBB *CDnMonsterActor::GetGenerationArea()
|
||
{
|
||
return &m_GenerationArea;
|
||
}
|
||
|
||
void CDnMonsterActor::SyncClassTime( LOCAL_TIME LocalTime )
|
||
{
|
||
MAActorRenderBase::m_LocalTime = LocalTime;
|
||
|
||
CDnActor::SyncClassTime( LocalTime );
|
||
}
|
||
|
||
void CDnMonsterActor::OnChangeAction( const char *szPrevAction )
|
||
{
|
||
if( m_pAi )
|
||
m_pAi->OnChangeAction( szPrevAction );
|
||
|
||
#ifdef PRE_ADD_AURA_FOR_MONSTER
|
||
_CheckActionWithProcessPassiveActionSkill(szPrevAction);
|
||
#endif
|
||
|
||
}
|
||
|
||
void CDnMonsterActor::_CheckActionWithProcessPassiveActionSkill( const char* szPrevAction )
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> <20><EFBFBD> <20>ݺ<EFBFBD><DDBA><EFBFBD><EFBFBD≯<EFBFBD> <20>н<EFBFBD>
|
||
if( szPrevAction && m_nPrevActionIndex == m_nActionIndex )
|
||
return;
|
||
|
||
// if instantly passive skill, then cancel skill. ( ex) archer's spinkick)
|
||
// because state effect must deactivate when change to another attack action.
|
||
if( m_hProcessSkill )
|
||
{
|
||
m_setUseActionName.clear();
|
||
m_setUseActionName.insert( szPrevAction );
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> prev <20><EFBFBD><D7BC><EFBFBD> next <20><EFBFBD><D7BC>̶<EFBFBD><CCB6><EFBFBD> <20><>ų<EFBFBD><C5B3> <20>̾<EFBFBD><CCBE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><EFBFBD><D7BC>̾<EFBFBD><CCBE><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> next <20><EFBFBD><D7BC><EFBFBD> <20>ƴ϶<C6B4><CFB6><EFBFBD>
|
||
// <20>нú<D0BD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD><C7B4>Ѵ<EFBFBD>.
|
||
ActionElementStruct* pElement = GetElement( szPrevAction );
|
||
bool bIsNextAction = false;
|
||
if( pElement )
|
||
{
|
||
// #25154 <20>⺻ <20><><EFBFBD>ĵ<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><>ų<EFBFBD><C5B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> next <20><EFBFBD><D7BC><EFBFBD> <20>̾<EFBFBD><CCBE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||
// <20><><EFBFBD><EFBFBD> <20><>ų <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>Լ<EFBFBD><D4BC><EFBFBD> ȣ<><C8A3><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> Stand <20><> <20>Ǿ<EFBFBD><C7BE>ִµ<D6B4> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// m_hProcessSkill <20><> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ǴܵǾ NULL <20><> <20>Ǿ<EFBFBD><C7BE><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
// m_hProcessSkill <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٸ<EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> onend <20><> <20><> <20>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵ<EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bIsNextAction <20><> false <20><> <20>ǰ<EFBFBD> m_hProcessSkill->IsUseSkillActionNames() <20>Լ<EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD>
|
||
// <20><>ų <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ǴܵǾ<DCB5><C7BE><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
bIsNextAction = ((pElement->szNextActionName != "Stand") && (pElement->szNextActionName == GetCurrentAction()));
|
||
}
|
||
|
||
if( false == bIsNextAction &&
|
||
m_hProcessSkill->IsUseActionNames( m_setUseActionName ) )
|
||
{
|
||
if( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) &&
|
||
m_hProcessSkill->GetDurationType() == CDnSkill::Instantly )
|
||
{
|
||
// <20>нú<D0BD> <20><>ų<EFBFBD><C5B3> ü<><C3BC> <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> üũ<C3BC>Ѵ<EFBFBD>. <20>ѹ<EFBFBD> üũ<C3BC>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD> ü<><C3BC> <20>Է<EFBFBD> <20>÷<EFBFBD><C3B7>״<EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD>ȴ<EFBFBD>.
|
||
// ü<><C3BC><EFBFBD>ԷµǴ<C2B5> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD≯<EFBFBD>ŭ <20>нú<D0BD> <20><>ų <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̰<EFBFBD> <20>þ<C3BE><EEB3AD>.
|
||
// <20>̷<EFBFBD><CCB7><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD> <20>ð<EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>нú<D0BD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> ü<><C3BC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if( false == m_hProcessSkill->CheckChainingPassiveSkill() )
|
||
{
|
||
m_hProcessSkill->OnEnd( MAActorRenderBase::m_LocalTime, 0.0f );
|
||
m_hProcessSkill.Identity();
|
||
}
|
||
}
|
||
else
|
||
// Note <20>ѱ<EFBFBD>: m_hProcessSkill <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȿ<EFBFBD>ؾ<EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CDnPlayerActor::CmdStop() <20>ʿ<EFBFBD><CABF><EFBFBD> <20>ɷ<EFBFBD><C9B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> <20><EFBFBD> <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// ó<><C3B3><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CDnActor::OnChangeAction <20>ʿ<EFBFBD><CABF><EFBFBD> ProcessAction <20><> Identity <20><>Ŵ.
|
||
if( IsEnabledAuraSkill() && m_hProcessSkill->IsAuraOn() )
|
||
{
|
||
m_hProcessSkill.Identity();
|
||
ClearSelfStateSignalBlowQueue(); // <20><><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20>ڱ<EFBFBD> <20>ڽſ<DABD><C5BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> Ÿ<>̹<EFBFBD> <20>ñ׳ο<D7B3> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> ť <20>ʱ<EFBFBD>ȭ <20><>Ŵ. <20>ȱ<C8B1> <20>ٸ<EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD>.
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::OnFinishAction(const char* szPrevAction, LOCAL_TIME time)
|
||
{
|
||
if( m_bChangeAxisOnFinishAction )
|
||
{
|
||
EtVector2 vView = EtVec3toVec2( *GetLookDir() );
|
||
vView *= -1.f;
|
||
Look( vView, true );
|
||
m_bChangeAxisOnFinishAction = false;
|
||
}
|
||
|
||
if( m_pAi )
|
||
m_pAi->OnFinishAction(szPrevAction, time);
|
||
}
|
||
|
||
void CDnMonsterActor::ResetActor()
|
||
{
|
||
if( m_pAi )
|
||
m_pAi->ResetDelay();
|
||
}
|
||
|
||
void CDnMonsterActor::OnBeginStateBlow( DnBlowHandle hBlow )
|
||
{
|
||
CDnActor::OnBeginStateBlow( hBlow );
|
||
|
||
if( m_pAggroSystem )
|
||
m_pAggroSystem->OnStateBlowAggro( hBlow );
|
||
}
|
||
|
||
// MASkillUser
|
||
#ifdef PRE_FIX_GAMESERVER_OPTIMIZE
|
||
void CDnMonsterActor::OnAddSkill( DnSkillHandle hSkill, bool isInitialize/* = false*/ )
|
||
{
|
||
// <20>нú<D0BD> <20≯鼭 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> Self <20><> <20>پ<EFBFBD><D9BE>ִ<EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>..
|
||
bool bPassiveBuff = false;
|
||
|
||
bPassiveBuff = ApplyPassiveSkill( hSkill, isInitialize );
|
||
|
||
if( bPassiveBuff )
|
||
m_vlhSelfPassiveBlowSkill.push_back( hSkill );
|
||
}
|
||
|
||
bool CDnMonsterActor::AddSkill( int nSkillTableID, int nLevel/* = 1*/, int iSkillLevelApplyType/* = CDnSkill::PVE*/ )
|
||
{
|
||
if( IsExistSkill( nSkillTableID, nLevel ) ) return false;
|
||
if( !MASkillUser::IsValidActor() ) return false;
|
||
if( GetRoom() == NULL ) return false;
|
||
|
||
DnSkillHandle hSkill = CDnSkill::CreateMonsterSkill( GetMySmartPtr(), nSkillTableID, nLevel );
|
||
if( !hSkill ) return false;
|
||
|
||
#ifdef PRE_ADD_AURA_FOR_MONSTER
|
||
CDnSkill::DurationTypeEnum eDurationType = hSkill->GetDurationType();
|
||
switch(eDurationType)
|
||
{
|
||
case CDnSkill::Aura:
|
||
m_vlhAuraSkills.push_back(hSkill);
|
||
}
|
||
#endif
|
||
|
||
#ifndef PRE_FIX_SKILLLIST
|
||
m_vlhSkillList.push_back( hSkill );
|
||
m_vbSelfAllocList.push_back( true );
|
||
#else
|
||
AddSkillObject( S_SKILL_OBJECT(hSkill, true) );
|
||
#endif // #ifndef PRE_FIX_SKILLLIST
|
||
|
||
if( hSkill->GetActor() )
|
||
hSkill->SetHasActor( GetMySmartPtr() );
|
||
|
||
OnAddSkill( hSkill );
|
||
|
||
return true;
|
||
}
|
||
#endif // #ifdef PRE_FIX_GAMESERVER_OPTIMIZE
|
||
|
||
bool CDnMonsterActor::ExecuteSkill( DnSkillHandle hSkill, LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
if ( CDnActor::ExecuteSkill(hSkill, LocalTime, fDelta) == false )
|
||
return false;
|
||
|
||
BYTE pBuffer[128] = {0,};
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
int nSkillID = hSkill->GetClassID();
|
||
char cLevel = hSkill->GetLevel();
|
||
|
||
Stream.Write( &nSkillID, sizeof(int) );
|
||
Stream.Write( &cLevel, sizeof(char) );
|
||
Stream.Write( &EtVec3toVec2( *GetLookDir() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
#if defined( PRE_ADD_ACADEMIC )
|
||
int iSummonerSkillID = 0;
|
||
DnSkillHandle hSummonerSkill = FindSkill( nSkillID );
|
||
if( hSummonerSkill )
|
||
iSummonerSkillID = hSummonerSkill->GetSummonerDecreaseSPSkillID();
|
||
Stream.Write( &iSummonerSkillID, sizeof(int) );
|
||
#endif // #if defined( PRE_ADD_ACADEMIC )
|
||
|
||
Send( eActor::SC_USESKILL, &Stream );
|
||
|
||
ResetPositionRevision();
|
||
|
||
return true;
|
||
}
|
||
|
||
CDnSkill::UsingResult CDnMonsterActor::UseSkill( int nSkillTableID, bool bCheckValid/* = true*/, bool bAutoUseFromServer/* = false*/, int nLuaSkillIndex/*=-1*/ )
|
||
{
|
||
CDnSkill::UsingResult Result = MASkillUser::UseSkill( nSkillTableID, bCheckValid, bAutoUseFromServer );
|
||
if( Result == CDnSkill::UsingResult::Success && nLuaSkillIndex >= 0 )
|
||
{
|
||
std::map<int,int>::iterator itor = m_mUseSkillCount.find( nLuaSkillIndex );
|
||
if( itor == m_mUseSkillCount.end() )
|
||
{
|
||
m_mUseSkillCount.insert( std::make_pair(nLuaSkillIndex,1) );
|
||
}
|
||
else
|
||
{
|
||
++(*itor).second;
|
||
}
|
||
}
|
||
|
||
return Result;
|
||
}
|
||
|
||
int CDnMonsterActor::GetUseSkillCount( int iLuaSkillIndex )
|
||
{
|
||
std::map<int,int>::iterator itor = m_mUseSkillCount.find( iLuaSkillIndex );
|
||
if( itor != m_mUseSkillCount.end() )
|
||
return (*itor).second;
|
||
|
||
return 0;
|
||
}
|
||
|
||
void CDnMonsterActor::SetScale( float fValue )
|
||
{
|
||
m_fScale = fValue;
|
||
if( m_hObject ) {
|
||
m_hObject->SetCollisionScale( m_fScale );
|
||
}
|
||
MAActorRenderBase::SetScale( EtVector3( m_fScale, m_fScale, m_fScale ) );
|
||
|
||
if( m_fWeight == 0.f ) m_fRevisionWeight = 0.f;
|
||
else m_fRevisionWeight = m_fWeight + ( ( m_fScale - 1.f ) * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ScaleWeightValue ) );
|
||
}
|
||
|
||
float CDnMonsterActor::GetWeight()
|
||
{
|
||
return m_fRevisionWeight;
|
||
}
|
||
|
||
float CDnMonsterActor::GetThreatRange()
|
||
{
|
||
_ASSERT( dynamic_cast<CDNMonsterAggroSystem*>(m_pAggroSystem) );
|
||
return m_pAggroSystem ? static_cast<CDNMonsterAggroSystem*>(m_pAggroSystem)->GetThreatRange() : 0.f;
|
||
}
|
||
|
||
float CDnMonsterActor::GetCognizanceThreatRange()
|
||
{
|
||
_ASSERT( dynamic_cast<CDNMonsterAggroSystem*>(m_pAggroSystem) );
|
||
return m_pAggroSystem ? static_cast<CDNMonsterAggroSystem*>(m_pAggroSystem)->GetCognizanceThreatRange() : 0.f;
|
||
}
|
||
|
||
float CDnMonsterActor::GetCognizanceThreatRangeSq()
|
||
{
|
||
_ASSERT( dynamic_cast<CDNMonsterAggroSystem*>(m_pAggroSystem) );
|
||
return m_pAggroSystem ? static_cast<CDNMonsterAggroSystem*>(m_pAggroSystem)->GetCognizanceThreatRangeSq() : 0.f;
|
||
}
|
||
|
||
std::string CDnMonsterActor::GetAIFileName()
|
||
{
|
||
DNTableFileFormat* pSox = NULL;
|
||
int nItemID = 0;
|
||
|
||
if( m_nMonsterWeightTableID == -1 )
|
||
{
|
||
pSox = GetDNTable( CDnTableDB::TMONSTER );
|
||
nItemID = m_nMonsterClassID;
|
||
}
|
||
else
|
||
{
|
||
pSox = GetDNTable( CDnTableDB::TMONSTERWEIGHT );
|
||
nItemID = m_nMonsterWeightTableID;
|
||
}
|
||
|
||
if( !pSox || !pSox->IsExistItem( nItemID ) )
|
||
return std::string("");
|
||
std::string szName = pSox->GetFieldFromLablePtr( nItemID, "_CustomAI" )->GetString();
|
||
|
||
return szName;
|
||
}
|
||
|
||
void CDnMonsterActor::CalcMonsterWeightIndex()
|
||
{
|
||
if( m_nMonsterClassID == 0 ) return;
|
||
DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TMONSTERWEIGHT );
|
||
if( !pSox )
|
||
{
|
||
g_Log.Log( LogType::_FILELOG, L"MonsterWeightTable.ext failed\r\n");
|
||
return;
|
||
}
|
||
|
||
std::vector<int> nVecList;
|
||
pSox->GetItemIDListFromField( "_MonsterTableIndex", m_nMonsterClassID, nVecList );
|
||
|
||
int nDifficulty;
|
||
for( DWORD i=0; i<nVecList.size(); i++ ) {
|
||
nDifficulty = pSox->GetFieldFromLablePtr( nVecList[i], "_Difficulty" )->GetInteger();
|
||
if( nDifficulty == m_AIDifficult ) {
|
||
m_nMonsterWeightTableID = nVecList[i];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::SetNaviDestination( SOBB* pOBB, UINT uiMoveFrontRate )
|
||
{
|
||
if( m_pAi )
|
||
m_pAi->OnInitNaviDestination( pOBB, uiMoveFrontRate );
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
|
||
int CDnMonsterActor::GetWaitOrderCount( int iSkillID )
|
||
{
|
||
std::map<int,int>::iterator itor = m_mOrderCount.find( iSkillID );
|
||
if( itor == m_mOrderCount.end() )
|
||
return 0;
|
||
return (*itor).second;
|
||
}
|
||
|
||
void CDnMonsterActor::AddWaitOrderCount( int iSkillID )
|
||
{
|
||
std::map<int,int>::iterator itor = m_mOrderCount.find( iSkillID );
|
||
if( itor == m_mOrderCount.end() )
|
||
{
|
||
m_mOrderCount.insert( std::make_pair(iSkillID,1) );
|
||
return;
|
||
}
|
||
++(*itor).second;
|
||
}
|
||
|
||
void CDnMonsterActor::DelWaitOrderCount( int iSkillID )
|
||
{
|
||
std::map<int,int>::iterator itor = m_mOrderCount.find( iSkillID );
|
||
if( itor == m_mOrderCount.end() )
|
||
return;
|
||
if( (*itor).second > 0 )
|
||
--(*itor).second;
|
||
}
|
||
|
||
bool CDnMonsterActor::OnAINonTarget()
|
||
{
|
||
// Walk_Font <20><EFBFBD> <20>˻<EFBFBD>
|
||
if( !IsExistAction( "Walk_Front") )
|
||
return true;
|
||
|
||
if ( !IsHit() && IsMove() )
|
||
CmdStop( "Stand", 0, g_fBendFrame );
|
||
|
||
if ( !IsMovable() )
|
||
return false;
|
||
|
||
// <20><EFBFBD><EEBDBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD>.
|
||
EtVector3 *pvPos = m_hActor->GetPosition();
|
||
EtVector3 vTemp;
|
||
vTemp = *pvPos;
|
||
vTemp.y = 0.f;
|
||
vTemp.x += cos( EtToRadian( _rand(m_hActor->GetRoom())%360 ) ) * ( 300 + _rand(m_hActor->GetRoom())%200 );
|
||
vTemp.z += sin( EtToRadian( _rand(m_hActor->GetRoom())%360 ) ) * ( 300 + _rand(m_hActor->GetRoom())%200 );
|
||
|
||
SOBB Box = *GetGenerationArea();
|
||
Box.Extent[1] = 1000000.f;
|
||
if( !Box.IsInside( vTemp ) )
|
||
{
|
||
vTemp = Box.Center;
|
||
vTemp -= Box.Axis[0] * Box.Extent[0];
|
||
vTemp -= Box.Axis[2] * Box.Extent[2];
|
||
|
||
int iModValue = static_cast<int>(Box.Extent[0] * 2.f);
|
||
if( iModValue > 0 ) vTemp += Box.Axis[0] * (float)( _rand(m_hActor->GetRoom())%iModValue );
|
||
else vTemp += Box.Axis[0];
|
||
|
||
iModValue = static_cast<int>(Box.Extent[2] * 2.f);
|
||
if( iModValue ) vTemp += Box.Axis[2] * (float)( _rand(m_hActor->GetRoom())%iModValue );
|
||
else vTemp += Box.Axis[2];
|
||
|
||
vTemp.y = CDnWorld::GetInstance(m_hActor->GetRoom()).GetHeight( vTemp );
|
||
vTemp += Box.Axis[1] * Box.Extent[1];
|
||
}
|
||
|
||
CmdMove( vTemp, "Walk_Front", -1, g_fBendFrame );
|
||
|
||
return true;
|
||
}
|
||
|
||
void CDnMonsterActor::OnBumpWall()
|
||
{
|
||
if( !m_pszCanBumpActionName )
|
||
return;
|
||
|
||
CmdAction( m_pszCanBumpActionName, 0, g_fBendFrame );
|
||
}
|
||
|
||
// <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// <20><> <20>κ<EFBFBD><CEBA><EFBFBD> CDnProjectile::GetPacketStream() <20><> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>ñ׳<C3B1> <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><EFBFBD>ü <20>ñ׳<C3B1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִµ<D6B4> <20>ϴ<EFBFBD> <20>״<EFBFBD><D7B4><EFBFBD> <20>Ӵϴ<D3B4>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٵ<EFBFBD><D9B5><EFBFBD> <20>Ҷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>մϴ<D5B4>. - <20>ѱ<EFBFBD>.
|
||
void CDnMonsterActor::SendProjectile( CDnProjectile *pProjectile, ProjectileStruct* pStruct, MatrixEx& LocalCross, int iSignalIndex )
|
||
{
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
DWORD dwVal = pProjectile->GetUniqueID();
|
||
Stream.Write( &dwVal, sizeof(DWORD) );
|
||
Stream.Write( &LocalCross.m_vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &LocalCross.m_vXAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
|
||
Stream.Write( &LocalCross.m_vYAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
|
||
Stream.Write( &LocalCross.m_vZAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
|
||
|
||
#if defined(PRE_FIX_55378)
|
||
int nActionIndex = m_nActionIndex;
|
||
|
||
std::string szChargerAction = GetChargerAction();
|
||
if (szChargerAction.empty() == false)
|
||
nActionIndex = GetElementIndex(szChargerAction.c_str());
|
||
|
||
Stream.Write( &nActionIndex, sizeof(int) );
|
||
#else
|
||
Stream.Write( &m_nActionIndex, sizeof(int) );
|
||
#endif // PRE_FIX_55378
|
||
|
||
Stream.Write( &iSignalIndex, sizeof(int) );
|
||
|
||
bool bUsedForceDir = pProjectile->IsUsedForceDir();
|
||
Stream.Write( &bUsedForceDir, sizeof(bool) );
|
||
if( bUsedForceDir )
|
||
{
|
||
const EtVector3& vForceDir = pProjectile->GetForceDir();
|
||
Stream.Write( &vForceDir, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
|
||
}
|
||
|
||
switch( pStruct->nTargetType )
|
||
{
|
||
case 2: // TargetPosition
|
||
{
|
||
Stream.Write( pProjectile->GetTargetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
break;
|
||
}
|
||
case 3: // Target
|
||
{
|
||
DnActorHandle hTarget = pProjectile->GetTargetActor();
|
||
if( !hTarget )
|
||
hTarget = GetActorHandle();
|
||
|
||
dwVal = hTarget->GetUniqueID();
|
||
Stream.Write( &dwVal, sizeof(DWORD) );
|
||
break;
|
||
}
|
||
}
|
||
|
||
Send( eActor::SC_PROJECTILE, &Stream );
|
||
}
|
||
|
||
|
||
// #15557 <20>̽<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD> <20><EFBFBD>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
// <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> LocalPlayerActor <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD> <20><> <20><EFBFBD>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><>Ŷ<EFBFBD><C5B6> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ݵ<EFBFBD><DDB5><EFBFBD> CDnLocalPlayerActor::OnProjectile() <20>ʵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><>.
|
||
void CDnMonsterActor::SendProjectileFromProjectile( CDnProjectile* pProjectile, int nSignalIndex )
|
||
{
|
||
CPacketCompressStream* pPacketStream = pProjectile->GetPacketStream();
|
||
_ASSERT( pPacketStream );
|
||
|
||
if( pPacketStream )
|
||
Send( eActor::SC_MONSTER_PROJECTILE_FROM_PROJECTILE, pPacketStream );
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex )
|
||
{
|
||
switch( Type ) {
|
||
case STE_LockTargetLook:
|
||
{
|
||
#if defined( PRE_MOD_LOCK_TARGET_LOOK )
|
||
LockTargetLookStruct * pStruct = static_cast<LockTargetLookStruct*>(pPtr);
|
||
m_nLockLookEventArea = pStruct->LookEeventAreaID;
|
||
#endif // PRE_MOD_LOCK_TARGET_LOOK
|
||
|
||
#if defined( PRE_FIX_MOVEBACK )
|
||
if( !IsNearMoveBack() )
|
||
m_bLockLookTarget = true;
|
||
#else
|
||
m_bLockLookTarget = true;
|
||
#endif
|
||
break;
|
||
}
|
||
case STE_CanBumpWall:
|
||
{
|
||
CanBumpWallStruct* pStruct = static_cast<CanBumpWallStruct*>(pPtr);
|
||
m_pszCanBumpActionName = pStruct->szActionName;
|
||
break;
|
||
}
|
||
case STE_Projectile:
|
||
{
|
||
ProjectileStruct* pStruct = (ProjectileStruct *)pPtr;
|
||
// MultipleŸ<65><C5B8><EFBFBD≯<EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Projectile <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><EFBFBD>
|
||
#if defined (PRE_MOD_AIMULTITARGET)
|
||
if( static_cast<MAAiScript*>(GetAIBase())->m_cMultipleTarget.GetMultipleTarget() > 0 )
|
||
#else
|
||
if( static_cast<MAAiScript*>(GetAIBase())->m_cMultipleTarget.bIsMultipleTarget() )
|
||
#endif
|
||
{
|
||
static_cast<MAAiScript*>(GetAIBase())->m_cMultipleTarget.CreateProjectile( this, static_cast<ProjectileStruct*>(pPtr), nSignalIndex );
|
||
}
|
||
else
|
||
{
|
||
DNVector(DnActorHandle) StigmaActorList;
|
||
if (pStruct->nTargetStateIndex != 0)
|
||
{
|
||
ScanActorByStateIndex(StigmaActorList, STATE_BLOW::BLOW_246);
|
||
}
|
||
|
||
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>츸 ó<><C3B3>
|
||
if (StigmaActorList.empty() == false)
|
||
{
|
||
int nStigmaActorCount = (int)StigmaActorList.size();
|
||
for (int i = 0; i < nStigmaActorCount; ++i)
|
||
{
|
||
//Ÿ<><C5B8> <20><><EFBFBD><EFBFBD>..
|
||
DnActorHandle hTargetActor = StigmaActorList[i];
|
||
|
||
CDnProjectile* pProjectile = CDnProjectile::CreateProjectile( GetRoom(), GetMySmartPtr(), m_Cross, pStruct, NULL, hTargetActor );
|
||
if( pProjectile == NULL )
|
||
return;
|
||
pProjectile->SetShooterType( GetMySmartPtr(), m_nActionIndex, nSignalIndex );
|
||
|
||
SendProjectile( pProjectile, pStruct, m_Cross, nSignalIndex );
|
||
OnProjectile( pProjectile, pStruct, m_Cross, nSignalIndex );
|
||
OnSkillProjectile( pProjectile );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//#52808 - <20>߰<EFBFBD> <20><>û (<28><><EFBFBD>ο<EFBFBD> <20><EFBFBD>ü <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD>ü <20><><EFBFBD><EFBFBD> <20>ȵ<EFBFBD>.
|
||
if (pStruct->nTargetStateIndex == 2)
|
||
return;
|
||
|
||
CDnProjectile* pProjectile = CDnProjectile::CreateProjectile( GetRoom(), GetMySmartPtr(), m_Cross, pStruct );
|
||
|
||
if( pProjectile == NULL )
|
||
return;
|
||
pProjectile->SetShooterType( GetMySmartPtr(), m_nActionIndex, nSignalIndex );
|
||
|
||
SendProjectile( pProjectile, pStruct, m_Cross, nSignalIndex );
|
||
OnProjectile( pProjectile, pStruct, m_Cross, nSignalIndex );
|
||
OnSkillProjectile( pProjectile );
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
case STE_ProjectileTargetPosition:
|
||
{
|
||
if( m_pAi )
|
||
m_pAi->SetProjectileTarget();
|
||
break;
|
||
}
|
||
|
||
case STE_ReserveProjectileTarget:
|
||
{
|
||
if( m_pAi )
|
||
m_pAi->ReservedProjectileTarget();
|
||
|
||
break;
|
||
}
|
||
|
||
case STE_RotateResistance:
|
||
{
|
||
RotateResistanceStruct *pStruct = (RotateResistanceStruct *)pPtr;
|
||
m_fRotateResistance = pStruct->fResistanceRatio;
|
||
break;
|
||
}
|
||
case STE_PositionRevision:
|
||
{
|
||
PositionRevisionStruct* pStruct = reinterpret_cast<PositionRevisionStruct*>(pPtr);
|
||
m_uiForcePositionRevisionTick = pStruct->nRevisionTick;
|
||
return;
|
||
}
|
||
|
||
case STE_SuicideMonster:
|
||
{
|
||
SuicideMonsterStruct* pStruct = (SuicideMonsterStruct*)pPtr;
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ°<CFB4>. <20><><EFBFBD>⼭ Ŭ<><C5AC><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD>.
|
||
CmdSuicide( pStruct->bDropItem ? true : false, pStruct->bGetExp ? true : false );
|
||
}
|
||
break;
|
||
case STE_TriggerEvent:
|
||
{
|
||
TriggerEventStruct *pStruct = (TriggerEventStruct *)pPtr;
|
||
CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventArea", GetBirthAreaHandle() );
|
||
CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "ActorHandle", GetUniqueID() );
|
||
CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventID", pStruct->nEventID );
|
||
CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnActor::TriggerEvent", LocalTime, 0.f );
|
||
}
|
||
break;
|
||
case STE_Announce:
|
||
{
|
||
AnnounceStruct* pStruct = reinterpret_cast<AnnounceStruct*>(pPtr);
|
||
|
||
DNVector(DnActorHandle) hScanList;
|
||
GetMAScanner().Scan( MAScanner::eType::MonsterSkillSameTeamExpectMe, m_hActor, 0.f, static_cast<float>(pStruct->nRange), hScanList );
|
||
|
||
for( UINT i=0 ; i<hScanList.size() ; ++i )
|
||
{
|
||
DnActorHandle hActor = hScanList[i];
|
||
if( hActor && hActor->IsMonsterActor() )
|
||
{
|
||
CDnMonsterActor* pMonster = static_cast<CDnMonsterActor*>(hActor.GetPointer());
|
||
if( pMonster->GetMonsterClassID() == pStruct->nTargetMonsterID )
|
||
{
|
||
pMonster->GetAIBase()->NotifyDieAnnounce();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case STE_NextCustomAction:
|
||
{
|
||
if( !GetAIBase() )
|
||
return;
|
||
|
||
int state = 0;
|
||
float fLength = 0.0f;
|
||
EtVector3* pvPos = GetPosition();
|
||
|
||
MAAiScript* pScript = static_cast<MAAiScript*>(GetAIBase());
|
||
if( pScript->GetTarget() )
|
||
{
|
||
state = pScript->GetTargetDistanceState( pScript->GetTarget() );
|
||
fLength = EtVec3Length( &( *pvPos - *pScript->GetTarget()->GetPosition() ) );
|
||
}
|
||
|
||
if( static_cast<MAAiScript*>(GetAIBase())->GetAIState() == MAAiScript::AT_CustomAction )
|
||
static_cast<MAAiScript*>(GetAIBase())->OnCustomAction( state, fLength, 0 );
|
||
if( static_cast<MAAiScript*>(GetAIBase())->GetAIState() == MAAiScript::AT_UseSkill )
|
||
{
|
||
CancelUsingSkill();
|
||
static_cast<MAAiScript*>(GetAIBase())->OnUseSkill( state, fLength, 0 );
|
||
}
|
||
return;
|
||
}
|
||
|
||
#ifdef PRE_ADD_MONSTER_CATCH
|
||
case STE_CatchActor:
|
||
{
|
||
CatchActor( reinterpret_cast<CatchActorStruct*>(pPtr), nSignalIndex );
|
||
}
|
||
break;
|
||
|
||
case STE_ReleaseActor:
|
||
{
|
||
ReleaseAllActor( /*reinterpret_cast<ReleaseActorStruct*>(pPtr)*/ );
|
||
}
|
||
break;
|
||
#endif // #ifdef PRE_ADD_MONSTER_CATCH
|
||
case STE_ChangeAxis:
|
||
{
|
||
m_bChangeAxisOnFinishAction = true;
|
||
}
|
||
break;
|
||
}
|
||
CDnActor::OnSignal( Type, pPtr, LocalTime, SignalStartTime, SignalEndTime, nSignalIndex );
|
||
}
|
||
|
||
bool CDnMonsterActor::IsHittable( DnActorHandle hHitter, LOCAL_TIME LocalTime, HitStruct *pHitSignal, int iHitUniqueID )
|
||
{
|
||
#if defined(PRE_FIX_61382)
|
||
#else
|
||
//#59347
|
||
//<2F><><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD> <20><>ȯ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD> <20><>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD>θ<EFBFBD> <20><><EFBFBD>ΰ<EFBFBD><CEB0>ø<EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Hittable<6C><65><EFBFBD>θ<EFBFBD> üũ <20>ϵ<EFBFBD><CFB5><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if ( IsPuppetSummonMonster() && m_hSummonerPlayerActor )
|
||
{
|
||
bool bSummonerPlayerActorHittable = m_hSummonerPlayerActor->IsHittable(hHitter, LocalTime, pHitSignal, iHitUniqueID);
|
||
if (bSummonerPlayerActorHittable == false)
|
||
return false;
|
||
}
|
||
#endif // PRE_FIX_61382
|
||
|
||
if( m_bNoDamage ) return false;
|
||
return CDnActor::IsHittable( hHitter, LocalTime, pHitSignal, iHitUniqueID );
|
||
}
|
||
|
||
void CDnMonsterActor::ProcessPositionRevision( float fDelta )
|
||
{
|
||
if( CheckSignalPositionRevision( fDelta ) || CheckPositionRevision() )
|
||
{
|
||
BYTE pBuffer[128] = { 0, };
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &EtVec3toVec2( *GetMoveVectorZ() ), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
|
||
|
||
Send( eActor::SC_POSREV, &Stream );
|
||
|
||
ResetPositionRevision();
|
||
}
|
||
}
|
||
|
||
bool CDnMonsterActor::CheckPositionRevision()
|
||
{
|
||
if( m_LastSendMoveMsg == 0 )
|
||
return false;
|
||
|
||
if( !IsMove() )
|
||
{
|
||
m_LastSendMoveMsg = CDnActionBase::m_LocalTime;
|
||
return false;
|
||
}
|
||
|
||
if( CDnActionBase::m_LocalTime - m_LastSendMoveMsg > s_nPositionRevisionTime )
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CDnMonsterActor::CheckSignalPositionRevision( float fDelta )
|
||
{
|
||
if( m_uiForcePositionRevisionTick == 0 )
|
||
return false;
|
||
|
||
if( m_uiPrevForcePositionRevisionTick == 0 )
|
||
{
|
||
//std::cout << GetTickCount() << ":ù<><C3B9>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ <20><><EFBFBD><EFBFBD>" << std::endl;
|
||
m_fForcePositionRevisionDelta = m_uiForcePositionRevisionTick/1000.f;
|
||
return true;
|
||
}
|
||
|
||
m_fForcePositionRevisionDelta -= fDelta;
|
||
if( m_fForcePositionRevisionDelta <= 0.f )
|
||
{
|
||
m_fForcePositionRevisionDelta = m_uiForcePositionRevisionTick/1000.f;
|
||
//std::cout << GetTickCount() << ":<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ <20><><EFBFBD><EFBFBD>" << std::endl;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
void CDnMonsterActor::ResetPositionRevision()
|
||
{
|
||
m_LastSendMoveMsg = CDnActionBase::m_LocalTime;
|
||
}
|
||
|
||
|
||
float CDnMonsterActor::GetRotateAngleSpeed()
|
||
{
|
||
return CDnMonsterState::GetRotateAngleSpeed() * m_fRotateResistance;
|
||
}
|
||
|
||
void CDnMonsterActor::AttachWeapon( DnWeaponHandle hWeapon, int nEquipIndex, bool bDelete )
|
||
{
|
||
CDnActor::AttachWeapon( hWeapon, nEquipIndex, bDelete );
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if( m_nMonsterWeightTableID == -1 ) return;
|
||
if( hWeapon->IsInfinityDurability() || hWeapon->GetDurability() <= 0 ) return;
|
||
|
||
DNTableFileFormat* pWeight = GetDNTable( CDnTableDB::TMONSTERWEIGHT );
|
||
int nDurability = (int)( hWeapon->GetDurability() * pWeight->GetFieldFromLablePtr( m_nMonsterWeightTableID, "_DurabilityWeight" )->GetFloat() );
|
||
hWeapon->SetDurability( nDurability );
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::SetTeam( int nValue )
|
||
{
|
||
if( GetTeam() != nValue ) {
|
||
if( m_pAi ) m_pAi->ResetAggro();
|
||
}
|
||
CDnActor::SetTeam( nValue );
|
||
}
|
||
|
||
void CDnMonsterActor::ProcessPartyCombo( LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
if( m_nPartyComboDelay > 0 ) m_nPartyComboDelay -= (int)( fDelta * 1000 );
|
||
if( m_nPartyComboDelay < 0 ) {
|
||
m_nPartyComboCount = 0;
|
||
m_nPartyComboDelay = 0;
|
||
m_hPartyHitActor.Identity();
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::OnPartyCombo( DnActorHandle hHitter, int nComboDelay )
|
||
{
|
||
// #12170 <20><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0<><30> hit <20><> <20><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƹ<EFBFBD><C6B9><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> ó<><C3B3>.
|
||
if( 0 == nComboDelay )
|
||
return;
|
||
|
||
if( m_hPartyHitActor == hHitter ) {
|
||
m_nPartyComboDelay = nComboDelay;
|
||
return;
|
||
}
|
||
m_hPartyHitActor = hHitter;
|
||
if( m_nPartyComboDelay > 0 ) {
|
||
m_nPartyComboCount++;
|
||
if( hHitter && hHitter->IsPlayerActor() ) {
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(hHitter.GetPointer());
|
||
pPlayer->UpdatePartyCombo( m_nPartyComboCount );
|
||
}
|
||
}
|
||
else {
|
||
m_nPartyComboCount = 0;
|
||
}
|
||
m_nPartyComboDelay = nComboDelay;
|
||
}
|
||
|
||
void CDnMonsterActor::Process_AutoRecallRange()
|
||
{
|
||
if( NULL == m_hSummonerPlayerActor )
|
||
return;
|
||
|
||
if( 0 == m_nAutoRecallRange )
|
||
return;
|
||
|
||
//#55707 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ <20>ȵ<EFBFBD>
|
||
bool isAttackState = IsAttack();
|
||
if (isAttackState == true)
|
||
return;
|
||
|
||
EtVector2 vVec;
|
||
vVec.x = m_hSummonerPlayerActor->GetPosition()->x - m_Cross.m_vPosition.x;
|
||
vVec.y = m_hSummonerPlayerActor->GetPosition()->z - m_Cross.m_vPosition.z;
|
||
|
||
float fLength = EtVec2Length(&vVec);
|
||
|
||
if( m_nAutoRecallRange < fLength )
|
||
{
|
||
//#55707 <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ŵ.
|
||
ResetAggro();
|
||
|
||
CmdWarp( *m_hSummonerPlayerActor->GetPosition(), EtVec3toVec2( *m_hSummonerPlayerActor->GetLookDir() ) );
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::ReTransmitSlaveMsg(CDNUserSession* pBreakIntoSession) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><DFB1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
{
|
||
BYTE pBuffer[32];
|
||
CPacketCompressStream Stream( pBuffer, 32 );
|
||
Stream.Write( &m_dwSummonerActorID, sizeof(DWORD) );
|
||
Stream.Write( &m_bSummoned , sizeof(bool) );
|
||
Stream.Write( &m_nMaxHP, sizeof(INT64) );
|
||
Stream.Write( &m_nHP, sizeof(INT64) );
|
||
Stream.Write( &m_bFollowSummonerStage, sizeof(bool) );
|
||
Stream.Write( &m_bReCreatedFollowStageMonster, sizeof(bool) );
|
||
|
||
#if defined(PRE_FIX_55618)
|
||
//BaseState<74><65> MaxHP/HP/<2F>̵<EFBFBD> <20>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD>, <20><> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>س<EFBFBD><D8B3><EFBFBD>
|
||
//<2F><><EFBFBD>̻<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> m_bCopiedFromSummoner <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ش<EFBFBD>..
|
||
INT64 nBaseMaxHP = m_BaseState.GetMaxHP();
|
||
float nBaseMaxHPRate = m_BaseState.GetMaxHPRatio();
|
||
|
||
Stream.Write( &nBaseMaxHP, sizeof(INT64) );
|
||
Stream.Write( &nBaseMaxHPRate, sizeof(float) );
|
||
|
||
Stream.Write( &m_nMoveSpeed, sizeof(int) );
|
||
#endif // PRE_FIX_55618
|
||
|
||
Send( pBreakIntoSession , eActor::SC_SLAVE_OF, GetUniqueID() , &Stream );
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::SlaveOf( DWORD dwSummonerActorUniqueID, bool bSummoned/* = false*/, bool bSuicideWhenSummonerDie/* = false*/, bool bFollowSummonerStage/* = false*/, bool bReCreateFollowStageMonster/* = false*/ )
|
||
{
|
||
BYTE pBuffer[32];
|
||
CPacketCompressStream Stream( pBuffer, 32 );
|
||
Stream.Write( &dwSummonerActorUniqueID, sizeof(DWORD) );
|
||
Stream.Write( &bSummoned, sizeof(bool) );
|
||
if( bSummoned )
|
||
{
|
||
Stream.Write( &m_nMaxHP, sizeof(INT64) );
|
||
Stream.Write( &m_nHP, sizeof(INT64) );
|
||
Stream.Write( &bFollowSummonerStage, sizeof(bool) );
|
||
Stream.Write( &bReCreateFollowStageMonster, sizeof(bool) );
|
||
|
||
#if defined(PRE_FIX_55618)
|
||
//BaseState<74><65> MaxHP/HP/<2F>̵<EFBFBD> <20>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD>, <20><> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>س<EFBFBD><D8B3><EFBFBD>
|
||
//<2F><><EFBFBD>̻<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> m_bCopiedFromSummoner <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ش<EFBFBD>..
|
||
INT64 nBaseMaxHP = m_BaseState.GetMaxHP();
|
||
float nBaseMaxHPRate = m_BaseState.GetMaxHPRatio();
|
||
|
||
Stream.Write( &nBaseMaxHP, sizeof(INT64) );
|
||
Stream.Write( &nBaseMaxHPRate, sizeof(float) );
|
||
|
||
Stream.Write( &m_nMoveSpeed, sizeof(int) );
|
||
#endif // PRE_FIX_55618
|
||
|
||
#if defined(PRE_FIX_61382)
|
||
Stream.Write(&m_isPuppetSummonMonster, sizeof(bool));
|
||
#endif // PRE_FIX_61382
|
||
}
|
||
|
||
Send( eActor::SC_SLAVE_OF, &Stream );
|
||
|
||
m_dwSummonerActorID = dwSummonerActorUniqueID;
|
||
|
||
if( bSummoned )
|
||
{
|
||
DnActorHandle hActor = CDnActor::FindActorFromUniqueID( GetRoom(), dwSummonerActorUniqueID );
|
||
//#53454 <20><><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ <20><>ü<EFBFBD><C3BC> PlayerActor<6F><72> <20>ƴ<EFBFBD> <20><><EFBFBD>찡 <20><><EFBFBD><EFBFBD>.
|
||
if( hActor/* && hActor->IsPlayerActor()*/ )
|
||
{
|
||
m_hSummonerPlayerActor = hActor;
|
||
m_bSuicideWhenSummonerDie = bSuicideWhenSummonerDie;
|
||
m_bFollowSummonerStage = bFollowSummonerStage;
|
||
|
||
// <20>÷<EFBFBD><C3B7>̾ <20><>ȯ<EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ʹ<EFBFBD> pvp/pve <20><>ų<EFBFBD><C5B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
SelectSkillLevelDataType( hActor->GetSelectedSkillLevelDataType(), true );
|
||
}
|
||
}
|
||
|
||
m_bSummoned = bSummoned;
|
||
m_bReCreatedFollowStageMonster = bReCreateFollowStageMonster;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
void CDnMonsterActor::SlaveRelease( void )
|
||
{
|
||
if( 0 == m_dwSummonerActorID )
|
||
return;
|
||
|
||
BYTE pBuffer[32];
|
||
CPacketCompressStream Stream( pBuffer, 32 );
|
||
Stream.Write( &m_dwSummonerActorID, sizeof(DWORD) );
|
||
Send( eActor::SC_SLAVE_RELEASE, &Stream );
|
||
|
||
if( m_hSummonerPlayerActor )
|
||
{
|
||
m_hSummonerPlayerActor.Identity();
|
||
}
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::OnHitSuccess( LOCAL_TIME LocalTime, DnActorHandle hActor, HitStruct *pStruct )
|
||
{
|
||
// <20>Ϲ<EFBFBD><CFB9><EFBFBD><EFBFBD><EFBFBD> <20><>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>⼭ <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20>÷<EFBFBD><C3B7>̾<EFBFBD><CCBE><EFBFBD> <20><EFBFBD> ī<><C4AB>Ʈ<EFBFBD><C6AE> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>.
|
||
if( m_hSummonerPlayerActor && m_hSummonerPlayerActor->IsPlayerActor() )
|
||
m_hSummonerPlayerActor->OnHitSuccess( LocalTime, hActor, pStruct );
|
||
}
|
||
|
||
void CDnMonsterActor::OnHitFinish( LOCAL_TIME LocalTime, HitStruct *pStruct )
|
||
{
|
||
CDnActor::OnHitFinish( LocalTime, pStruct );
|
||
|
||
if (IsSummonedMonster())
|
||
{
|
||
DnActorHandle hMasterActor = GetSummonerPlayerActor();
|
||
if (hMasterActor)
|
||
{
|
||
int nDieCount = 0;
|
||
for( DWORD i=0; i<m_hVecLastHitList.size(); i++ ) {
|
||
if( m_hVecLastHitList[i] && m_hVecLastHitList[i]->IsDie() ) nDieCount++;
|
||
}
|
||
|
||
hMasterActor->UpdateMissionByMonsterKillCount(nDieCount);
|
||
}
|
||
}
|
||
|
||
if( GetAIBase() )
|
||
GetAIBase()->OnHitFinish( LocalTime, pStruct );
|
||
}
|
||
|
||
void CDnMonsterActor::ResetAggro( void )
|
||
{
|
||
if( m_pAggroSystem )
|
||
m_pAggroSystem->ResetAggro();
|
||
}
|
||
|
||
void CDnMonsterActor::ResetAggro( DnActorHandle hActor )
|
||
{
|
||
if( m_pAggroSystem )
|
||
m_pAggroSystem->ResetAggro( hActor );
|
||
}
|
||
|
||
void CDnMonsterActor::RequestDamageFromStateBlow( DnBlowHandle hFromBlow, int iDamage )
|
||
{
|
||
if( m_bNoDamage ) return;
|
||
CDnActor::RequestDamageFromStateBlow( hFromBlow, iDamage );
|
||
}
|
||
|
||
#ifdef PRE_ADD_MONSTER_CATCH
|
||
void CDnMonsterActor::_CatchThisActor( DnActorHandle hResultActor, int nSignalIndex )
|
||
{
|
||
S_CATCH_ACTOR_INFO CatchActorInfo;
|
||
|
||
CatchActorInfo.hCatchedActor = hResultActor;
|
||
CatchActorInfo.hCatchedActor->SetActionQueue( m_strCatchedActorAction.c_str() );
|
||
m_iCatchedActorActionIndex = CatchActorInfo.hCatchedActor->GetElementIndex( m_strCatchedActorAction.c_str() );
|
||
|
||
// <20>̵<EFBFBD>/<2F>ൿ<EFBFBD>Ұ<EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> <20>߰<EFBFBD>.
|
||
CatchActorInfo.iCatchCantMoveBlowID = CatchActorInfo.hCatchedActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_070, -1, "", false, false );
|
||
CatchActorInfo.iCatchCantActionBlowID = CatchActorInfo.hCatchedActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_071, -1, "", false, false );
|
||
|
||
if( CatchActorInfo.hCatchedActor->IsPlayerActor() )
|
||
{
|
||
static_cast<CDnPlayerActor*>(CatchActorInfo.hCatchedActor.GetPointer())->SetCatcherMonsterActor( GetMySmartPtr() );
|
||
}
|
||
|
||
m_vlCatchedActors.push_back( CatchActorInfo );
|
||
|
||
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>Ҵٰ<D2B4> <20><>Ŷ <20><><EFBFBD><EFBFBD>.
|
||
BYTE pBuffer[ 128 ] = { 0 };
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
DWORD dwCatchedActorID = CatchActorInfo.hCatchedActor->GetUniqueID();
|
||
int nCatchActionIndex = GetCurrentActionIndex();
|
||
int nCatchSignalArrayIndex = nSignalIndex;
|
||
Stream.Write( &dwCatchedActorID, sizeof(DWORD) );
|
||
Stream.Write( &nCatchActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &nCatchSignalArrayIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
|
||
Send( eActor::SC_CATCH_ACTOR, &Stream );
|
||
}
|
||
|
||
void CDnMonsterActor::CatchActor( CatchActorStruct* pCatchActor, int nSignalIndex )
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴٸ<CAB4> <20>ѳ<EFBFBD><D1B3><EFBFBD> <20><><EFBFBD><EFBFBD> <20>־ ó<><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
|
||
if( FALSE == pCatchActor->bMultiCatch )
|
||
if( false == m_vlCatchedActors.empty() )
|
||
return;
|
||
|
||
m_strCatchBoneName = pCatchActor->szCatchBoneName;
|
||
m_strTargetActorCatchBoneName = pCatchActor->szTargetActorCatchBoneName;
|
||
|
||
if( pCatchActor->szCatchedActorAction != NULL &&
|
||
0 < strlen(pCatchActor->szCatchedActorAction) )
|
||
{
|
||
m_strCatchedActorAction.assign( pCatchActor->szCatchedActorAction );
|
||
}
|
||
else
|
||
m_strCatchedActorAction.assign( "Hold" );
|
||
|
||
EtVector3 vCatchBonePos( 0.0f, 0.0f, 0.0f );
|
||
GetObjectHandle()->SetCalcAni( true );
|
||
EtMatrix matBoneWorld = GetBoneMatrix( m_strCatchBoneName.c_str() );
|
||
GetObjectHandle()->SetCalcAni( false );
|
||
memcpy_s( &vCatchBonePos, sizeof(EtVector3), &matBoneWorld._41, sizeof(EtVector3) );
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><> <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><>ġ <20><>ó<EFBFBD><C3B3><EFBFBD><EFBFBD> <20>ñ׳ο<D7B3><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// <20>Ÿ<EFBFBD><C5B8><EFBFBD> ª<><C2AA> <20>ְ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> Ȯ<><C8AE>.
|
||
DNVector( DnActorHandle ) vlhActors;
|
||
ScanActor( GetGameRoom(), vCatchBonePos, pCatchActor->fCatchDistance, vlhActors );
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̰<EFBFBD><CCB0><EFBFBD> <20><><EFBFBD><EFBFBD> üũ.
|
||
|
||
float fMinDistanceSQ = FLT_MAX;
|
||
DnActorHandle hResultActor;
|
||
for( int i = 0; i < (int)vlhActors.size(); ++i )
|
||
{
|
||
DnActorHandle hActor = vlhActors.at( i );
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20>ñ׳ο<D7B3><CEBF><EFBFBD> <20>ѹ<EFBFBD> üũ<C3BC><C5A9> <20><> <20><><EFBFBD>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
if( m_setCatchCheckedActorIDs.end() != m_setCatchCheckedActorIDs.find( hActor->GetUniqueID() ) )
|
||
continue;
|
||
|
||
// <20>ڱ<EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20>н<EFBFBD>
|
||
if( GetMySmartPtr() == hActor )
|
||
continue;
|
||
|
||
// üũ<C3BC><C5A9> <20><> <20>ֵ<EFBFBD><D6B5><EFBFBD> set <20><> <20><><EFBFBD>ٷ<EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD>.
|
||
m_setCatchCheckedActorIDs.insert( hActor->GetUniqueID() );
|
||
|
||
// <20>÷<EFBFBD><C3B7>̾<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
if( false == hActor->IsPlayerActor() )
|
||
continue;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
|
||
if( GetTeam() == hActor->GetTeam() )
|
||
continue;
|
||
|
||
// CanHit <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>.
|
||
if( FALSE == pCatchActor->bIgnoreCanHit )
|
||
{
|
||
if( false == hActor->CDnActorState::IsHittable() )
|
||
continue;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִٸ<D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||
if( hActor->IsAppliedThisStateBlow( STATE_BLOW::BLOW_099 ) )
|
||
continue;
|
||
}
|
||
|
||
// bMultiCatch <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִٸ<D6B4> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>༮<EFBFBD><E0BCAE> <20><><EFBFBD><EFBFBD> ó<><C3B3>./
|
||
// <20><><EFBFBD><EFBFBD> <20>ִٸ<D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>.
|
||
EtVector3 vTargetActorPos = *hActor->GetPosition();
|
||
EtVector3 vDist = vCatchBonePos - vTargetActorPos;
|
||
float fDistanceSQ = EtVec3LengthSq( &vDist );
|
||
if( TRUE == pCatchActor->bMultiCatch ||
|
||
fDistanceSQ < fMinDistanceSQ )
|
||
{
|
||
// <20><><EFBFBD>̵<EFBFBD> <20>´<EFBFBD><C2B4><EFBFBD> Ȯ<><C8AE>.
|
||
bool bHeightMax = vTargetActorPos.y < (pCatchActor->fHeightMax + vCatchBonePos.y);
|
||
bool bHeightMin = (vCatchBonePos.y + pCatchActor->fHeightMin) < vTargetActorPos.y; // HeightMin <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if( bHeightMax && bHeightMin )
|
||
{
|
||
bool bCatchFailed = true;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, 0: <20>и<EFBFBD>, 1: <20><><EFBFBD><EFBFBD>, 2: <20><><EFBFBD>۾Ƹӷ<C6B8> <20>ߵ<EFBFBD>.
|
||
int iFailedType = -1;
|
||
int iBlowID = 0;
|
||
string strBlockOrParringAction;
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
// <20>и<EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD>⼱ <20><>Ʈ<EFBFBD><C6AE> <20>ƴϹǷ<CFB9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE> üũ.
|
||
bool bPassParring = true;
|
||
if( FALSE == pCatchActor->bIgnoreParring )
|
||
{
|
||
bool bAppliedBlockBlow = hActor->IsAppliedThisStateBlow( STATE_BLOW::BLOW_030 );
|
||
bool bAppliedParringBlow = hActor->IsAppliedThisStateBlow( STATE_BLOW::BLOW_031 );
|
||
|
||
if( bAppliedBlockBlow || bAppliedParringBlow )
|
||
{
|
||
// <20>и<EFBFBD><D0B8><EFBFBD> <20><> <20><><EFBFBD>쿣 <20>и<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>..
|
||
// <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD>ʿ<EFBFBD><CABF><EFBFBD> HitParam <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20>Ѱ<EFBFBD><D1B0>ش<EFBFBD>.
|
||
SHitParam HitParam;
|
||
HitParam.szActionName = m_strCatchedActorAction;
|
||
HitParam.fDamage = 1.0f;// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>⼭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴϹǷ<CFB9> <20>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD>̳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>. 0 <20≯<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF>üũ<C3BC><C5A9><EFBFBD><EFBFBD> <20>н<EFBFBD><D0BD><EFBFBD>.
|
||
HitParam.bIgnoreParring = false;
|
||
|
||
CDnActorState* pState = static_cast<CDnActorState*>(this);
|
||
bool bSuccess = false;
|
||
|
||
if( bAppliedParringBlow )
|
||
{
|
||
DNVector(DnBlowHandle) vlhBlows;
|
||
hActor->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_031, vlhBlows );
|
||
if( false == vlhBlows.empty() )
|
||
{
|
||
DnBlowHandle hParringBlow = vlhBlows.front();
|
||
bSuccess = hParringBlow->OnDefenseAttack( GetMySmartPtr(), pState, HitParam, true );
|
||
if( bSuccess )
|
||
{
|
||
iFailedType = 0;
|
||
iBlowID = hParringBlow->GetBlowID();
|
||
}
|
||
}
|
||
}
|
||
|
||
if( (false == bSuccess) && bAppliedBlockBlow )
|
||
{
|
||
DNVector(DnBlowHandle) vlhBlows;
|
||
hActor->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_030, vlhBlows );
|
||
if( false == vlhBlows.empty() )
|
||
{
|
||
DnBlowHandle hBlockBlow = vlhBlows.front();
|
||
bSuccess = hBlockBlow->OnDefenseAttack( GetMySmartPtr(), pState, HitParam, true );
|
||
if( bSuccess )
|
||
{
|
||
iFailedType = 1;
|
||
iBlowID = hBlockBlow->GetBlowID();
|
||
}
|
||
}
|
||
}
|
||
|
||
if( bSuccess )
|
||
{
|
||
bPassParring = false;
|
||
// <20>и<EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ǰ<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
|
||
if( HitParam.szActionName != m_strCatchedActorAction )
|
||
{
|
||
m_hActor->SetActionQueue( HitParam.szActionName.c_str() );
|
||
strBlockOrParringAction = HitParam.szActionName;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// <20>и<EFBFBD><D0B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>۾Ƹӷ<C6B8> <20>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ.
|
||
if( bPassParring )
|
||
{
|
||
if( hActor->CatchCalcSuperArmor( GetMySmartPtr(), pCatchActor->nApplySuperArmorDamage ) )
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>۾Ƹ<DBBE> <20>ٵǾ<D9B5> <20><><EFBFBD><EFBFBD> <20><>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>.
|
||
if( TRUE == pCatchActor->bMultiCatch )
|
||
{
|
||
_CatchThisActor( hActor, nSignalIndex );
|
||
}
|
||
else
|
||
{
|
||
hResultActor = hActor;
|
||
fMinDistanceSQ = fDistanceSQ;
|
||
}
|
||
|
||
bCatchFailed = false;
|
||
}
|
||
else
|
||
{
|
||
iFailedType = 2;
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ȿ<EFBFBD> <20>ִµ<D6B4><C2B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20>˷<EFBFBD><CBB7><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
// <20>и<EFBFBD><D0B8>̳<EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD>۾ƸӰ<C6B8> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> Ŭ<><EFBFBD> Ƚ<><C8BD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD>, <20>и<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD> <20><><EFBFBD><EFBFBD>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
|
||
if( bCatchFailed )
|
||
{
|
||
BYTE pBuffer[ 128 ] = { 0 };
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, 0: <20>и<EFBFBD>, 1: <20><><EFBFBD><EFBFBD>, 2: <20><><EFBFBD>۾Ƹӷ<C6B8> <20>ߵ<EFBFBD>.
|
||
int iFailedType = 0;
|
||
DWORD dwCatchFailedActorID = hActor->GetUniqueID();
|
||
int iParringOrBlockActionIndex = hActor->GetElementIndex( strBlockOrParringAction.c_str() );
|
||
Stream.Write( &iFailedType, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
|
||
Stream.Write( &iBlowID, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
Stream.Write( &dwCatchFailedActorID, sizeof(DWORD) );
|
||
Stream.Write( &iParringOrBlockActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
|
||
|
||
Send( eActor::SC_CATCH_ACTOR_FAILED, &Stream );
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
if( hResultActor )
|
||
{
|
||
_CatchThisActor( hResultActor, nSignalIndex );
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::ReleaseThisActor( DnActorHandle hActor )
|
||
{
|
||
vector<S_CATCH_ACTOR_INFO>::iterator iter = m_vlCatchedActors.begin();
|
||
for( iter; iter != m_vlCatchedActors.end(); ++iter )
|
||
{
|
||
S_CATCH_ACTOR_INFO& CatchActorInfo = *iter;
|
||
if( CatchActorInfo.hCatchedActor == hActor )
|
||
{
|
||
ReleaseThisActor( CatchActorInfo );
|
||
m_vlCatchedActors.erase( iter );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDnMonsterActor::ReleaseThisActor( S_CATCH_ACTOR_INFO &CatchActorInfo )
|
||
{
|
||
if( CatchActorInfo.hCatchedActor )
|
||
{
|
||
m_setCatchCheckedActorIDs.erase( CatchActorInfo.hCatchedActor->GetUniqueID() );
|
||
|
||
CatchActorInfo.hCatchedActor->CmdRemoveStateEffectFromID( CatchActorInfo.iCatchCantMoveBlowID );
|
||
CatchActorInfo.hCatchedActor->CmdRemoveStateEffectFromID( CatchActorInfo.iCatchCantActionBlowID );
|
||
|
||
// Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD>´ٰ<C2B4> <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
BYTE pBuffer[ 128 ] = { 0 };
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
DWORD dwCatchActorID = CatchActorInfo.hCatchedActor->GetUniqueID();
|
||
Stream.Write( &dwCatchActorID, sizeof(DWORD) );
|
||
|
||
Send( eActor::SC_RELEASE_ACTOR, &Stream );
|
||
|
||
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˸<EFBFBD> <20>ʿ䰡 <20>ִٸ<D6B4>.. <20><><EFBFBD><EFBFBD> <20><> ó<><C3B3><EFBFBD>ϰ<EFBFBD>.
|
||
|
||
if( CatchActorInfo.hCatchedActor->IsPlayerActor() )
|
||
{
|
||
static_cast<CDnPlayerActor*>( CatchActorInfo.hCatchedActor.GetPointer() )->ReleaseCatcherMonsterActor();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDnMonsterActor::ReleaseAllActor( void )
|
||
{
|
||
// üũ <20><> <20><><EFBFBD><EFBFBD>.
|
||
m_setCatchCheckedActorIDs.clear();
|
||
|
||
// <20>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> <20><><EFBFBD><EFBFBD>
|
||
for( int i = 0; i < (int)m_vlCatchedActors.size(); ++i )
|
||
{
|
||
S_CATCH_ACTOR_INFO& CatchActorInfo = m_vlCatchedActors.at( i );
|
||
if( CatchActorInfo.hCatchedActor )
|
||
{
|
||
ReleaseThisActor( CatchActorInfo );
|
||
}
|
||
}
|
||
|
||
m_vlCatchedActors.clear();
|
||
}
|
||
|
||
void CDnMonsterActor::ProcessCatchActor( LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
vector<S_CATCH_ACTOR_INFO>::iterator iter = m_vlCatchedActors.begin();
|
||
for( iter; iter != m_vlCatchedActors.end(); )
|
||
{
|
||
S_CATCH_ACTOR_INFO& CatchActorInfo = *iter;
|
||
// <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>÷<EFBFBD><C3B7>̾ <20><EFBFBD><D7BE><EFBFBD> <20><>. <20><><EFBFBD>ش<EFBFBD>.
|
||
// TODO: <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><EFBFBD><D7BE><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if( CatchActorInfo.hCatchedActor &&
|
||
false == CatchActorInfo.hCatchedActor->IsDie() &&
|
||
false == IsDie() )
|
||
{
|
||
EtVector3 vCatchBonePos( 0.0f, 0.0f, 0.0f );
|
||
EtMatrix matBoneWorld = GetBoneMatrix( m_strCatchBoneName.c_str() );
|
||
memcpy_s( &vCatchBonePos, sizeof(EtVector3), &matBoneWorld._41, sizeof(EtVector3) );
|
||
|
||
// vCatchBonePos <20><> ij<><C4B3><EFBFBD><EFBFBD> Bip01 <20><> <20><>ġ<EFBFBD><C4A1><EFBFBD>Ѿ<EFBFBD> <20>Ѵ<EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> vCatchBonePos <20><> <20><><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Bip01 <20><> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD>
|
||
// <20><EFBFBD>ŭ <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||
EtVector3 vPlayerCatchedPointPos( 0.0f, 0.0f, 0.0f );
|
||
CatchActorInfo.hCatchedActor->GetObjectHandle()->SetCalcAni( true );
|
||
matBoneWorld = CatchActorInfo.hCatchedActor->GetBoneMatrix( m_strTargetActorCatchBoneName.c_str() );
|
||
CatchActorInfo.hCatchedActor->GetObjectHandle()->SetCalcAni( false );
|
||
memcpy_s( &vPlayerCatchedPointPos, sizeof(EtVector3), &matBoneWorld._41, sizeof(EtVector3) );
|
||
|
||
EtVector3 vDelta = vCatchBonePos - vPlayerCatchedPointPos;
|
||
EtVector3 vNowCatchedActorPos = *CatchActorInfo.hCatchedActor->GetPosition();
|
||
EtVector3 vCatchedActorPos = vNowCatchedActorPos + vDelta;
|
||
CatchActorInfo.hCatchedActor->SetPosition( vCatchedActorPos );
|
||
|
||
//CatchActorInfo.hCatchedActor->SetActionQueue( m_strCatchedActorAction.c_str() );
|
||
|
||
// <20>ٸ<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||
int iCurrentActionIndex = CatchActorInfo.hCatchedActor->GetCurrentActionIndex();
|
||
if( iCurrentActionIndex != m_iCatchedActorActionIndex )
|
||
CatchActorInfo.hCatchedActor->SetActionQueue( m_strCatchedActorAction.c_str() );
|
||
|
||
++iter;
|
||
}
|
||
else
|
||
{
|
||
ReleaseThisActor( CatchActorInfo );
|
||
iter = m_vlCatchedActors.erase( iter );
|
||
}
|
||
}
|
||
|
||
if( false == IsSignalRange( STE_CatchActor ) )
|
||
{
|
||
if( false == m_setCatchCheckedActorIDs.empty() )
|
||
m_setCatchCheckedActorIDs.clear();
|
||
}
|
||
}
|
||
#endif // #ifdef PRE_ADD_MONSTER_CATCH
|
||
|
||
#if defined(PRE_FIX_51048)
|
||
void CDnMonsterActor::AddPassiveStateEffectInfo(PassiveStateEffectInfo& stateEffectInfo)
|
||
{
|
||
m_PassiveStateEffectInfoList.push_back(stateEffectInfo);
|
||
}
|
||
|
||
void CDnMonsterActor::InitPassiveStateEffectInfo()
|
||
{
|
||
m_PassiveStateEffectInfoList.clear();
|
||
}
|
||
|
||
void CDnMonsterActor::ApplyPassiveStateEffect()
|
||
{
|
||
if (m_PassiveStateEffectInfoList.empty())
|
||
return;
|
||
|
||
std::list<PassiveStateEffectInfo>::iterator iter = m_PassiveStateEffectInfoList.begin();
|
||
std::list<PassiveStateEffectInfo>::iterator endIter = m_PassiveStateEffectInfoList.end();
|
||
|
||
for (; iter != endIter; ++iter)
|
||
{
|
||
PassiveStateEffectInfo& passiveStateEffect = (*iter);
|
||
|
||
DnSkillHandle hSkill = FindSkill(passiveStateEffect.pParentSkill->iSkillID);
|
||
if (hSkill)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> -> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int iBlowID = CmdAddStateEffect( passiveStateEffect.pParentSkill, passiveStateEffect.emBlowIndex, -1, passiveStateEffect.szParam.c_str(), true ); // Duration Time<6D><65> -1 <20≯<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
OnApplyPassiveSkillBlow( iBlowID );
|
||
|
||
hSkill->SetAppliedPassiveBlows( true );
|
||
}
|
||
}
|
||
}
|
||
|
||
bool CDnMonsterActor::ApplyPassiveSkill( DnSkillHandle hSkill, bool isInitialize/* = false*/ )
|
||
{
|
||
bool bPassiveBuf = false;
|
||
|
||
if( CDnSkill::Passive == hSkill->GetSkillType() )
|
||
{
|
||
int iNumStateEffect = hSkill->GetStateEffectCount();
|
||
for( int i = 0; i < iNumStateEffect; ++i )
|
||
{
|
||
CDnSkill::StateEffectStruct* pSE = hSkill->GetStateEffectFromIndex( i );
|
||
if( CDnSkill::StateEffectApplyType::ApplySelf == pSE->ApplyType )
|
||
{
|
||
if( CDnSkill::DurationTypeEnum::Buff == hSkill->GetDurationType() )
|
||
{
|
||
bPassiveBuf = true;
|
||
if( hSkill->IsSatisfyWeapon() )
|
||
{
|
||
//<2F><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if (GetEnablePassiveStateEffectList() == true)
|
||
{
|
||
PassiveStateEffectInfo passiveStateEffectInfo;
|
||
passiveStateEffectInfo.pParentSkill = hSkill->GetInfo();
|
||
passiveStateEffectInfo.emBlowIndex = (STATE_BLOW::emBLOW_INDEX)pSE->nID;
|
||
passiveStateEffectInfo.nDurationTime = -1;
|
||
passiveStateEffectInfo.szParam = pSE->szValue;
|
||
|
||
AddPassiveStateEffectInfo(passiveStateEffectInfo);
|
||
}
|
||
else
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> -> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int iBlowID = CmdAddStateEffect( hSkill->GetInfo(), (STATE_BLOW::emBLOW_INDEX)pSE->nID, -1, pSE->szValue.c_str(), true ); // Duration Time<6D><65> -1 <20≯<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
OnApplyPassiveSkillBlow( iBlowID );
|
||
|
||
hSkill->SetAppliedPassiveBlows( true );
|
||
}
|
||
|
||
#ifndef _FINAL_BUILD
|
||
char szTemp[256] = { 0, };
|
||
WideCharToMultiByte( CP_ACP, 0, hSkill->GetName(), -1, szTemp, _countof(szTemp), NULL, NULL );
|
||
OutputDebug( "[<5B>нú<D0BD> <20><><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d] \"%s\" <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF>Index: %d, Value:%s\n", hSkill->GetClassID(), szTemp, pSE->nID, pSE->szValue.c_str() );
|
||
#endif // #ifndef _FINAL_BUILD
|
||
}
|
||
#ifndef _FINAL_BUILD
|
||
else
|
||
{
|
||
char szTemp[256] = { 0, };
|
||
WideCharToMultiByte( CP_ACP, 0, hSkill->GetName(), -1, szTemp, _countof(szTemp), NULL, NULL );
|
||
OutputDebug( "[<5B>нú<D0BD> <20><><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD>: %d] \"%s\" <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>.\n", hSkill->GetClassID(), szTemp );
|
||
}
|
||
#endif // #ifndef _FINAL_BUILD
|
||
}
|
||
#ifndef _FINAL_BUILD
|
||
else
|
||
{
|
||
char szTemp[256] = { 0, };
|
||
WideCharToMultiByte( CP_ACP, 0, hSkill->GetName(), -1, szTemp, _countof(szTemp), NULL, NULL );
|
||
OutputDebug( "[<5B><>ų <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE> <20><><EFBFBD><EFBFBD>: %d] \"%s\" <20>нú<D0BD> <20><><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD> Buff <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> <20>ʾƼ<CABE> <20><><EFBFBD><EFBFBD> <20>ȵ<EFBFBD>\n", hSkill->GetClassID(), szTemp );
|
||
}
|
||
#endif // #ifndef _FINAL_BUILD
|
||
}
|
||
}
|
||
}
|
||
|
||
return bPassiveBuf;
|
||
}
|
||
#endif // PRE_FIX_51048
|
||
|
||
|
||
#if defined(PRE_FIX_61382)
|
||
void CDnMonsterActor::RequestDamageFromStateBlow( DnBlowHandle hFromBlow, int iDamage, CDnDamageBase::SHitParam* pHitParam/* = NULL*/ )
|
||
{
|
||
if (IsPuppetSummonMonster() == true)
|
||
{
|
||
DnActorHandle hOwnerActor = GetSummonerPlayerActor();
|
||
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>츸? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_051) && hOwnerActor)
|
||
{
|
||
#if defined(PRE_FIX_59347) && !defined(PRE_FIX_67656)
|
||
hOwnerActor->SetApplyPartsDamage(true);
|
||
#endif // PRE_FIX_59347
|
||
|
||
hOwnerActor->RequestDamageFromStateBlow(hFromBlow, iDamage, pHitParam);
|
||
|
||
#if defined(PRE_FIX_59347) && !defined(PRE_FIX_67656)
|
||
hOwnerActor->SetApplyPartsDamage(false);
|
||
#endif // PRE_FIX_59347
|
||
}
|
||
}
|
||
else
|
||
{
|
||
CDnActor::RequestDamageFromStateBlow(hFromBlow, iDamage, pHitParam);
|
||
}
|
||
}
|
||
#endif // PRE_FIX_61382
|
||
|
||
#if defined(PRE_FIX_64312)
|
||
void CDnMonsterActor::SendApplySummonMonsterExSkill(int nBaseSkillID, int nLevel, int nSelectedType, DWORD dwMasterUniqueID, int nMasterExSkillID)
|
||
{
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
Stream.Write(&nBaseSkillID, sizeof(int));
|
||
Stream.Write(&nLevel, sizeof(int));
|
||
Stream.Write(&nSelectedType, sizeof(int));
|
||
Stream.Write(&dwMasterUniqueID, sizeof(DWORD));
|
||
Stream.Write(&nMasterExSkillID, sizeof(int));
|
||
|
||
Send( eActor::SC_APPLY_SUMMON_MONSTER_EX_SKILL, &Stream );
|
||
}
|
||
#endif // PRE_FIX_64312
|