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

8992 lines
No EOL
291 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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

#include "StdAfx.h"
#include "DnActor.h"
#include "DnWorld.h"
#include "DnWorldGrid.h"
#include "MAActorRenderBase.h"
#include "MAMovementBase.h"
#include "DnWeapon.h"
#include "EtActionSignal.h"
#include "VelocityFunc.h"
#include "DnWorldBrokenProp.h"
#include "DnWorldSector.h"
#include "DnProjectile.h"
#include "DnMonsterActor.h"
#include "TaskManager.h"
#include "DnPlayerActor.h"
#include "PerfCheck.h"
#include "DnStateBlow.h"
#include "DnBlow.h"
#include "DnGameTask.h"
#include "DnItemTask.h"
#include "DNUserData.h"
#include "DNUserSession.h"
#include "DnWorldTrapProp.h"
#include "DnChangeActionStrProcessor.h"
//#include "DNUserConnection.h"
// Siva Shaodw Test ÀÓ½Ã
#ifdef _SHADOW_TEST
#include "DNProtocol.h"
#include "GameSendPacket.h"
bool g_bEnableShadow[MAX_SESSION_COUNT] = { 0, };
#endif
#include "EtComputeDist.h"
#include "DNAggroSystem.h"
#include "DnParryBlow.h"
#include "DnCooltimeParryBlow.h"
#include "DnChargerBlow.h"
#include "DnBuffProp.h"
#include "DnWorldBrokenBuffProp.h"
#include "DnReverseTeamBlow.h"
#include "DnHighLanderBlow.h"
#include "DnCannonMonsterActor.h"
#include "DnPlayerSpeedHackChecker.h"
#include "DnFrostbiteBlow.h"
#include "DnChangeActionSetBlow.h"
#include "DnInvincibleAtBlow.h"
#include "DnBreakSuperArmorBlow.h"
#include "DnBurnCriticalBlow.h"
#include "DnDisableActionBlow.h"
#ifdef PRE_ADD_EXPORT_DPS_INFORMATION
#include "DnDPSReporter.h"
#endif
#include "DnManaShieldBlow.h"
#include "DnCurseBlow.h"
#include "DNGameDataManager.h"
#include "DnStateBlowSignalProcessor.h"
#include "DnInvincibleTypeBlow.h"
#include "DnImmuneByTypeBlow.h"
#include "DnComboDamageLimitBlow.h"
#include "DnTransmitDamageBlow.h"
#include "DnChangeStandActionBlow.h"
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
#include "DnTotalLevelSkillBlows.h"
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
#if defined(PRE_FIX_68898)
#include "DnPartialPlayProcessor.h"
#endif // PRE_FIX_68898
#include "SmartPtrDef.h"
#include "DnBubbleSystem.h"
#include "DnObserverEventMessage.h"
DECL_DN_SMART_PTR_STATIC( CDnActor, MAX_SESSION_COUNT, 100 )
STATIC_DECL_INIT( CDnActor, CEtOctree<DnActorHandle> *, s_pOctree ) = { NULL, };
STATIC_DECL_INIT( CDnActor, DWORD, s_dwUniqueCount ) = { 0, };
STATIC_DECL_INIT( CDnActor, CDnActor::mapActorSearch, s_dwMapActorSearch );
float CDnActor::s_fDieDelta = 20.f;
float CEtOctreeNode<DnActorHandle>::s_fMinRadius = 1000.0f;
#define DOWN_DELAY_RANDOM_RANGE 0.2f // 20ÇÁ·Î ±æ°Å³ª ¤E°Å³ª~
#ifdef PRE_FIX_GAMESERVER_OPTIMIZE
STATIC_DECL_INIT( CDnActor, CFrameSkip, s_MonsterProcess );
STATIC_DECL_INIT( CDnActor, float, s_fMonsterProcessDelta );
STATIC_DECL_INIT( CDnActor, CFrameSkip, s_NpcProcess );
STATIC_DECL_INIT( CDnActor, float, s_fNpcProcessDelta );
#endif
CDnActor::CDnActor( CMultiRoom *pRoom, int nClassID )
: CDnUnknownRenderObject( pRoom, true )
, m_vStaticPosition( 0.f, 0.f, 0.f )
, m_vPrevPosition( 0.f, 0.f, 0.f )
{
CDnActorState::Initialize( this );
m_nClassID = nClassID;
m_fAddHeight = 0.f;
m_bShow = true;
m_fDownDelta = 0.f;
m_fDieDelta = 0.f;
m_fMaxDieDelta = CDnActor::s_fDieDelta;
m_fStiffDelta = 0.f;
m_fLastDownRatio = 1.f;
m_LastHitSignalTime = 0;
m_nLastHitSignalIndex = -1;
m_nLastDamageHitterActionIndex = 0;
m_nTeam = 0;
m_dwUniqueID = -1;
m_pAggroSystem = NULL;
m_bModifyPlaySpeed = false;
m_PlaySpeedStartTime = 0;
m_dwPlaySpeedTime = 0;
m_bEnableNormalSuperAmmor = false;
m_nNormalSuperAmmorTime = 0;
m_fBreakNormalSuperAmmorDurability = 0.f;
m_HitCheckType = HitCheckTypeEnum::BoundingBox;
memset( m_bSelfDeleteWeapon, 0, sizeof( m_bSelfDeleteWeapon ) );
m_pStateBlow = new CDnStateBlow( GetMySmartPtr() );
memset( m_nSkillSuperAmmorValue, 0, sizeof(m_nSkillSuperAmmorValue) );
memset( m_nLastUpdateSkillSuperAmmorValue, 0, sizeof(m_nLastUpdateSkillSuperAmmorValue) );
m_nSkillSuperAmmorTime = 0;
m_fSkillSuperAmmorDamageDecreaseProb = 0.f;
m_bIngnoreNormalSuperArmor = false;
InsertOctreeNode();
m_bUseSignalSkillCheck = false;
ZeroMemory( m_abSignalSkillCheck, sizeof(m_abSignalSkillCheck) );
m_iCantMoveReferenceCount = 0;
m_iCantActionReferenceCount = 0;
m_iCantUseSkillReferenceCount = 0;
m_iCantAttackReferenceCount = 0;
m_iCantXZMoveSE = 0;
#ifdef _SHADOW_TEST
m_bIsShadowActor = false;
m_bEnableShadowActor = true;
#endif
m_iLastDamage = 0;
m_bOnSignalFromChargerSE = false;
m_bAllowCalcCombo = true;
m_bOctreeUpdate = true;
m_bToggleIngnoreHit = false;
m_dwGenTick = timeGetTime();
m_iFrameStopRefCount = 0;
m_fPlaySpeed = 0.0f;
m_iLastProcessPressCount = 0;
m_bCompleteKill_AfterProcessStateBlow = false;
m_pStateBlowSignalProcessor = new CDnStateBlowSignalProcessor();
m_bChangeWeaponLocked = false;
m_bSkipChangeWeaponAction = false;
m_bSkipOnAttatchDetachWeapon = false;
#if defined(PRE_ADD_50907)
m_ChangeWeaponRefCount = 0;
m_bOrigWeaponWhenChangeWeaponSelfDelete = false;
#endif // PRE_ADD_50907
#if defined(PRE_ADD_50907)
m_DisarmamentRefCount = 0;
m_bOrigWeaponWhenDisarmamentSelfDelete = false;
#endif // PRE_ADD_50907
#if defined(PRE_FIX_50482)
m_nChangeTeamRefCount = 0;
#endif // PRE_FIX_50482
#if defined(PRE_FIX_59347)
m_bApplyPartsDamage = false;
#endif // PRE_FIX_59347
#ifdef PRE_ADD_GRAVITY_PROPERTY
m_fGravityEnd = 0.0f;
#endif // PRE_ADD_GRAVITY_PROPERTY
// Rotate.
m_dwRotateStartTime = 0;
m_dwRotateTime = 0;
m_bRotate = false;;
m_bRotLeft = false; // ȸÀü¹æÇâ.
m_fSpeedRot = 0.0f; // ȸÀü¼Óµµ.
m_fStartSpeed = 0.0f; // ½ÃÀÛ¼Óµµ.
m_fEndSpeed = 0.0f; // Á¾·á¼Óµµ.
m_vRotAxis.x = m_vRotAxis.y = m_vRotAxis.z = 0.0f; // ȸÀüÃàÁÂÇ¥.
}
CDnActor::~CDnActor()
{
RemoveUniqueSearchMap( GetRoom(), this );
FreeAction();
for( int i=0; i<2; i++ ) SAFE_RELEASE_SPTR( m_hWeapon[i] );
RemoveOctreeNode();
SAFE_DELETE_VEC( m_VecPreActionState );
SAFE_DELETE_VEC( m_VecPreActionCustomState );
SAFE_DELETE(m_pStateBlow);
SAFE_DELETE( m_pAggroSystem );
SAFE_DELETE(m_pStateBlowSignalProcessor);
}
void CDnActor::InsertOctreeNode()
{
if( STATIC_INSTANCE(s_pOctree) ) {
SSphere Sphere;
GetBoundingSphere( Sphere );
m_pCurrentNode = STATIC_INSTANCE(s_pOctree)->Insert( GetMySmartPtr(), Sphere );
}
}
void CDnActor::RemoveOctreeNode()
{
if( STATIC_INSTANCE(s_pOctree) ) {
if( !STATIC_INSTANCE(s_pOctree)->Remove( GetMySmartPtr(), m_pCurrentNode ) ) {
STATIC_INSTANCE(s_pOctree)->Remove( GetMySmartPtr(), NULL );
}
m_pCurrentNode = NULL;
}
}
void CDnActor::SetUniqueID( DWORD dwUniqueID )
{
RemoveUniqueSearchMap( GetRoom(), this );
m_dwUniqueID = dwUniqueID;
InsertUniqueSearchMap( GetRoom(), this );
}
void CDnActor::InsertUniqueSearchMap( CMultiRoom *pRoom, CDnActor *pActor )
{
if( pActor->GetUniqueID() == -1 ) return;
STATIC_INSTANCE_(s_dwMapActorSearch).insert( make_pair( pActor->GetUniqueID(), pActor->GetMySmartPtr() ) );
}
void CDnActor::RemoveUniqueSearchMap( CMultiRoom *pRoom, CDnActor *pActor )
{
if( pActor->GetUniqueID() == -1 ) return;
std::map<DWORD, DnActorHandle>::iterator it;
it = STATIC_INSTANCE_(s_dwMapActorSearch).find( pActor->GetUniqueID() );
if( it != STATIC_INSTANCE_(s_dwMapActorSearch).end() ) {
STATIC_INSTANCE_(s_dwMapActorSearch).erase( it );
}
}
// Static Func
void CDnActor::InitializeNextStage( CMultiRoom* pRoom )
{
CDNGameRoom* pGameRoom = static_cast<CDNGameRoom*>(pRoom);
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ )
{
if( !STATIC_INSTANCE_(s_pVecProcessList)[i]->IsPlayerActor() )
{
//g_Log.Log( LogType::_INVALIDACTOR, "[%d] MapIdx:%d ClassID:%d LocalTime=%I64d\r\n", g_Config.nManagedID, pGameRoom->m_iMapIdx, STATIC_INSTANCE_(s_pVecProcessList)[i]->GetClassID(), pGameTask ? pGameTask->m_pFrameSync->GetMSTime() : 0 );
STATIC_INSTANCE_(s_pVecProcessList)[i]->Release();
i--;
}
}
}
bool CDnActor::InitializeClass( CMultiRoom *pRoom )
{
if( !CDnWorld::IsActive(pRoom) ) return false;
DNVector(DnActorHandle) VecList;
GetActorList( pRoom, VecList );
int iNumActor = (int)VecList.size();
for( int i = 0; i < iNumActor; ++i )
{
DnActorHandle hActor = VecList.at( i );
CDnActor::ActorTypeEnum ActorType = hActor->GetActorType();
if( ActorType > -1 && ActorType <= ActorTypeEnum::Reserved6 )
hActor->OnInitializeNextStage();
}
float fCenter, fSize;
CDnWorld::GetInstance(pRoom).CalcWorldSize( fCenter, fSize );
SAFE_DELETE( STATIC_INSTANCE_(s_pOctree) );
STATIC_INSTANCE_(s_pOctree) = new CEtOctree<DnActorHandle>( false );
STATIC_INSTANCE_(s_pOctree)->Initialize( EtVector3( 0.f, fCenter, 0.f ), fSize );
STATIC_INSTANCE_(CDnActor::s_dwUniqueCount) = 0;
#ifdef PRE_FIX_GAMESERVER_OPTIMIZE
STATIC_INSTANCE_(s_MonsterProcess).SetFramePerSec( 10.f );
STATIC_INSTANCE_(s_fMonsterProcessDelta) = 0.f;
STATIC_INSTANCE_(s_NpcProcess).SetFramePerSec( 1.f );
STATIC_INSTANCE_(s_fNpcProcessDelta) = 0.f;
#endif
return true;
}
void CDnActor::ProcessClass( CMultiRoom *pRoom, LOCAL_TIME LocalTime, float fDelta )
{
#ifdef PRE_FIX_GAMESERVER_OPTIMIZE
float fResultDelta[2] = { fDelta, fDelta };
bool bProcessSkip[2] = { false, false };
if( STATIC_INSTANCE_(s_MonsterProcess).Update( fDelta ) ) {
STATIC_INSTANCE_(s_fMonsterProcessDelta) += fDelta;
fResultDelta[0] = STATIC_INSTANCE_(s_fMonsterProcessDelta);
bProcessSkip[0] = false;
STATIC_INSTANCE_(s_fMonsterProcessDelta) = 0.f;
}
else {
bProcessSkip[0] = true;
STATIC_INSTANCE_(s_fMonsterProcessDelta) += fDelta;
}
if( STATIC_INSTANCE_(s_NpcProcess).Update( fDelta ) ) {
STATIC_INSTANCE_(s_fNpcProcessDelta) += fDelta;
fResultDelta[1] = STATIC_INSTANCE_(s_fNpcProcessDelta);
bProcessSkip[1] = false;
STATIC_INSTANCE_(s_fNpcProcessDelta) = 0.f;
}
else {
bProcessSkip[1] = true;
STATIC_INSTANCE_(s_fNpcProcessDelta) += fDelta;
}
float fTempDelta;
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ ) {
CDnActor *pActor = STATIC_INSTANCE_(s_pVecProcessList)[i];
pActor->SyncClassTime( LocalTime );
fTempDelta = fDelta;
if( !pActor->IsPlayerActor() ) {
if( pActor->IsMonsterActor() ) {
#ifndef PRE_FIX_MOMSTER_PROCESS_DELTA
// ¸ó½ºÅÍ¿Í Ç÷¹À̾îÀÇ ÇÁ·¹ÀÓÀ²ÀÌ ´Þ¶ó¼­ ¹Î°¨ÇÑ ºÎºÐ¿¡¼­ Ŭ¶ó¿Í ¼­¹öÀÇ ½ÌÅ©°¡ ´Þ¶óÁö°ÔµË´Ï´Ù
// ƯÁ¤ Delta°ªÀ» ÀÌ¿ëÇÑ º¸°£ °è»êÀ̳ª Delta °ªÀ» »ç¿ëÇÏ´Â ºÎºÐ¿¡¼­ ¹Ì¹¦ÇÏ°Ô ½ÌÅ©°¡ Ʋ¾îÁ®¼­ ¸ó½ºÅÍ´Â ÇÁ·¹ÀÓ ½ÌÅ© °ÉÁö¾Êµµ·Ï ¼³Á¤ÇÕ´Ï´Ù.
fTempDelta = fResultDelta[0];
if( bProcessSkip[0] ) continue;
#endif
}
if( pActor->IsNpcActor() ) {
fTempDelta = fResultDelta[1];
if( bProcessSkip[1] ) continue;
}
}
/*
if( bProcessSkip == true && !STATIC_INSTANCE_(s_pVecProcessList)[i]->IsPlayerActor() ) {
continue;
}
if( !STATIC_INSTANCE_(s_pVecProcessList)[i]->IsPlayerActor() ) {
fTempDelta = fResultDelta;
}
else fTempDelta = fDelta;
*/
STATIC_INSTANCE_(s_pVecProcessList)[i]->Process( LocalTime, fTempDelta );
SSphere Sphere;
STATIC_INSTANCE_(s_pVecProcessList)[i]->GetBoundingSphere( Sphere );
if( STATIC_INSTANCE_(s_pVecProcessList)[i]->m_bOctreeUpdate )
STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode = STATIC_INSTANCE_(s_pOctree)->Update( STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr(), Sphere, STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode );
if( STATIC_INSTANCE_(s_pVecProcessList)[i]->IsDestroy() ) {
STATIC_INSTANCE_(s_pVecProcessList)[i]->Release();
i--;
}
}
#else
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ ) {
STATIC_INSTANCE_(s_pVecProcessList)[i]->SyncClassTime( LocalTime );
STATIC_INSTANCE_(s_pVecProcessList)[i]->Process( LocalTime, fDelta );
SSphere Sphere;
STATIC_INSTANCE_(s_pVecProcessList)[i]->GetBoundingSphere( Sphere );
if( STATIC_INSTANCE_(s_pVecProcessList)[i]->m_bOctreeUpdate )
STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode = STATIC_INSTANCE_(s_pOctree)->Update( STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr(), Sphere, STATIC_INSTANCE_(s_pVecProcessList)[i]->m_pCurrentNode );
if( STATIC_INSTANCE_(s_pVecProcessList)[i]->IsDestroy() ) {
STATIC_INSTANCE_(s_pVecProcessList)[i]->Release();
i--;
}
}
#endif
}
void CDnActor::ProcessAIClass( CMultiRoom *pRoom, LOCAL_TIME LocalTime, float fDelta )
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ )
{
STATIC_INSTANCE_(s_pVecProcessList)[i]->ProcessAI( LocalTime, fDelta );
}
}
void CDnActor::ReleaseClass( CMultiRoom *pRoom )
{
SAFE_DELETE( STATIC_INSTANCE_(s_pOctree) );
SAFE_DELETE_MAP( STATIC_INSTANCE_(s_dwMapActorSearch) );
DeleteAllObject( pRoom );
STATIC_INSTANCE_(s_pVecProcessList).clear();
}
int CDnActor::ScanActor( CMultiRoom *pRoom, EtVector3 &vPos, float fRadius, DNVector(DnActorHandle) &VecList, bool bInside )
{
SSphere Sphere;
Sphere.Center = vPos;
Sphere.fRadius = fRadius;
STATIC_INSTANCE_(s_pOctree)->Pick( Sphere, VecList, bInside );
return (int)VecList.size();
}
int CDnActor::ScanActorByActorSize( CMultiRoom *pRoom, EtVector3 &vPos, float fRadius, DNVector(DnActorHandle) &VecList, bool bInside, bool bActorSize )
{
SSphere Sphere;
Sphere.Center = vPos;
Sphere.fRadius = fRadius;
STATIC_INSTANCE_(s_pOctree)->Pick( Sphere, VecList, bInside, bActorSize );
return (int)VecList.size();
}
void CDnActor::GetActorList(CMultiRoom *pRoom, DNVector(DnActorHandle) &VecList)
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ )
{
DnActorHandle hActor = STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr();
VecList.push_back(hActor);
}
}
void CDnActor::GetOpponentActorList(CMultiRoom *pRoom, int nTeam, DNVector(DnActorHandle) &VecList, EtVector3* pPos/*=NULL*/, float fMaxRange/*=0.f*/ )
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ )
{
DnActorHandle hActor = STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr();
if( hActor->GetTeam() != nTeam )
{
bool bPush = true;
if( pPos && fMaxRange > 0.f )
{
if( EtVec3LengthSq( &(*pPos-*hActor->GetPosition()) ) > fMaxRange*fMaxRange )
bPush = false;
}
if( bPush )
VecList.push_back(hActor);
}
}
}
DnActorHandle CDnActor::FindActorFromUniqueID( CMultiRoom *pRoom, DWORD dwUniqueID )
{
std::map<DWORD, DnActorHandle>::iterator it = STATIC_INSTANCE_(s_dwMapActorSearch).find( dwUniqueID );
if( it != STATIC_INSTANCE_(s_dwMapActorSearch).end() ) return it->second;
return CDnActor::Identity();
}
DnActorHandle CDnActor::FindActorFromName( CMultiRoom *pRoom, TCHAR *szName )
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ ) {
if( !wcscmp( STATIC_INSTANCE_(s_pVecProcessList)[i]->GetName(), szName ) ) return STATIC_INSTANCE_(s_pVecProcessList)[i]->GetMySmartPtr();
}
return CDnActor::Identity();
}
void CDnActor::ProcessReservedRemoveBlows( void )
{
if( false == m_vlReservedRemoveBlows.empty() )
{
for( int i = 0; i < (int)m_vlReservedRemoveBlows.size(); ++i )
{
DnBlowHandle hBlow = m_vlReservedRemoveBlows.at( i );
if( hBlow )
this->CmdRemoveStateEffectFromID( hBlow->GetBlowID() );
}
m_vlReservedRemoveBlows.clear();
}
}
void CDnActor::Process( LOCAL_TIME LocalTime, float fDelta )
{
UpdateStealMagicBuff();
int nState = GetState();
m_bEnableNormalSuperAmmor = false;
CDnActionBase::ProcessAction( LocalTime, fDelta );
if( 0 < GetCantMoveSEReferenceCount() )
m_vAniDistance.x = m_vAniDistance.z = 0.0f;
if( !IsNpcActor() )
{
PROFILE_TIME_TEST( OnSkillProcess( LocalTime, fDelta ) );
}
ProcessDown( LocalTime, fDelta );
ProcessDie( LocalTime, fDelta );
ProcessStiff( LocalTime, fDelta );
ProcessPlaySpeed( LocalTime, fDelta );
ProcessRotate( LocalTime, fDelta ); // Rotate;
PROFILE_TIME_TEST( ProcessState( LocalTime, fDelta ) );
PROFILE_TIME_TEST( ProcessPress() );
if (m_pStateBlowSignalProcessor && !IsDie() )
m_pStateBlowSignalProcessor->Process(LocalTime, fDelta);
//»óÅÂÈ¿°ú 229¹ø¿¡¼­ µî·ÏµÈ »óÅÂÈ¿°ú Àû¿ë¿ë ÇÔ¼ö..
ApplySkillStateEffect();
for( int i=0; i<2; i++ )
{
if( m_hWeapon[i] )
m_hWeapon[i]->Process( LocalTime, fDelta );
}
#ifdef PRE_ADD_GRAVITY_PROPERTY
if( m_fGravityEnd > 0.0f )
{
m_fGravityEnd -= fDelta;
if( m_fGravityEnd <= 0.0f )
{
SetVelocityY( 0.01f );
SetResistanceY( -30.0f );
SetAppliedYDistance( false );
m_fGravityEnd = 0.0f;
}
}
#endif // PRE_ADD_GRAVITY_PROPERTY
#ifdef _SHADOW_TEST
if( g_bEnableShadow[GetRoom()->GetRoomID()] && m_bEnableShadowActor && GetGameRoom() ) {
char pBuf[256];
CPacketCompressStream Stream( pBuf, 256 );
int nIndex = GetElementIndex( m_szAction.c_str() );
float fFrame = GetCurFrame();
EtVector3 vMoveX = *GetMoveVectorX();
EtVector3 vMoveZ = *GetMoveVectorZ();
Stream.Write( &nIndex, sizeof(int) );
Stream.Write( &fFrame, sizeof(float) );
Stream.Write( &m_Cross.m_vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( &m_Cross.m_vXAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
Stream.Write( &m_Cross.m_vZAxis, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
Stream.Write( &vMoveX, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
Stream.Write( &vMoveZ, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
bool bMoveTarget = ( GetMoveTarget() ) ? true : false;
bool bLookTarget = ( GetLookTarget() ) ? true : false;
Stream.Write( &bMoveTarget, sizeof(bool) );
if( bMoveTarget ) {
DnActorHandle hMoveTarget = GetMoveTarget();
Stream.Write( hMoveTarget->GetPosition(), sizeof(EtVector3) );
}
Stream.Write( &bLookTarget, sizeof(bool) );
if( bLookTarget ) {
DnActorHandle hLookTarget = GetLookTarget();
Stream.Write( hLookTarget->GetPosition(), sizeof(EtVector3) );
}
for( DWORD i=0; i<GetGameRoom()->GetUserCount(); i++ ) {
SendActorShadowMsg( GetGameRoom()->GetUserData(i), GetUniqueID(), eActor::SC_SHADOW, (BYTE*)Stream.GetBuffer(), Stream.Tell() );
}
}
#endif
// ¸¶Áö¸·À¸·Î ¹Þ¾Ò´ø µ¥¹ÌÁö ÃʱâÈ­. (È­¿° »óÅÂÈ¿°ú¿¡¼­ ¾²ÀÓ)
m_iLastDamage = 0;
}
void CDnActor::GetBoundingSphere( SSphere &Sphere, bool bActorSize/* = false*/ )
{
MAActorRenderBase *pRenderBase = static_cast<MAActorRenderBase *>(this);
if( pRenderBase ) {
if( pRenderBase->GetBoundingSphere( Sphere ) == false ) {
Sphere.Center = m_Cross.m_vPosition;
Sphere.fRadius = (float)GetUnitSize();
}
}
else {
Sphere.Center = m_Cross.m_vPosition;
Sphere.fRadius = (float)GetUnitSize();
}
if (bActorSize == true)
{
Sphere.Center = FindAutoTargetPos();
Sphere.fRadius = (float)GetUnitSize();
}
}
void CDnActor::GetBoundingBox( SAABox &Box )
{
MAActorRenderBase *pRenderBase = static_cast<MAActorRenderBase *>(this);
if( pRenderBase ) {
pRenderBase->GetBoundingBox( Box );
}
else {
Box.Min = m_Cross.m_vPosition + EtVector3( -50.f, -50.f, -50.f );
Box.Max = m_Cross.m_vPosition + EtVector3( 50.f, 50.f, 50.f );
}
}
void CDnActor::AddStateEffectQueue( const CDnSkill::SkillInfo& ParentSkillInfo, const CDnSkill::StateEffectStruct& StateEffectInfo )
{
m_dqApplySelfStateBlowQ.push_back( S_NO_PACKET_SELF_STATEBLOW(ParentSkillInfo, StateEffectInfo) );
}
void CDnActor::ClearSelfStateSignalBlowQueue( bool bItemSkill/* = false*/ )
{
deque<S_NO_PACKET_SELF_STATEBLOW>::iterator iter = m_dqApplySelfStateBlowQ.begin();
for( iter; iter != m_dqApplySelfStateBlowQ.end(); )
{
if( bItemSkill == iter->ParentSkillInfo.bIsItemSkill )
{
iter = m_dqApplySelfStateBlowQ.erase( iter );
}
else
{
iter++;
}
}
}
void CDnActor::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex )
{
switch( Type ) {
case STE_Hit:
{
if( IsDie() ) break;
if (ProcessIgnoreHitSignal() == true)
break;
HitStruct *pStruct = (HitStruct *)pPtr;
DNVector(DnActorHandle) hVecList;
DNVector(DnActorHandle) hVecActorToApplyStateEffect;
int nWeaponLength = 0;
bool bOnDamageCalled = false;
if( pStruct->bIncludeWeaponLength && GetWeapon() ) nWeaponLength = GetWeapon()->GetWeaponLength();
MatrixEx CrossTemp = m_Cross;
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
// ½ºÄÉÀÏµÈ ¸ó½ºÅÍÀÇ °æ¿ì È÷Æ® ½Ã±×³ÎÀÇ Áß½ÉÃàÀÌ Ç×»ó ¾×ÅÍÀÇ ¿øÁ¡ À§Ä¡°¡ ¸Â´Â °ÍÀº ¾Æ´Ï±â ¶§¹®¿¡
// ¿ÀÇÁ¼Â¿¡µµ Á¤È®ÇÏ°Ô ½ºÄÉÀÏ °ªÀ» Àû¿ë½ÃÄÑ Áà¾ß ÇÑ´Ù.(#18971)
EtVector3 vOffset = *pStruct->vOffset * GetScale()->y;
CrossTemp.MoveLocalZAxis( vOffset.z );
CrossTemp.MoveLocalXAxis( vOffset.x );
CrossTemp.MoveLocalYAxis( vOffset.y );
// ƯÁ¤ º»°ú ¸µÅ©µÈ »óŶó¸é..
if( pStruct->szLinkBoneName && strlen(pStruct->szLinkBoneName) > 0 )
{
int nBoneIndex = GetBoneIndex( pStruct->szLinkBoneName );
if( -1 != nBoneIndex )
{
EtMatrix matBoneWorld = GetBoneMatrix( pStruct->szLinkBoneName );
EtMatrixMultiply( (EtMatrix*)&CrossTemp, (EtMatrix*)&CrossTemp, &matBoneWorld );
}
}
// ¸ó½ºÅÍ´Â ½ºÄÉÀÏ¿¡µû¶ó º¸Á¤ÇØÁà¾ßÇÑ´Ù.
float fDistanceMax = pStruct->fDistanceMax * GetScale()->y;
float fDistanceMin = pStruct->fDistanceMin * GetScale()->y;
float fHeightMax = pStruct->fHeightMax * GetScale()->y;
EtVector3 vPos = CrossTemp.m_vPosition;
float fDistance = max( fDistanceMax, fHeightMax - pStruct->fHeightMin ) + nWeaponLength;
float fXZDistanceSQ = fDistanceMax + nWeaponLength;
float fXZDistanceMinSQ = fDistanceMin; // Min Àº Weapon ±æÀÌ ¿µÇâ¾È¹Þ½À´Ï´Ù.
fXZDistanceSQ *= fXZDistanceSQ;
fXZDistanceMinSQ *= fXZDistanceMinSQ;
ScanActor( GetRoom(), vPos, fDistance, hVecList );
//#53454 ²ÀµÎ°¢½Ã ¼Òȯ¾×ÅÍÀÎ °æ¿ì, ²ÀµÎ°¢½Ã ÁÖÀÎ?Àº HitList¿¡¼­ Á¦¿Ü ½ÃŲ´Ù.
#if defined(PRE_FIX_61382)
ExceptionHitList2(hVecList, m_Cross, GetMySmartPtr(), pStruct, hVecActorToApplyStateEffect, 0, fDistance, m_vPrevPosition);
#else
ExceptionHitList(hVecList, m_Cross, GetMySmartPtr(), pStruct);
#endif // PRE_FIX_61382
EtVector3 vDir;
EtVector3 vZVec = m_Cross.m_vZAxis;
if( pStruct->fCenterAngle != 0.f ) {
EtMatrix matRotate;
EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) );
EtVec3TransformNormal( &vZVec, &vZVec, &matRotate );
#if defined(PRE_FIX_63356)
//#63356 ¼­Å¬º½¹öÀÇ °æ¿ì È÷Æ® ¿µ¿ªÀÌ 180µµ ȸÀüÀÌ µÈ °æ¿ì..
//vPos´Â ÇöÀç ij¸¯ÅÍÀÇ ¹æÇâ¿¡¼­ ¿É¼Â °ª¸¸Å­ À̵¿ÀÌ µÇ°í, È÷Æ® ¿µ¿ªÀº 180µµ ȸÀüÀÌ µÇ´Â °æ¿ì À̹ǷÎ
//Çã¿ë °¢µµ °è»ê¿¡¼­ ÀÌ È¸Àü °ªÀ» Àû¿ë ½ÃÄÑ¾ß ÇÑ´Ù.
CrossTemp.m_vZAxis = vZVec;
#endif // PRE_FIX_63356
}
SAABox Box;
float fDot = 0.0f;
SHitParam HitParam;
bool bHit = false;
bool bFirstHit = true;
if( m_LastHitSignalTime > LocalTime ) bFirstHit = false;
if( m_nLastHitSignalIndex != nSignalIndex ) {
bFirstHit = true;
m_nLastHitSignalIndex = nSignalIndex;
}
HitParam.szActionName = pStruct->szTargetHitAction;
HitParam.fDamage = pStruct->fDamageProb * 0.01f;
HitParam.fDurability = pStruct->fDurabilityDamageProb * 0.01f;
HitParam.vVelocity = *pStruct->vVelocity;
HitParam.vResistance = *pStruct->vResistance;
HitParam.hHitter = GetMySmartPtr();
HitParam.hWeapon = GetActiveWeapon(0);
HitParam.vPosition = vPos;
HitParam.fStiffProb = pStruct->fStiffProb * 0.01f;
HitParam.RemainTime = SignalEndTime;
HitParam.nDamageType = pStruct->nDamageType;
HitParam.nSkillSuperAmmorIndex = pStruct->nApplySuperAmmorIndex - 1;
HitParam.nSkillSuperAmmorDamage = pStruct->nApplySuperAmmorDamage;
HitParam.cAttackType = (char)pStruct->nAttackType;
HitParam.DistanceType = (pStruct->nDistanceType == 0) ? CDnDamageBase::DistanceTypeEnum::Melee : CDnDamageBase::DistanceTypeEnum::Range;
HitParam.HasElement = CalcHitElementType( ( pStruct->bUseSkillApplyWeaponElement == TRUE ) ? true : false );
HitParam.bIgnoreCanHit = ( pStruct->bIgnoreCanHit == TRUE );
HitParam.bIgnoreParring = ( pStruct->bIgnoreParring == TRUE );
HitParam.bReleaseCatchActor = ( pStruct->bReleaseCatchedActor == TRUE );
HitParam.nWeightValueLimit = pStruct->nWeightValueLimit;
bool isFirstHitter = true;
HitParam.nHitLimitCount = pStruct->nHitLimitCount;
bool isHitLimited = false;
HitLimitCountInfo* pHitLimitCountInfo = NULL;
if (HitParam.nHitLimitCount != 0)
{
//HitLimitCountÁ¤º¸°¡ µî·ÏµÇ¾î ÀÖ´Â°Ô ÀÖ´ÂÁö È®ÀÎ..
HIT_LIMIT_COUNT_INFO_LIST::iterator findIter = m_HitLimitCountInfoList.find(nSignalIndex);
if (findIter != m_HitLimitCountInfoList.end())
pHitLimitCountInfo = &findIter->second;
else
{
//»õ·Î¿î Á¤º¸ Ãß°¡ Çϰí, ÇØ´ç ¸®½ºÆ®ÀÇ Á¤º¸ÀÇ Æ÷ÀÎÅÍ ¾ò´Â´Ù..
HitLimitCountInfo newHitLimitCountInfo(HitParam.nHitLimitCount, HitParam.nHitLimitCount);
m_HitLimitCountInfoList.insert(HIT_LIMIT_COUNT_INFO_LIST::value_type(nSignalIndex, newHitLimitCountInfo));
HIT_LIMIT_COUNT_INFO_LIST::iterator findIter = m_HitLimitCountInfoList.find(nSignalIndex);
if (findIter != m_HitLimitCountInfoList.end())
pHitLimitCountInfo = &findIter->second;
}
}
// Note: ¿©±â¼­ Clear Çϸé ÀÌÀü¿¡ ¶§·È´ø ¾ÖµéÀÇ È÷Æ®½Ã±×³Î Á¾·á ½Ã°£ÀÌ º¹±¸µÇÁö ¾ÊÀº »óÅ·Π³Ñ¾î°¡¹ö¸± ¼ö ÀÖ½À´Ï´Ù.
// ½´ÆÛ¾Æ¸Ó ÀÖ´Â ¾Ö°¡ ¸Â¾ÒÀ» ¶§ FPS°¡ 1.8ÀÌ µÇ¾î EndTime ÀÌ µÚ·Î ¹Ð¸° ä·Î ProcessPlaySpeed ¿¡¼­ Á¦´ë·Î º¹±¸ ½ÃÄÑÁÖ·Á¸é
// ¸¶Áö¸·À¸·Î ¸ÂÀº ¾ÖµéÀ» ¸®½ºÆ®·Î º¹±¸½Ã۱â Àü¿¡ ³¯¸®¸é ¾ÈµË´Ï´Ù.
m_hVecLastHitList.clear();
// Actor üũ
for( DWORD i=0; i<hVecList.size(); i++ )
{
if( !hVecList[i] )
continue;
// Hit¼ö Á¦ÇÑ
//ÃÖ´ë Hit¼ö°¡ ¼³Á¤µÇ¾î ÀÖ°í, Hit¼ö°¡ ÃÖ´ë Hit¼ö¸¦ ³Ñ¾î °¡¸é ¸ØÃá´Ù.
isHitLimited = (pHitLimitCountInfo && (pHitLimitCountInfo->nHitLimitCount != 0 && pHitLimitCountInfo->nHitCount <= 0));
if (isHitLimited)
break;
// Â÷Á® »óÅÂÈ¿°ú¶ó¸é ÇØ´ç »óÅÂÈ¿°úÀÇ ID ¸¦ À¯´ÏÅ© ¾ÆÀ̵𸦠»ç¿ëÇÑ´Ù.
// ¼îÅ© ¿Àºê ·¼¸¯Ã³·³ °°Àº ¾×¼ÇÀ¸·Î Â÷Á® »óÅÂÈ¿°úÀÇ ÀνºÅϽº °¹¼ö´ë·Î µ¿½Ã¿¡ ¿©·¯ È÷Æ® ½Ã±×³ÎÀ» ¹ßµ¿½Ã۱â À§Çؼ­.
if( m_hChargerBlowCalledOnSignal )
{
if( !hVecList[i]->IsHittable( GetMySmartPtr(), LocalTime, pStruct, m_hChargerBlowCalledOnSignal->GetBlowID() ) )
continue;
// ¿©±â¼­ hitparam ÀÇ À¯´ÏÅ© id ¸¦ ¼ÂÆÃÇØÁà¾ß ÃßÈÄ¿¡ ondamage ¿¡¼­ ÀÌ id º°·Î Á¤¸®µÇ¾î ÃßÈÄ ishittable È£Ãâ½Ã »ç¿ëÇÏ°Ô µÈ´Ù.
HitParam.iUniqueID = m_hChargerBlowCalledOnSignal->GetBlowID();
}
else
{
if( !hVecList[i]->IsHittable( GetMySmartPtr(), LocalTime, pStruct ) )
continue;
}
switch( hVecList[i]->GetHitCheckType() ) {
case HitCheckTypeEnum::BoundingBox:
{
HitParam.vPosition = vPos;
vDir = *hVecList[i]->GetPosition() - vPos;
vDir.y = 0.f;
hVecList[i]->GetBoundingBox( Box );
if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue;
if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue;
EtVec3Normalize( &vDir, &vDir );
fDot = EtVec3Dot( &vZVec, &vDir );
if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue;
if( Box.Min.y < vPos.y + pStruct->fHeightMin &&
Box.Max.y < vPos.y + pStruct->fHeightMin ) continue;
if( Box.Min.y > vPos.y + fHeightMax &&
Box.Max.y > vPos.y + fHeightMax ) continue;
HitParam.vViewVec = -vDir;
}
break;
case HitCheckTypeEnum::Collision:
{
SCollisionCapsule Capsule;
SCollisionResponse CollisionResult;
DNVector(SCollisionResponse) vCollisionResult;
Capsule.Segment.vOrigin = vPos;
float fHeight = fHeightMax - pStruct->fHeightMin;
Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) );
Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f );
Capsule.fRadius = ( fDistanceMax + nWeaponLength );
EtVector3 vDestPos;
if( hVecList[i]->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false ) continue;
if( CollisionResult.pCollisionPrimitive )
{
for( UINT k=0 ; k<vCollisionResult.size() ; ++k )
{
if( vCollisionResult[k].pCollisionPrimitive ) {
vCollisionResult[k].pCollisionPrimitive->GetBoundingBox( Box );
if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) {
vCollisionResult.erase( vCollisionResult.begin() + k );
k--;
continue;
}
if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) {
vCollisionResult.erase( vCollisionResult.begin() + k );
k--;
continue;
}
DNVector(EtVector3) vPointList;
vPointList.push_back( Box.GetCenter() );
#ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ||
vCollisionResult[k].pCollisionPrimitive->Type == CT_CAPSULE ) {
#else
if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ) {
#endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
Box.GetVertices( vPointList );
}
bool bCheck = false;
for( DWORD m=0; m<vPointList.size(); m++ ) {
#if defined(PRE_FIX_63356)
//#63356 ¼­Å¬º½¹öÀÇ °æ¿ì È÷Æ® ¿µ¿ªÀÌ 180µµ ȸÀüÀÌ µÈ °æ¿ì..
//vPos´Â ÇöÀç ij¸¯ÅÍÀÇ ¹æÇâ¿¡¼­ ¿É¼Â °ª¸¸Å­ À̵¿ÀÌ µÇ°í, È÷Æ® ¿µ¿ªÀº 180µµ ȸÀüÀÌ µÇ´Â °æ¿ì À̹ǷÎ
//Çã¿ë °¢µµ °è»ê¿¡¼­ ÀÌ È¸Àü °ªÀ» Àû¿ë ½ÃÄÑ¾ß ÇÑ´Ù.
if( hVecList[i]->CheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == true ) {
#else
if( hVecList[i]->CheckCollisionHitCondition(vPos, m_Cross, vPointList[m], pStruct->fAngle) == true ) {
#endif // PRE_FIX_63356
bCheck = true;
break;
}
}
if( bCheck == false ) {
vCollisionResult.erase( vCollisionResult.begin() + k );
k--;
continue;
}
HitParam.vBoneIndex.push_back( hVecList[i]->GetObjectHandle()->GetParentBoneIndex( vCollisionResult[k].pCollisionPrimitive ) );
}
}
if( vCollisionResult.empty() ) continue;
GetCenterPos( *CollisionResult.pCollisionPrimitive, vDestPos );
HitParam.vPosition = vDestPos;
}
else
{
ASSERT( 0 );
}
if( pStruct->fDistanceMin > 100.f )
{
vCollisionResult.clear();
Capsule.fRadius = pStruct->fDistanceMin;
if( hVecList[i]->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == true ) {
if( CollisionResult.pCollisionPrimitive )
{
for( UINT k=0 ; k<vCollisionResult.size() ; ++k )
{
if( vCollisionResult[k].pCollisionPrimitive ) {
vCollisionResult[k].pCollisionPrimitive->GetBoundingBox( Box );
if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) {
vCollisionResult.erase( vCollisionResult.begin() + k );
k--;
continue;
}
if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > vPos.y + fHeightMax ) {
vCollisionResult.erase( vCollisionResult.begin() + k );
k--;
continue;
}
DNVector(EtVector3) vPointList;
vPointList.push_back( Box.GetCenter() );
#ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ||
vCollisionResult[k].pCollisionPrimitive->Type == CT_CAPSULE ) {
#else
if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ) {
#endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
Box.GetVertices( vPointList );
}
bool bCheck = false;
for( DWORD m=0; m<vPointList.size(); m++ ) {
#ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
// »©¾ßÇÏ´Â ¿µ¿ª¿¡¼­ ÇÑÁ¡ÀÌ¶óµµ ¾È °É¸®¸é hit ¿µ¿ª°ú °ÉÃÄ ÀÖ´Â ³ðÀ̹ǷΠ»©Áö ¾Ê´Â´Ù...
#if defined(PRE_FIX_63356)
if( hVecList[i]->CheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == false ) {
#else
if( hVecList[i]->CheckCollisionHitCondition(vPos, m_Cross, vPointList[m], pStruct->fAngle) == false ) {
#endif // PRE_FIX_63356
#else
#if defined(PRE_FIX_63356)
if( hVecList[i]->CheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == true ) {
#else
if( hVecList[i]->CheckCollisionHitCondition(vPos, m_Cross, vPointList[m], pStruct->fAngle) == true ) {
#endif // PRE_FIX_63356
#endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
bCheck = true;
break;
}
}
#ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
if( bCheck == true ) {
#else
if( bCheck == false ) {
#endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL
vCollisionResult.erase( vCollisionResult.begin() + k );
k--;
continue;
}
int nBoneIndex = hVecList[i]->GetObjectHandle()->GetParentBoneIndex( vCollisionResult[k].pCollisionPrimitive );
std::vector<int>::iterator it = std::find( HitParam.vBoneIndex.begin(), HitParam.vBoneIndex.end(), nBoneIndex );
if( it != HitParam.vBoneIndex.end() ) {
HitParam.vBoneIndex.erase( it );
}
}
}
}
}
if( HitParam.vBoneIndex.empty() ) continue;
}
HitParam.vViewVec = vPos - vDestPos;
EtVec3Normalize( &HitParam.vViewVec, &HitParam.vViewVec );
}
break;
}
HitParam.bFirstHit = bFirstHit;
bFirstHit = false;
bHit = true;
if( !HitParam.szActionName.empty() ) {
m_hVecLastHitList.push_back( hVecList[i] );
// ÇÁ·¹ÀÓÀÌ »¡¶óÁ³À» °æ¿ì¿¡ Áߺ¹À¸·Î ¾×ÅͰ¡ µé¾î¿Ã ¼ö ÀÖ´Ù.
if( m_hVecLastHitListByRemainTime.end() == find( m_hVecLastHitListByRemainTime.begin(), m_hVecLastHitListByRemainTime.end(), hVecList[i] ) )
{
m_hVecLastHitListByRemainTime.push_back( hVecList[i] );
}
#if defined(PRE_ADD_PREFIX_SYSTE_RENEW)
// HitSignal¿¡¼­ ½ºÅ³ ¿©ºÎ »ó°ü¾øÀÌ Á¢µÎ»ç ½ºÅ³ ¹ßµ¿
// Á¢µÎ¾î »óÅÂÈ¿°ú ¹«½ÃÇÏ´Â »óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é Àû¿ë ¾ÈµÊ
// #40186 Á¢¹Ì»ç? ¹ßµ¿ Á¶°Ç º¯°æ (µ¥¹ÌÁö ºñÀ²ÀÌ 0ÀÎ °æ¿ì ¹ßµ¿ µÇÁö ¾Êµµ·ÏÇÔ.)
if (HitParam.bFirstHit &&
pStruct->fDamageProb != 0.0f &&
!IsAppliedThisStateBlow(STATE_BLOW::BLOW_183) &&
isFirstHitter)
{
ProcessPrefixOffenceSkill_New();
isFirstHitter = false;
}
#else
//////////////////////////////////////////////////////////////////////////
// Á¢µÎ¾î °ø°Ý¿ë ½ºÅ³ ¹ßµ¿ Áغñ ÀÛ¾÷..
// ÆòŸÀ϶§¸¸ Á¢µÎ¾î ½Ã½ºÅÛ °ø°Ý½ºÅ³ ¹ßµ¿
// ÆòŸÀ̰í, HitÇÁ·¹ÀÓ¿¡ óÀ½ µé¾î ¿Ô°í, ù¹øÂ° ¸Â´Â ³à¼®À϶§
bool isCanUsePrefixSkill = CanUsePrefixSkill();
if (isCanUsePrefixSkill && HitParam.bFirstHit && isFirstHitter)
{
OutputDebug("CDnActor::OnSignal -> STE_Hit start %d current %d end %d\n", (int)SignalStartTime, (int)LocalTime, (int)SignalEndTime);
//¿©±â¼­´Â Àڽſ¡°Ô Àû¿ë ÇÏ´Â »óÅ ȿ°ú¸¸ Àû¿ë½Ã۰í,
//¸Â´Â ³à¼®¿¡°Ô Àû¿ëÇØ¾ßÇÒ »óÅ ȿ°ú´Â Target->OnDamage¿¡¼­ ó¸® µÇµµ·ÏÇÑ´Ù.??
ProcessPrefixOffenceSkill( 1.0f );
isFirstHitter = false;
}
#endif // PRE_ADD_PREFIX_SYSTE_RENEW
#ifdef PRE_ADD_MONSTER_CATCH
if( HitParam.bReleaseCatchActor )
{
if( IsMonsterActor() )
{
static_cast<CDnMonsterActor*>(this)->ReleaseThisActor( hVecList[ i ] );
}
}
#endif // #ifdef PRE_ADD_MONSTER_CATCH
hVecList[i]->OnDamage( GetMySmartPtr(), HitParam, pStruct );
if( 0 != pStruct->StateEffectFilter )
{
OnHitSignalStateEffectFilterException( hVecList[ i ]->GetUniqueID(), pStruct->StateEffectFilter );
}
bOnDamageCalled = true;
//Hit¼ö Áõ°¡
if (pHitLimitCountInfo)
pHitLimitCountInfo->nHitCount--;
}
hVecActorToApplyStateEffect.push_back( hVecList[i] );
#ifdef PRE_ADD_TRIGGER_BY_HIT_CONDITION
if( pStruct->szTriggerEventParameter != NULL && IsPlayerActor() == false && hVecList[i]->IsMonsterActor() )
{
CDnMonsterActor* pTrigerTargetMonsterActor = static_cast<CDnMonsterActor*>( hVecList[i].GetPointer());
if( pTrigerTargetMonsterActor )
{
std::string strParam = pStruct->szTriggerEventParameter;
std::vector<std::string> tokens;
TokenizeA(strParam, tokens, ";");
if (tokens.size() == 2)
{
if( pTrigerTargetMonsterActor->GetMonsterClassID() == atoi(tokens[0].c_str()) )
{
CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventArea", pTrigerTargetMonsterActor->GetBirthAreaHandle() );
CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "ActorHandle", pTrigerTargetMonsterActor->GetUniqueID() );
CDnWorld::GetInstance(GetRoom()).InsertTriggerEventStore( "EventID", atoi(tokens[1].c_str()) );
CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnActor::TriggerEvent", CDnActionBase::m_LocalTime, 0.f );
}
}
}
}
#endif
}
bool bIsFarm = false;
CDnGameTask *pGameTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" );
if( pGameTask && pGameTask->GetGameTaskType() == GameTaskType::Farm )
bIsFarm = true;
if( false == bIsFarm && IsProcessSkill() )
{
int iNumActorApplyStateEffect = (int)hVecActorToApplyStateEffect.size();
m_hProcessSkill->CheckTargetCount( iNumActorApplyStateEffect );
for( int i = 0; i < iNumActorApplyStateEffect; ++i )
{
// ´ë»óÀÌ ¾óÀ½°¨¿Á »óÅÂÀ϶§´Â »óÅÂÈ¿°ú Àû¿ë ¹«½Ã
if (hVecActorToApplyStateEffect[ i ]->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
continue;
// ½ºÅ³ ´ë»ó ¼³Á¤ÀÌ ¾Æ±ºÀΰ¡ Ÿ°ÙÀΰ¡¿¡ µû¶ó »óÅÂÈ¿°ú Àû¿ëÀ» ±¸ºÐÇÑ´Ù.
switch( m_hProcessSkill->GetTargetType() )
{
case CDnSkill::Enemy:
case CDnSkill::Self:
if( GetTeam() == hVecActorToApplyStateEffect[ i ]->GetTeam() )
continue;
break;
case CDnSkill::Friend:
case CDnSkill::Party:
if( GetTeam() != hVecActorToApplyStateEffect[ i ]->GetTeam() )
continue;
break;
// ½ºÅ³ Àû¿ë ´ë»óÀÌ ¾Æ±º/Àû±º ÀüºÎ ´Ù ¶ó¸é »óÅÂÈ¿°ú Àû¿ë ÂÊ¿¡¼­ Àû¿ë ¿©ºÎ¸¦ ±¸ºÐÇØ¾ß ÇÑ´Ù.
case CDnSkill::All:
break;
}
// »óÅÂÀÌ»ó Add ½Ã¿¡ Áö¼Ó ±¸ºÐ À妽º ó¸® ÇÊ¿ä.
// ÇØ´ç ActorÀÇ Áö¼ÓÈ¿°ú ±¸ºÐ À妽º¸¦ ±¸ºÐÇÏ¿© ¼º°øÇÑ °æ¿ì¿¡ »óÅÂÀÌ»ó Ãß°¡ ½ÃÅ´.
map<int, bool> mapDuplicateResult;
CDnSkill::CanApply eResult = CDnSkill::CanApplySkillStateEffect( hVecActorToApplyStateEffect[i], m_hProcessSkill, mapDuplicateResult, true );
if( CDnSkill::CanApply::Fail != eResult )
{
for( DWORD k = 0; k < m_hProcessSkill->GetStateEffectCount(); k++ )
{
CDnSkill::StateEffectStruct *pLocalStruct = m_hProcessSkill->GetStateEffectFromIndex(k);
if (pStruct->szSkipStateBlows && CDnSkill::IsSkipStateBlow(pStruct->szSkipStateBlows, (STATE_BLOW::emBLOW_INDEX)pLocalStruct->nID))
continue;
// ¾Æ±º±îÁö Èú ½ÃÄÑÁÖ´Â ½ºÅ³ÀÇ °æ¿ì¿£ Self Èú°ú Target Èú µÎ °³ÀÇ »óÅÂÈ¿°ú°¡ ¼±¾ðµÇ¾îÀÖµû.
// Self »óÅÂÈ¿°ú´Â Àڽſ¡°Ô ÀÌ¹Ì Àû¿ëµÇ¾ú°í ¿©±ä Hit ½Ã±×³Î ÆÇÁ¤µÇ´Â °÷ÀÌ±â ‹š¹®¿¡ Target ¸¸ Àû¿ëµÈ´Ù.
switch( pLocalStruct->ApplyType )
{
case CDnSkill::ApplySelf:
continue;
break;
case CDnSkill::ApplyTarget:
break;
case CDnSkill::ApplyEnemy:
if( GetTeam() == hVecActorToApplyStateEffect[ i ]->GetTeam() )
continue;
break;
case CDnSkill::ApplyFriend:
if( GetTeam() != hVecActorToApplyStateEffect[ i ]->GetTeam() )
continue;
break;
}
// °°Àº ½ºÅ³ ÁßøÀÏ °æ¿ì¿£ ½ºÅ³ È¿°ú Áß¿¡ È®·ü üũÇÏ´Â °ÍµéÀº ÀÌ¹Ì CanApplySkillStateEffect ¿¡¼­ È®·üüũµÇ°í
// Åë°úµÈ »óÅÂÀÌ´Ù. µû¶ó¼­ ¿©±â¼± È®·ü üũ µÈ°ÇÁö È®ÀÎÇÏ°í µÈ°Å¶ó¸é ´Ù½Ã È®·ü üũ ¾ÈÇϵµ·Ï ÇÔ¼ö È£Ãâ ÇØÁØ´Ù.
bool bAllowAddThisSE = true;
bool bCheckCanBegin = true;
if( CDnSkill::ApplyDuplicateSameSkill == eResult )
{
map<int, bool>::iterator iter = mapDuplicateResult.find( pLocalStruct->nID );
// ¸Ê¿¡ ¾ø´Â °æ¿ì ÇöÀç ¾×ÅͰ¡ »óÅÂÈ¿°ú¿¡ °É·ÁÀÖÁö ¾ÊÀ¸¹Ç·Î ±×³É Á¤»óÀûÀ¸·Î »óÅÂÈ¿°ú Ãß°¡ ·çƾ ½ÇÇà.
if( mapDuplicateResult.end() != iter )
{
// °°Àº ½ºÅ³ÀÇ È®·üÀÖ´Â »óÅÂÈ¿°ú°¡ ÇöÀç °É·ÁÀ־ CanAdd ¸¦ È£ÃâÇØº¸¾ÒÀ¸³ª ½ÇÆÐÇßÀ½.
// ÀÌ·± °æ¿ì¿£ »óÅÂÈ¿°ú Ãß°¡ÇÏÁö ¾Ê´Â´Ù.
if( false == (iter->second) )
bAllowAddThisSE = false;
else
// ÀÌ¹Ì CanAdd ¸¦ Åë°úÇÑ »óÅÂÀ̹ǷΠCmdAddStateEffect È£Ã⠽à µû·Î üũÇÏÁö ¾Êµµ·Ï ÇØÁØ´Ù.
bCheckCanBegin = false;
}
}
if( bAllowAddThisSE )
{
// #72931 ½ºÅ©¸®¸Ó ÀúÁÖ ÄðŸÀÓ °øÀ¯ ó¸® -> ³ªÁß¿¡ ÀÌ·±½ÄÀ¸·Î ¾²´Â°Å ¸¹¾ÆÁö¸é ÀϹÝÈ­ÇØ¾ßÇÔ
bool bShareCurseCoolTime = false;
if( pLocalStruct->nID == STATE_BLOW::BLOW_244 )
{
DNVector(DnBlowHandle) vlhBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_244, vlhBlows );
if( static_cast<int>( vlhBlows.size() ) > 0 )
{
CDnCurseBlow* pDnCurseBlow = static_cast<CDnCurseBlow*>( vlhBlows[0].GetPointer() );
if( pDnCurseBlow )
{
pLocalStruct->szValue += ";";
pLocalStruct->szValue += FormatA( "%f", pDnCurseBlow->GetCoolTime() );
bShareCurseCoolTime = true;
}
}
}
// ¿©±â¼­ µî·ÏµÇ¾î ÀÖ´Â Á¦°Å µÇ¾î¾ßÇÒ »óÅÂÈ¿°úµé ¾ø¾Ø´Ù. [2010/12/08 semozz]
hVecActorToApplyStateEffect[i]->RemoveResetStateBlow();
hVecActorToApplyStateEffect[i]->CmdAddStateEffect( m_hProcessSkill->GetInfo(), (STATE_BLOW::emBLOW_INDEX)pLocalStruct->nID,
pLocalStruct->nDurationTime, pLocalStruct->szValue.c_str(), false, bCheckCanBegin );
if( bShareCurseCoolTime ) // #72931 ÄðŸÀÓ ºÙ¿´´ø°Å ´Ù½Ã Á¦°Å
{
std::string::size_type delimiterindex = pLocalStruct->szValue.rfind( ";" );
if( delimiterindex != std::string::npos )
{
pLocalStruct->szValue.erase( delimiterindex, pLocalStruct->szValue.length() - delimiterindex );
}
}
// ¿ø·¡´Â OnDamage() È£ÃâµÇ¸é ¾ÈÂÊ¿¡¼­ DamageRemainTime À» ¼ÂÆÃÇØÁØ´Ù. ÇÏÁö¸¸
// Èúó·³ µ¥¹ÌÁö ¾øÀÌ »óÅÂÈ¿°ú¸¸ Ãß°¡½Ã۱â À§ÇÑ hit ½Ã±×³Îµµ ÀÖÀ¸¹Ç·Î OnDamage() È£ÃâµÇÁö ¾Ê¾Ò´õ¶óµµ
// ¿©±â¼­ LastDamageTime ÀÌ ¼ÂÆÃ ¾ÈµÇ¾îÀÖ´Â ³à¼®Àº ¼ÂÆÃÇØÁÖµµ·Ï ÇÑ´Ù.
// ÀÌ·¸°Ô ÇØ¾ß hit ½Ã±×³Î¿¡ Çѹ游 ¸Â´Â´Ù.
if( !bOnDamageCalled )
{
hVecActorToApplyStateEffect[ i ]->SetDamageRemainTime( GetUniqueID(), HitParam.RemainTime );
hVecActorToApplyStateEffect[ i ]->SetLastDamageHitUniqueID( GetUniqueID(), HitParam.iUniqueID );
}
}
}
}
// ½ºÅ³ »ç¿ë ³¡³µÀ¸¸é ¸®¼Â¸®½ºÆ® ÃʱâÈ­ [2010/12/09 semozz]
hVecActorToApplyStateEffect[i]->InitStateBlowIDToRemove();
}
}
if( bHit ) {
m_LastHitSignalTime = SignalEndTime;
OnHitFinish( LocalTime, pStruct );
}
else m_LastHitSignalTime = -1;
// ÇÁ¶ø üũ
// Note: ÇÁ¶øÃ¼Å©´Â »óÅÂÈ¿°ú¸¸ ÀÖ´Â Heal °°Àº °ÍÀº üũÇÏÁö ¾Êµµ·Ï ÇÕ´Ï´Ù. HitAction ÀÌ ¾ø´Â °ÍÀ¸·Î ±¸ºÐ.
if( false == HitParam.szActionName.empty()
//ÇÊÅͰ¡ Àû¿ëµÇ¾î ÀÖÁö ¾ÊÀ»¶§¸¸ ÇÁ¶ø¿¡ µ¥¹ÌÁö¸¦ ÁÙ ¼ö ÀÖ´Ù.
&& pStruct->StateEffectFilter == 0
)
{
DNVector(CEtWorldProp*) pVecProp;
CDnWorld* pWorld = CDnWorld::GetInstancePtr(GetRoom());
pWorld->ScanProp( vPos, fDistance, pVecProp );
for( DWORD i=0; i<pVecProp.size(); i++ )
{
if( false == ((CDnWorldProp*)pVecProp[i])->IsBrokenType() )
continue;
if( !((CDnWorldBrokenProp*)pVecProp[i])->IsHittable( GetMySmartPtr(), LocalTime ) )
continue;
pVecProp[i]->GetBoundingBox( Box );
if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue;
if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue;
vDir = ((CDnWorldProp*)pVecProp[i])->GetMatEx()->m_vPosition - vPos;
EtVec3Normalize( &vDir, &vDir );
fDot = EtVec3Dot( &vZVec, &vDir );
if( EtToDegree( acos( fDot ) ) > pStruct->fAngle )
continue;
if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < m_Cross.m_vPosition.y + pStruct->fHeightMin )
continue;
if( Box.Min.y > vPos.y + fHeightMax && Box.Max.y > m_Cross.m_vPosition.y + fHeightMax )
continue;
HitParam.vViewVec = -vDir;
((CDnWorldProp*)pVecProp[i])->OnDamage( GetMySmartPtr(), HitParam );
}
}
//////////////////////////////////////////////////////////////////////////
// Á¢µÎ¾î °ø°Ý¿ë ½ºÅ³ ³¡..
InitPrefixOffenceSkills();
//////////////////////////////////////////////////////////////////////////
// PROFILE_TICK_TEST_BLOCK_END();
}
break;
case STE_VelocityAccel:
{
VelocityAccelStruct *pStruct = (VelocityAccelStruct *)pPtr;
MAMovementBase *pMovement = GetMovement();
// #24949 VelocityAccel ½Ã±×³Î »ç¿ëÇÏ´Â ºÎºÐµµ ¸·µµ·Ï ó¸®.
EtVector3 vVelocity = *pStruct->vVelocity;
EtVector3 vResistance = *pStruct->vResistance;
if( 0 < GetCantXZMoveSEReferenceCount() )
{
vVelocity.x = vVelocity.z = 0.0f;
vResistance.x = vResistance.z = 0.0f;
}
if( pMovement )
{
pMovement->SetVelocity( vVelocity );
pMovement->SetResistance( vResistance );
}
}
break;
case STE_State:
{
if( IsCustomProcessSignal() ) break;
StateStruct *pStruct = (StateStruct *)pPtr;
int nState = CDnActorState::s_nActorStateIndex[pStruct->nStateOne] |
CDnActorState::s_nActorStateIndex[pStruct->nStateTwo] |
CDnActorState::s_nActorStateIndex[pStruct->nStateThree];
SetState( (ActorStateEnum)nState );
}
break;
case STE_CustomState:
{
if( IsCustomProcessSignal() ) break;
CustomStateStruct *pStruct = (CustomStateStruct *)pPtr;
int nState = CDnActorState::s_nActorCustomStateIndex[pStruct->nStateOne] |
CDnActorState::s_nActorCustomStateIndex[pStruct->nStateTwo] |
CDnActorState::s_nActorCustomStateIndex[pStruct->nStateThree];
SetCustomState( (ActorCustomStateEnum)nState );
}
break;
case STE_CanHit:
{
// °áºù »óŰ¡ µÇ¾úÀ»¶§ ÇöÀç ÁøÇàÁßÀÎ ¾×¼Ç¿¡¼­ ÇÁ·¹ÀÓÀÌ ½ºÅ¾µÇ´Â °æ¿ì°¡Àִµ¥
// ƯÁ¤ ¾×¼ÇÀÇ STE_CanHit °¡ False ÀÎ »óÅÂÀ϶§´Â °áºù»óÅ¿¡¼­µµ Hit °¡ µé¾î°¡Áö ¾Ê´ø ¹®Á¦°¡ À־ °áºù »óÅ¿¡¼­´Â ¹«Á¶°Ç
// ¸Âµµ·Ï ÇØÁØ´Ù.
if(GetStateBlow()->IsApplied( STATE_BLOW::BLOW_041))
{
SetHittable(true);
break;
}
CanHitStruct *pStruct = (CanHitStruct *)pPtr;
SetHittable( ( pStruct->bHittable == TRUE ) ? true : false );
}
break;
case STE_CanMove:
{
if( CDnActorState::Cant_Move != (m_StateEffect & CDnActorState::Cant_Move) )
{
CanMoveStruct *pStruct = (CanMoveStruct *)pPtr;
SetMovable( ( pStruct->bCanMove == TRUE ) ? true : false );
}
}
break;
case STE_SendAction_Weapon:
{
SendAction_WeaponStruct *pStruct = (SendAction_WeaponStruct *)pPtr;
if( 2 <= pStruct->nWeaponIndex ) // º¸Á¶¹«±â¿ë À妽ºÀÌ´Ù.
break;
if( !GetActiveWeapon( pStruct->nWeaponIndex ) ) break;
if( pStruct->szActionName )
{
// Ç÷¹ÀÌ¾î ¾×ÅÍÀÎ °æ¿ìÇöÀç ¾×¼Ç¿¡¼­ ½ò ¼ö ÀÖ´Â ¹ß»çü °¹¼ö¿¡ ¹«±âÀÇ ¹ß»çü °¹¼ö¸¦ ´õÇØÁØ´Ù.
if( GetActiveWeapon( pStruct->nWeaponIndex )->IsExistAction( pStruct->szActionName ) )
{
GetActiveWeapon( pStruct->nWeaponIndex )->SetActionQueue( pStruct->szActionName );
}
}
}
break;
case STE_MotionSpeed:
{
if( IsModifyPlaySpeed() ) break;
MotionSpeedStruct *pStruct = (MotionSpeedStruct *)pPtr;
float fIncreadSpeed = 1.f / pStruct->fFrame * 60.f;
DWORD dwTime = (DWORD)( ( SignalEndTime - SignalStartTime ) * fIncreadSpeed );
float fSpeed = 1.f / 60.f * pStruct->fFrame;
SetPlaySpeed( dwTime, fSpeed );
}
break;
case STE_NormalSuperAmmor:
{
NormalSuperAmmorStruct *pStruct = (NormalSuperAmmorStruct *)pPtr;
m_bEnableNormalSuperAmmor = ( pStruct->bEnable == TRUE ) ? true : false;
m_nNormalSuperAmmorTime = pStruct->nTime;
m_fBreakNormalSuperAmmorDurability = pStruct->fBreakDurability;
if ( m_bIngnoreNormalSuperArmor )
{
m_bEnableNormalSuperAmmor = false;
}
}
break;
case STE_ResetVelocity:
{
ResetVelocityStruct *pStruct = (ResetVelocityStruct *)pPtr;
if( pStruct->bXAxis ) {
SetVelocityX( 0.f );
SetResistanceX( 0.f );
}
if( pStruct->bYAxis ) {
SetVelocityY( 0.f );
SetResistanceY( 0.f );
}
if( pStruct->bZAxis ) {
SetVelocityZ( 0.f );
SetResistanceZ( 0.f );
}
}
break;
case STE_Projectile:
{
ProjectileStruct *pStruct = (ProjectileStruct *)pPtr;
OutputDebug("%s m_bOnSignalFromChargerSE: %d m_ActorType: %d", __FUNCTION__, m_bOnSignalFromChargerSE, m_ActorType);
// Note: Ç÷¹À̾îÀÎ °æ¿ì¿£ ¸ðµç ÇÁ·ÎÁ§Å¸ÀÏ ÆÐŶÀ» Ŭ¶ó·ÎºÎÅÍ ¹Þ¾Æ¼­ »ý¼ºÇÕ´Ï´Ù.
// Direction ŸÀÔÀÌ¶óµµ °¢ ·ÎÄÈ Ä«¸Þ¶ó ¹æÇâ¿¡ µû¸¥ ¼³Á¤µµ Àֱ⠶§¹®¿¡..
if( false == m_bOnSignalFromChargerSE )
if( m_ActorType <= CDnActorState::Reserved6 )
break;
MatrixEx LocalCross = *GetMatEx();
CDnProjectile *pProjectile = CDnProjectile::CreateProjectile( GetRoom(), GetMySmartPtr(), LocalCross, pStruct );
if( pProjectile == NULL ) break;
pProjectile->SetShooterType( GetMySmartPtr(), m_nActionIndex, nSignalIndex );
//bool bActorAttachWeapon = false;
//if( pStruct->nWeaponTableID == 0 && GetWeapon(1) ) bActorAttachWeapon = true;
if( m_bOnSignalFromChargerSE && m_hChargetDestActor )
{
DNVector(DnBlowHandle) vlhChargerBlows;
m_hChargetDestActor->GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_062, vlhChargerBlows ); // 1°³ ÀÌ»ó Áߺ¹µÇÁö ¾Ê´Â °Ô ÁÁÀºµ¥ ±âȹ¿¡¼­ ¾îÂî ÇÒÁö.
for( int i = 0; i < (int)vlhChargerBlows.size(); ++i )
{
if( vlhChargerBlows[i] )
static_cast<CDnChargerBlow*>( vlhChargerBlows.at( i ).GetPointer() )->OnProjectileSignal( pProjectile );
}
}
if( false == m_bOnSignalFromChargerSE )
{
OnProjectile( pProjectile, pStruct, LocalCross, nSignalIndex );
OnSkillProjectile( pProjectile );
}
}
break;
case STE_SkillSuperAmmor:
{
SkillSuperAmmorStruct *pStruct = (SkillSuperAmmorStruct *)pPtr;
m_nSkillSuperAmmorValue[0] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorOneProb );
m_nSkillSuperAmmorValue[1] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorTwoProb );
m_nSkillSuperAmmorValue[2] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorThreeProb );
m_nSkillSuperAmmorValue[3] = (int)( GetSuperAmmor() * pStruct->fSuperAmmorFourProb );
memcpy( m_nLastUpdateSkillSuperAmmorValue, m_nSkillSuperAmmorValue, sizeof(m_nSkillSuperAmmorValue) );
m_nSkillSuperAmmorTime = pStruct->nTime;
m_fSkillSuperAmmorDamageDecreaseProb = pStruct->fDamageDecreaseProb;
}
break;
case STE_SummonMonster:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonMonsterStruct* pStruct = (SummonMonsterStruct *)pPtr;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
if( pGameTask )
{
// ³»ºÎÀûÀ¸·Î °ªÀ» ¹Ù²ã¼­ »ç¿ëÇϱ⠶§¹®¿¡ ¹Ýµå½Ã º¹»çÇØ¼­ »ç¿ëÇÑ´Ù.
#ifdef PRE_FIX_MEMOPT_SIGNALH
SummonMonsterStruct Struct;
CopyShallow_SummonMonsterStruct(Struct, pStruct);
#else
SummonMonsterStruct Struct = *pStruct;
#endif
// 167¹ø ¼Òȯ ¸ó½ºÅÍ ½ºÅ³·¹º§ °­Á¦ ¼ÂÆÃ »óÅÂÈ¿°ú ó¸®. ///////////////////
if( IsPlayerActor() )
{
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_167 ) )
{
DNVector(DnBlowHandle) vlBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_167, vlBlows );
if( false == vlBlows.empty() )
{
Struct.nForceSkillLevel = (int)vlBlows.front()->GetFloatValue();
}
}
}
//////////////////////////////////////////////////////////////////////////
if(Struct.PositionCheck == TRUE )
{
MatrixEx Cross = *GetMatEx();
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
if( INSTANCE(CDnWorld).IsOnNavigationMesh( Cross.GetPosition() ) == false )
break;
}
pGameTask->RequestSummonMonster( GetActorHandle(), &Struct );
}
}
break;
//case STE_SummonProp:
// {
// SummonPropStruct *pStruct = (SummonPropStruct *)pPtr;
// MatrixEx Cross = m_Cross;
// Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
// Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
// Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
// float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
// EtVector3 vRotate;
// vRotate = *pStruct->vRotate;
// vRotate.y += EtToDegree( acos(fDot) );
// CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
// DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, Cross.m_vPosition, vRotate, *pStruct->vScale );
// }
// break;
// ****************************************************************************************************************
// ÇÁ¶ø ¼Òȯ ½Ã±×³Î¿¡¼­ ¼ÒȯµÇ´Â ÇÁ¶ø Ŭ·¡½ºµéÀº ¹Ýµå½Ã void ReleasePostCustomParam() ¸¦ ±¸ÇöÇØ¾ß ÇÔ!!
// ŸÀÔ¿¡ ¸ÂÃç¼­ ÇÁ¶ø struct ¸¦ »èÁ¦ÇÏÁö ¾ÊÀ¸¸é boost::pool ¿¡¼­ ¸Þ¸ð¸® courrupt
// ****************************************************************************************************************
case STE_SummonChestProp:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonChestPropStruct *pStruct = (SummonChestPropStruct *)pPtr;
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
EtVector3 vRotate;
vRotate = *pStruct->vRotate;
vRotate.y += EtToDegree( acos(fDot) );
ChestStruct* pChestPropInfo = new ChestStruct;
pChestPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID;
pChestPropInfo->nNeedKeyID = pStruct->nNeedKeyID;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_Chest, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pChestPropInfo );
if( -1 < pStruct->nLifeTime )
hProp->SetLifeTime( pStruct->nLifeTime );
hProp->SetMasterActor(GetMySmartPtr());
}
break;
case STE_SummonBrokenProp:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonBrokenPropStruct *pStruct = (SummonBrokenPropStruct *)pPtr;
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
EtVector3 vRotate;
vRotate = *pStruct->vRotate;
vRotate.y += EtToDegree( acos(fDot) );
BrokenStruct* pBrokenPropInfo = new BrokenStruct;
pBrokenPropInfo->nDurability = pStruct->nDurability;
pBrokenPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_Broken, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBrokenPropInfo );
if( -1 < pStruct->nLifeTime )
hProp->SetLifeTime( pStruct->nLifeTime );
hProp->SetMasterActor(GetMySmartPtr());
}
break;
case STE_SummonBrokenDamageProp:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonBrokenDamagePropStruct *pStruct = (SummonBrokenDamagePropStruct *)pPtr;
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
EtVector3 vRotate;
vRotate = *pStruct->vRotate;
vRotate.y += EtToDegree( acos(fDot) );
BrokenDamageStruct* pBrokenDamagePropInfo = new BrokenDamageStruct;
pBrokenDamagePropInfo->nMonsterTableID = 102; // goblin
pBrokenDamagePropInfo->nDurability = pStruct->nDurability;
pBrokenDamagePropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID;
pBrokenDamagePropInfo->nSkillTableID = pStruct->nSkillTableID;
pBrokenDamagePropInfo->nSkillLevel = pStruct->nSkillLevel;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_BrokenDamage, Cross.m_vPosition, vRotate,
*pStruct->vScale, pStruct->nLifeTime, (void*)pBrokenDamagePropInfo );
if( !hProp )
break;
MAActorProp* pActorProp = dynamic_cast<MAActorProp*>(hProp.GetPointer());
_ASSERT( pActorProp );
if( pActorProp )
pActorProp->CopyActorStateFromThis( GetMySmartPtr() );
if( -1 < pStruct->nLifeTime )
hProp->SetLifeTime( pStruct->nLifeTime );
hProp->SetMasterActor(GetMySmartPtr());
}
break;
case STE_SummonHitMoveDamageBrokenProp:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonHitMoveDamageBrokenPropStruct *pStruct = (SummonHitMoveDamageBrokenPropStruct *)pPtr;
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
EtVector3 vRotate;
vRotate = *pStruct->vRotate;
vRotate.y += EtToDegree( acos(fDot) );
HitMoveDamageBrokenStruct* pHitMoveDamageBrokenPropInfo = new HitMoveDamageBrokenStruct;
pHitMoveDamageBrokenPropInfo->nMonsterTableID = 102; // goblin
pHitMoveDamageBrokenPropInfo->nDurability = pStruct->nDurability;
pHitMoveDamageBrokenPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID;
pHitMoveDamageBrokenPropInfo->MovingAxis = pStruct->MovingAxis;
pHitMoveDamageBrokenPropInfo->fDefaultAxisMovingSpeed = pStruct->fDefaultAxisMovingSpeed;
pHitMoveDamageBrokenPropInfo->fMaxAxisMoveDistance = pStruct->fMaxAxisMoveDistance;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_HitMoveDamageBroken, Cross.m_vPosition, vRotate,
*pStruct->vScale, pStruct->nLifeTime, (void*)pHitMoveDamageBrokenPropInfo );
if( !hProp )
break;
MAActorProp* pActorProp = dynamic_cast<MAActorProp*>(hProp.GetPointer());
_ASSERT( pActorProp );
if( pActorProp )
pActorProp->CopyActorStateFromThis( GetMySmartPtr() );
if( -1 < pStruct->nLifeTime )
hProp->SetLifeTime( pStruct->nLifeTime );
hProp->SetMasterActor(GetMySmartPtr());
}
break;
case STE_SummonBuffProp:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonBuffPropStruct *pStruct = (SummonBuffPropStruct *)pPtr;
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
EtVector3 vRotate;
vRotate = *pStruct->vRotate;
vRotate.y += EtToDegree( acos(fDot) );
BuffStruct* pBuffPropInfo = new BuffStruct;
pBuffPropInfo->nMonsterTableID = 102; // goblin
pBuffPropInfo->nSkillTableID = pStruct->nSkillTableID;
pBuffPropInfo->nSkillLevel = pStruct->nSkillLevel;
pBuffPropInfo->nTeam = pStruct->nTeam;
pBuffPropInfo->fCheckRange = pStruct->fCheckRange;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_Buff, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBuffPropInfo );
if( !hProp )
break;
MAActorProp* pActorProp = dynamic_cast<MAActorProp*>(hProp.GetPointer());
_ASSERT( pActorProp );
if( pActorProp )
pActorProp->CopyActorStateFromThis( GetMySmartPtr() );
if( -1 < pStruct->nLifeTime )
hProp->SetLifeTime( pStruct->nLifeTime );
static_cast<CDnBuffProp*>(hProp.GetPointer())->SetSummoner( GetMySmartPtr() );
hProp->SetMasterActor(GetMySmartPtr());
}
break;
case STE_SummonBuffBrokenProp:
{
// #48747 ¾ÆÄ«µ¥¹Í °°ÀÌ ¼Òȯü·Î °ø°ÝÀ» ÇÏ´Â °æ¿ì¿£ ½ºÇÙÀ» ½á¼­ °É·Á ÀÖÀ¸¸é ¼Òȯµµ ¾ÈµÇ¾î¾ß ÇÔ..
if( IsPlayerActor() && ((CDnPlayerActor*)this)->IsInvalidPlayerChecker() ) break;
SummonBuffBrokenPropStruct *pStruct = (SummonBuffBrokenPropStruct *)pPtr;
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vPosition->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vPosition->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vPosition->z;
float fDot = EtVec3Dot( &EtVector3( 0.f, 0.f, 1.f ), &Cross.m_vZAxis );
EtVector3 vRotate;
vRotate = *pStruct->vRotate;
vRotate.y += EtToDegree( acos(fDot) );
BuffBrokenStruct* pBuffBrokenPropInfo = new BuffBrokenStruct;
pBuffBrokenPropInfo->nMonsterTableID = 102; // goblin
pBuffBrokenPropInfo->nDurability = pStruct->nDurability;
pBuffBrokenPropInfo->nItemDropGroupTableID = pStruct->nItemDropGroupTableID;
pBuffBrokenPropInfo->nSkillTableID = pStruct->nSkillTableID;
pBuffBrokenPropInfo->nSkillLevel = pStruct->nSkillLevel;
pBuffBrokenPropInfo->nTeam = pStruct->nTeam;
pBuffBrokenPropInfo->fCheckRange = pStruct->fCheckRange;
CDnGameTask* pGameTask = static_cast<CDnGameTask*>(CTaskManager::GetInstancePtr(GetRoom())->GetTask( "GameTask" ));
DnPropHandle hProp = pGameTask->RequestGenerationProp( pStruct->nSummonPropTableID, PTE_BuffBroken, Cross.m_vPosition, vRotate, *pStruct->vScale, pStruct->nLifeTime, (void*)pBuffBrokenPropInfo );
if( !hProp )
break;
MAActorProp* pActorProp = dynamic_cast<MAActorProp*>(hProp.GetPointer());
_ASSERT( pActorProp );
if( pActorProp )
pActorProp->CopyActorStateFromThis( GetMySmartPtr() );
if( -1 < pStruct->nLifeTime )
hProp->SetLifeTime( pStruct->nLifeTime );
static_cast<CDnWorldBrokenBuffProp*>(hProp.GetPointer())->SetSummoner( GetMySmartPtr() );
hProp->SetMasterActor(GetMySmartPtr());
}
break;
// ****************************************************************************************************************
// ÇÁ¶ø ¼Òȯ ½Ã±×³Î¿¡¼­ ¼ÒȯµÇ´Â ÇÁ¶ø Ŭ·¡½ºµéÀº ¹Ýµå½Ã void ReleasePostCustomParam() ¸¦ ±¸ÇöÇØ¾ß ÇÔ!!
// ****************************************************************************************************************
case STE_DropItem:
{
DropItemStruct *pStruct = (DropItemStruct*)pPtr;
DNVector(CDnItem::DropItemStruct) VecList;
CDnDropItem::CalcDropItemList( GetRoom(), pStruct->nDropItemTableID, VecList );
MatrixEx Cross = m_Cross;
Cross.m_vPosition += Cross.m_vXAxis * pStruct->vOffset->x;
Cross.m_vPosition += Cross.m_vYAxis * pStruct->vOffset->y;
Cross.m_vPosition += Cross.m_vZAxis * pStruct->vOffset->z;
CDnItemTask *pTask = (CDnItemTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "ItemTask" );
int nSeed = 0;
for( DWORD i=0; i<VecList.size(); i++ )
{
#if defined(PRE_FIX_46730)
//bFixPositionÀÌ true·Î ¼³Á¤µÇ¸é nSeed°ªÀ» 0À¸·Î ¼³Á¤Çؼ­ ¾ÆÀÌÅÛ À§Ä¡ º¸Á¤À» ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù.
if (( pStruct->bFixPosition?true:false) == true)
nSeed = 0;
else
nSeed = VecList[i].nSeed;
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, nSeed, VecList[i].nCount, 0, -1, VecList[i].nEnchantID );
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, nSeed, VecList[i].nCount, 0 );
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
#else
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, VecList[i].nSeed, VecList[i].nCount, 0, -1, VecList[i].nEnchantID );
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pTask->RequestDropItem( VecList[i].dwUniqueID, Cross.m_vPosition, VecList[i].nItemID, VecList[i].nSeed, VecList[i].nCount, 0 );
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
#endif // PRE_FIX_46730
}
}
break;
// Çѱâ 2009.7.27
// Àڽſ¡°Ô »ç¿ëÇÏ´Â È¿°ú Àû¿ë ½Ã°£ °ü·Ã (#1911)
case STE_ApplyStateEffect:
{
// ½ºÅ³À» »ç¿ëÇÑ ¼ø°£ »óÅÂÈ¿°ú Àû¿ëµÇ±â Àü¿¡ ¾×ÅͰ¡ Á×À¸¸é »óÅÂÈ¿°ú´Â Ãß°¡µÇÁö ¾ÊÀ¸¹Ç·Î
// ¾Æ·¡·Î »óÅÂÈ¿°ú ·çƾÀ» ÁøÇà½ÃŰÁö ¾Ê´Â´Ù.
if( GetHP() <= 0 )
{
if( m_hAuraSkill && m_hAuraSkill->IsAuraOn() )
{
OnSkillAura( m_hAuraSkill, false );
}
ClearSelfStateSignalBlowQueue();
break;
}
if( false == m_dqApplySelfStateBlowQ.empty() )
{
ApplyStateEffectStruct* pStruct = (ApplyStateEffectStruct*)pPtr;
if( pStruct->StateEffectIndex < (int)m_dqApplySelfStateBlowQ.size() )
{
const S_NO_PACKET_SELF_STATEBLOW& StateBlowInfo = m_dqApplySelfStateBlowQ.at( pStruct->StateEffectIndex );
ApplyStateEffectSignalProcess(StateBlowInfo, pStruct);
}
else
{
OutputDebug( "[Error!!]CDnActor::OnSignal, case STE_ApplyStateEffect: ½ºÅ³¿¡ µé¾îÀÖ´Â »óÅÂÈ¿°ú °¹¼ö(%d)¸¦ ¹þ¾î³­ Àû¿ë »óÅÂÈ¿°ú À妽º(%d)ÀÓ.\n",
(int)m_dqApplySelfStateBlowQ.size(), pStruct->StateEffectIndex );
_ASSERT( !"case STE_ApplyStateEffect: ½ºÅ³¿¡ µé¾îÀÖ´Â »óÅÂÈ¿°ú °¹¼ö¸¦ ¹þ¾î³­ Àû¿ë »óÅÂÈ¿°ú À妽ºÀÓ" );
}
}
}
break;
case STE_Parring:
{
ParringStruct* pStruct = (ParringStruct*)pPtr;
DNVector(DnBlowHandle) vlhParryBlows;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_031, vlhParryBlows );
int iNumParryBlow = (int)vlhParryBlows.size();
for( int i = 0; i < iNumParryBlow; ++i )
{
DnBlowHandle hParryBlow = vlhParryBlows.at( i );
if( !hParryBlow )
continue;
const CDnSkill::SkillInfo* pParentSkillInfo = hParryBlow->GetParentSkillInfo();
if( pParentSkillInfo && pStruct->nSkillID == pParentSkillInfo->iSkillID )
{
CDnParryBlow* pParryBlow = static_cast<CDnParryBlow*>(hParryBlow.GetPointer());
if( false == pParryBlow->IsEnabled() )
{
pParryBlow->EnableParrying( pStruct->fProb );
pParryBlow->SetParringActionName( pStruct->szParringActionName );
}
}
}
}
break;
case STE_CooltimeParring:
{
CooltimeParringStruct* pStruct = (CooltimeParringStruct*)pPtr;
DNVector(DnBlowHandle) vlhParryBlows;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_153, vlhParryBlows );
int iNumParryBlow = (int)vlhParryBlows.size();
for( int i = 0; i < iNumParryBlow; ++i )
{
DnBlowHandle hParryBlow = vlhParryBlows.at( i );
if( !hParryBlow )
continue;
const CDnSkill::SkillInfo* pParentSkillInfo = hParryBlow->GetParentSkillInfo();
if( pParentSkillInfo && pStruct->nSkillID == pParentSkillInfo->iSkillID )
{
CDnCooltimeParryBlow* pParryBlow = static_cast<CDnCooltimeParryBlow*>(hParryBlow.GetPointer());
if( false == pParryBlow->IsEnabled() )
{
pParryBlow->EnableParrying( pStruct->fProb );
pParryBlow->SetParringActionName( pStruct->szParringActionName );
}
}
}
}
break;
case STE_Gravity:
{
GravityStruct *pStruct = (GravityStruct *)pPtr;
MatrixEx CrossOffset = m_Cross;
CrossOffset.MoveLocalXAxis( pStruct->vOffset->x );
CrossOffset.MoveLocalYAxis( pStruct->vOffset->y );
CrossOffset.MoveLocalZAxis( pStruct->vOffset->z );
DNVector(DnActorHandle) hVecList;
CDnActor::ScanActor( GetRoom(), CrossOffset.m_vPosition, pStruct->fDistanceMax, hVecList );
#ifdef PRE_ADD_GRAVITY_PROPERTY
EtVector3 vPos = CrossOffset.m_vPosition;
float fXZDistanceMaxSQ = pStruct->fDistanceMax;
float fXZDistanceMinSQ = pStruct->fDistanceMin;
fXZDistanceMaxSQ *= fXZDistanceMaxSQ;
fXZDistanceMinSQ *= fXZDistanceMinSQ;
SAABox Box;
float fDot = 0.0f;
EtVector3 vZVec = m_Cross.m_vZAxis;
if( pStruct->fCenterAngle != 0.f )
{
EtMatrix matRotate;
EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) );
EtVec3TransformNormal( &vZVec, &vZVec, &matRotate );
}
#endif // PRE_ADD_GRAVITY_PROPERTY
for( DWORD i=0; i<hVecList.size(); i++ ) {
if( !hVecList[i] ) continue;
if( hVecList[i] == GetMySmartPtr() ) continue;
if( hVecList[i]->IsDie() ) continue;
if( hVecList[i]->GetWeight() == 0.f ) continue;
if( hVecList[i]->IsNpcActor() ) continue;
if( hVecList[i]->ProcessIgnoreGravitySignal() ) continue;
bool bHittable = false;
switch( pStruct->nTargetType ) {
case 0: // Enemy
if( hVecList[i]->GetTeam() == GetTeam() ) break;
bHittable = true;
break;
case 1: // Friend
if( hVecList[i]->GetTeam() != GetTeam() ) break;
bHittable = true;
break;
case 2: // All
bHittable = true;
break;
}
if( !bHittable ) continue;
bHittable = true;
switch( pStruct->nApplyTargetState ) {
case 0: // Normal
if( hVecList[i]->GetState() == CDnActorState::Down ) break;
bHittable = true;
break;
case 1: // Down
if( !( hVecList[i]->GetState() & CDnActorState::Down ) ) break;
bHittable = true;
break;
case 2: // Normal + Down
bHittable = true;
break;
}
if( !bHittable ) continue;
#ifdef PRE_ADD_GRAVITY_PROPERTY
bool bCheckArea = true;
DnActorHandle hActor = hVecList[i];
EtVector3 vDirActorToPos;
vDirActorToPos = *hActor->GetPosition() - vPos;
vDirActorToPos.y = 0.f;
hActor->GetBoundingBox( Box );
float fSQDistance = SquaredDistance( vPos, Box );
if( fSQDistance > fXZDistanceMaxSQ )
bCheckArea = false;
if( fSQDistance <= fXZDistanceMinSQ )
bCheckArea = false;
if( pStruct->fAngle != 0.0f )
{
EtVec3Normalize( &vDirActorToPos, &vDirActorToPos );
fDot = EtVec3Dot( &vZVec, &vDirActorToPos );
if( EtToDegree( acos( fDot ) ) > pStruct->fAngle )
bCheckArea = false;
}
if( pStruct->fHeightMax == 0.0f )
pStruct->fHeightMax = 3000.0f;
if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin )
bCheckArea = false;
if( Box.Min.y > vPos.y + pStruct->fHeightMax && Box.Max.y > vPos.y + pStruct->fHeightMax )
bCheckArea = false;
if( !bCheckArea )
{
hActor->SetVelocityZ( 0.0f );
hActor->SetResistanceZ( 0.0f );
hActor->ResetLook();
continue;
}
#endif // PRE_ADD_GRAVITY_PROPERTY
MAMovementBase *pMovement = hVecList[i]->GetMovement();
if( !pMovement ) continue;
EtVector3 vDir = *hVecList[i]->GetPosition() - CrossOffset.m_vPosition;
float fDistance = EtVec3Length( &vDir );
float fDistance2 = EtVec3Length( &EtVector3( vDir.x, 0.f, vDir.z ) );
EtVec3Normalize( &vDir, &vDir );
#ifdef PRE_ADD_GRAVITY_PROPERTY
float fDistanceMaxToMin = pStruct->fDistanceMax - pStruct->fDistanceMin;
float fTemp = 0.0f;
if( fDistanceMaxToMin > 0.0f )
fTemp = pStruct->fMinVelocity + ( ( (pStruct->fMaxVelocity - pStruct->fMinVelocity) / fDistanceMaxToMin ) * ( fDistanceMaxToMin - fDistance ) );
float fHeight = CrossOffset.m_vPosition.y - hVecList[i]->GetPosition()->y;
float fHeightMaxToMin = pStruct->fHeightMax - pStruct->fHeightMin;
float fTempVertical = 0.0f;
if( fHeightMaxToMin > 0.0f )
fTempVertical = pStruct->fMinVelocity_Vertical + ( ( (pStruct->fMaxVelocity_Vertical - pStruct->fMinVelocity_Vertical) / fHeightMaxToMin ) * ( fHeightMaxToMin - fHeight ) );
#else // PRE_ADD_GRAVITY_PROPERTY
float fTemp = pStruct->fMinVelocity + ( ( (pStruct->fMaxVelocity - pStruct->fMinVelocity) / pStruct->fDistanceMax ) * ( pStruct->fDistanceMax - fDistance ) );
#endif // PRE_ADD_GRAVITY_PROPERTY
EtVector3 vVel;
if( pMovement ) {
EtVector3 vCurLook = *pMovement->GetLookDir();
pMovement->Look( EtVec3toVec2(vDir), true );
pMovement->SetVelocityZ( -fTemp );
pMovement->SetResistanceZ( fTemp * 2.f );
#ifdef PRE_ADD_GRAVITY_PROPERTY
if( fTempVertical > 0.0f )
{
pMovement->SetVelocityY( fTempVertical );
pMovement->SetResistanceY( fTempVertical * 2.f );
pMovement->SetAppliedYDistance( true );
hVecList[i]->SetGravityEnd( 0.2f + ( float(SignalEndTime - SignalStartTime) / 1000.0f ) );
}
#endif // PRE_ADD_GRAVITY_PROPERTY
pMovement->Look( EtVec3toVec2(vCurLook), true );
}
}
}
break;
case STE_MoveY:
{
if( m_pMovement )
{
MoveYStruct* pStruct = (MoveYStruct*)pPtr;
float fYDelta = pStruct->fVelocityY * ((float(SignalEndTime - SignalStartTime) / 1000.0f));
float fWholeMoveYDistance = (0.0f < fYDelta) ? fYDelta : -fYDelta;
m_pMovement->SetMoveYDistancePerSec( pStruct->fVelocityY, fWholeMoveYDistance, (pStruct->bMaintainYPos == TRUE) ? true : false );
}
}
break;
// Signal Rotate.
case STE_Rotate:
{
RotateStruct * pStruct = static_cast< RotateStruct * >( pPtr );
float fLength = (float)( SignalEndTime - SignalStartTime ) * (CDnActionBase::m_fFPS / 60.0f);
DWORD dwTime = (DWORD)( fLength - 16.6666f );
SetRotate( dwTime, pStruct->fStartSpeed, pStruct->fEndSpeed, *(pStruct->vAxis), pStruct->bLeft == TRUE ? true : false );
}
break;
}
}
LOCAL_TIME CDnActor::CheckRemainFrameTime()
{
float fCurFrame = GetCurFrame();
int nCurActionIndex = GetCurrentActionIndex();
ActionElementStruct *pStruct = GetElement(nCurActionIndex);
LOCAL_TIME remainTime = 0;
if (pStruct)
remainTime = pStruct->dwLength - (LOCAL_TIME)fCurFrame;
return remainTime;
}
bool CDnActor::SetActionQueue( const char *szActionName, int nLoopCount, float fBlendFrame, float fStartFrame, bool bCheck, bool bCheckStateEffect )
{
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_224 ) )
{
DNVector(DnBlowHandle) vlhDisableActionSetBlow;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_224, vlhDisableActionSetBlow );
// ¾×¼Ç ¼Â º¯°æ »óÅÂÈ¿°ú´Â ¿©·¯°³ ÀÖÀ» ¼ö ÀÖ´Ù.
int iNumBlow = (int)vlhDisableActionSetBlow.size();
for( int i = 0; i < iNumBlow; ++i )
{
CDnDisableActionBlow* pDisableActionSetBlow = static_cast<CDnDisableActionBlow*>( vlhDisableActionSetBlow.at( i ).GetPointer() );
if(pDisableActionSetBlow->IsMatchedAction(szActionName))
return false;
}
}
const char *szName = szActionName;
if( bCheck ) {
if( m_szActionQueue.empty() ) {
if( strcmp( szName, m_szAction.c_str() ) == NULL )
{
LOCAL_TIME remainTime = CheckRemainFrameTime();
//ÇöÀç µ¿ÀÛÀÌ °ÅÀÇ ³¡±îÁö °¬´Ù¸é µ¿ÀÛ ³¡³µ´Ù°í º¸°í ´ÙÀ½ µ¿ÀÛ ¿¹¾àÇÑ´Ù..
if (remainTime >= 20)
return false;
}
}
else {
if( strcmp( szName, m_szActionQueue.c_str() ) == NULL )
{
LOCAL_TIME remainTime = CheckRemainFrameTime();
//ÇöÀç µ¿ÀÛÀÌ °ÅÀÇ ³¡±îÁö °¬´Ù¸é µ¿ÀÛ ³¡³µ´Ù°í º¸°í ´ÙÀ½ µ¿ÀÛ ¿¹¾àÇÑ´Ù..
if (remainTime >= 20)
return false;
}
}
}
int nCurrentActionIndex = GetElementIndex( szName );
if( bCheckStateEffect && nCurrentActionIndex > -1 )
{
int nActionState = GetState( nCurrentActionIndex );
// State¿¡ µû¶ó ¼¼ºÎÀûÀ¸·Î ³ª´¶´Ù~
// °ø°ÝºÒ°¡ÀÏ ¶© °ø°Ý state ÀÎ ¾×¼ÇÀº »ç¿ë ¸øÇÔ.
if( (nActionState & ActorStateEnum::Attack) && !( nActionState & ActorStateEnum::IgnoreCantAction) )
{
if( (GetStateEffect() & CDnActorState::Cant_AttackAction) == CDnActorState::Cant_AttackAction )
{
if( !IsDie() || IsGMTrace() )
return false;
}
}
}
CDnActionBase::SetActionQueue( szName, nLoopCount, fBlendFrame, fStartFrame );
if( nCurrentActionIndex != -1 ) {
for( int i=(int)m_VecPreActionState[nCurrentActionIndex].size()-1; i>=0; i-- ) {
if( (int)fStartFrame >= m_VecPreActionState[nCurrentActionIndex][i].nOffset ) {
SetState( (CDnActorState::ActorStateEnum)m_VecPreActionState[nCurrentActionIndex][i].nState );
break;
}
}
for( int i=(int)m_VecPreActionCustomState[nCurrentActionIndex].size()-1; i>=0; i-- ) {
if( (int)fStartFrame >= m_VecPreActionCustomState[nCurrentActionIndex][i].nOffset ) {
SetCustomState( (CDnActorState::ActorCustomStateEnum)m_VecPreActionCustomState[nCurrentActionIndex][i].nState );
break;
}
}
for( int i=(int)m_VecPreCanMoveState[nCurrentActionIndex].size()-1; i>=0; i-- ) {
if( (int)fStartFrame >= m_VecPreCanMoveState[nCurrentActionIndex][i].nOffset ) {
SetMovable( ( m_VecPreCanMoveState[nCurrentActionIndex][i].nState == TRUE ) ? true : false );
break;
}
}
}
return true;
}
void CDnActor::SetCustomAction( const char *szActionName, float fFrame )
{
if( m_hToggleSkill && m_hToggleSkill->IsToggleOn() )
{
CDnChangeActionStrProcessor* pChangeAction = static_cast<CDnChangeActionStrProcessor*>( m_hToggleSkill->GetProcessor( IDnSkillProcessor::CHANGE_ACTIONSTR ) );
if( pChangeAction ) {
pChangeAction->GetChangeActionName( szActionName );
}
}
CDnActionBase::SetCustomAction( szActionName, fFrame );
}
void CDnActor::ProcessDown( LOCAL_TIME LocalTime, float fDelta )
{
if( IsDie() ) return;
if( GetState() == CDnActorState::Down && m_fDownDelta > 0.f )
{
m_fDownDelta -= ( fDelta * ( ( 1.f / 60.f ) * CDnActionBase::GetFPS() ) );
if( m_fDownDelta <= 0.f ) {
m_fDownDelta = 0.f;
m_fLastDownRatio = 1.f;
SetActionQueue( "Down_StandUp", 0, 0.f, 0.f, true, false );
}
}
}
void CDnActor::ProcessStiff( LOCAL_TIME LocalTime, float fDelta )
{
if( IsDie() ) return;
if( IsStiff() ) {
if( m_fStiffDelta == 0.f ) return;
m_fStiffDelta -= ( fDelta * ( ( 1.f / 60.f ) * CDnActionBase::GetFPS() ) );
if( m_fStiffDelta <= 0.f ) {
m_fStiffDelta = 0.f;
ActionElementStruct *pStruct = GetElement( m_szAction.c_str() );
if( pStruct ) SetActionQueue( pStruct->szNextActionName.c_str(), 0, 3.f );
else SetActionQueue( "Stand", 0, 3.f );
}
}
else m_fStiffDelta = 0.f;
}
void CDnActor::ProcessDie( LOCAL_TIME LocalTime, float fDelta )
{
if( !IsDie() ) return;
m_fDieDelta -= fDelta;
if( m_fDieDelta <= 0.f ) {
SetDestroy();
return;
}
}
void CDnActor::RequestKillAfterProcessStateBlow(DnActorHandle hHitter)
{
m_bCompleteKill_AfterProcessStateBlow = true;
m_hCompleteKillActor = hHitter;
}
void CDnActor::ExecuteKillAfterProcessStateBlow()
{
if(m_bCompleteKill_AfterProcessStateBlow)
{
SetHP( 0 );
RequestHPMPDelta( CDnState::ElementEnum_Amount, -( GetMaxHP() *2 ), GetUniqueID() );
m_bCompleteKill_AfterProcessStateBlow = false;
//ÃÖÁ¾ DieÈ£Ãâ
Die(m_hCompleteKillActor);
m_hCompleteKillActor.Identity();
}
}
void CDnActor::CmdRefreshHPSP( INT64 nHP, int nSP )
{
SetHP( min( nHP, GetMaxHP() ) );
SetSP( min( nSP, GetMaxSP() ) );
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &m_nHP, sizeof(INT64) );
Stream.Write( &m_nSP, sizeof(int) );
//printf("[RLKT_DEBUG][%s] CurHP: %lld FuncRecvCurHP: %lld SP: %d\n", __FUNCTION__, m_nHP, nHP , m_nSP);
Send( eActor::SC_REFRESHHPSP, &Stream );
}
void CDnActor::CmdAction( const char *szActionName, int nLoopCount, float fBlendFrame, bool bCheckOverlapAction, bool bFromStateBlow/* = false*/, bool bSkillChain/* = false*/ )
{
SetActionQueue( szActionName, nLoopCount, fBlendFrame, 0.f, bCheckOverlapAction );
// Note: ¶óÀÌ¡ ½½·¡½Ã ó·³ ÀԷ¿¡ µû¶ó ¿©·¯ ¾×¼ÇÀÌ ³ª´µ¾î ³ª°¡´Â °æ¿ì ½ºÅ³ÀÇ
// »óÅÂÈ¿°ú°¡ Áö¼ÓµÇ¾î¾ß ÇϹǷΠ½ºÅ³ ÂÊ¿¡ ¾Ë·ÁÁÖµµ·Ï ÇÑ´Ù.
// ¼­¹ö·Î´Â CmdActon ÀÌ È£ÃâµÉ ¶§ ÆÐŶ¿¡ °°ÀÌ ³¯¾Æ°¨.
if( bSkillChain )
{
if( m_hProcessSkill )
m_hProcessSkill->OnChainInput( szActionName );
}
}
int CDnActor::CmdAddStateEffect( const CDnSkill::SkillInfo* pParentSkillInfo, STATE_BLOW::emBLOW_INDEX emBlowIndex, int nDurationTime, const char *szParam, bool bOnPlayerInit/* = false*/, bool bCheckCanBegin/* = true*/ , bool bEternity /*= false*/ )
{
if( emBlowIndex < STATE_BLOW::BLOW_NONE || emBlowIndex >= STATE_BLOW::BLOW_MAX )
{
if( pParentSkillInfo )
g_Log.Log(LogType::_ERROR, L"[CDnActor::CmdAddStateEffect] SkillID:%d, STATE_BLOW:%d\r\n", pParentSkillInfo->iSkillID, emBlowIndex );
else
g_Log.Log(LogType::_ERROR, L"[CDnActor::CmdAddStateEffect] STATE_BLOW:%d\r\n", emBlowIndex);
return -1;
}
// [2011/03/18 semozz]
// »óÅÂÈ¿°ú °­Á¦ BeginÀ» À§ÇØ ÄÚµå ¼öÁ¤
int nBlowID = AddStateBlow( emBlowIndex, pParentSkillInfo, nDurationTime, szParam, bOnPlayerInit, bCheckCanBegin , bEternity );
DnBlowHandle hBlow = GetStateBlowFromID(nBlowID);
if (pParentSkillInfo && pParentSkillInfo->bItemPrefixSkill)
ForceBeginStateBlow(hBlow);
return nBlowID;
}
void CDnActor::CmdModifyStateEffect( int iBlowID, STATE_BLOW& StateBlowInfo )
{
DnBlowHandle hBlow = m_pStateBlow->GetStateBlowFromID( iBlowID );
if( hBlow )
{
char acBuffer[ 32 ];
CPacketCompressStream Stream( acBuffer, sizeof(acBuffer) );
Stream.Write( &iBlowID, sizeof(int) );
Stream.Write( &StateBlowInfo.fDurationTime, sizeof(float) );
Send( eActor::SC_CMDMODIFYSTATEEFFECT, &Stream );
}
}
DnBlowHandle CDnActor::GetStateBlowFromID( int nStateBlowID )
{
return m_pStateBlow->GetStateBlowFromID( nStateBlowID );
}
void CDnActor::CmdRemoveStateEffect( STATE_BLOW::emBLOW_INDEX emBlowIndex, bool bRemoveFromServerToo/* = true*/ )
{
DelStateBlow( emBlowIndex );
}
void CDnActor::CmdRemoveStateEffectImmediately( STATE_BLOW::emBLOW_INDEX emBlowIndex )
{
if( !m_pStateBlow )
return;
m_pStateBlow->RemoveImediatlyStateEffectByBlowIndex( emBlowIndex );
}
void CDnActor::CmdRemoveStateEffectFromID( int nID )
{
#ifdef PRE_FIX_REMOVE_STATE_EFFECT_PACKET
// ¿©±â´Ù ³Ö°ÔµÇ¸é ÆÛÆ÷¸Õ½º ºÎÇϰ¡ ÀÖÀ»°Í °°±â¶§¹®¿¡ ÀÏ´ÜÀº ³ÖÁö¾Ê½À´Ï´Ù.
// ¿Ø¸¸ÇѰæ¿ì¿¡¼­´Â ºí·Î¿ì ¾ÆÀ̵𸦠ãÀºÀÌÈÄ¿¡ ³Ö¾îÁֱ⶧¹®¿¡ ±»ÀÌ °Ë»çÇÒ ÇÊ¿ä´Â ¾ø¾îº¸ÀÔ´Ï´Ù.
// if( m_pStateBlow->IsExistStateBlowFromBlowID( nID ) == false )
// return;
#endif
m_pStateBlow->RemoveStateBlowFromID( nID );
SendRemoveStateEffectFromID(nID);
}
void CDnActor::ClearTriggerBuff()
{
for( int itr = 0; itr < (int)m_vTriggerBuff.size(); ++itr )
CmdRemoveStateEffectFromID( m_vTriggerBuff[itr] );
m_vTriggerBuff.clear();
}
void CDnActor::CmdWarp()
{
CmdWarp( *GetPosition(), EtVec3toVec2( *GetLookDir() ) );
}
void CDnActor::CmdWarp( EtVector3 &vPos, EtVector2 &vLook, CDNUserSession* pGameSession/*=NULL*/, bool bCheckPlayerFollowSummonedMonster/*=false*/ )
{
SetPosition( vPos );
SetPrevPosition( vPos );
Look( vLook, true );
if( abs( CDnWorld::GetInstance(GetRoom()).GetHeight( vPos ) - vPos.y ) > 5.f ) {
SetVelocityY( -3.0f );
SetResistanceY( -18.0f );
}
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &vPos, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( &vLook, sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
// pGameSession ÀÌ ÀÖ´Â °æ¿ì´Â ÇØ´ç ¼¼¼Ç¿¡°Ô¸¸ ÆÐŶ º¸³½´Ù.
if( pGameSession )
Send( pGameSession, eActor::SC_CMDWARP, GetUniqueID(), &Stream );
else
Send( eActor::SC_CMDWARP, &Stream );
}
bool CDnActor::CheckDamageAction( DnActorHandle hActor )
{
MAMovementBase *pMovement = GetMovement();
// ¸ð¾ç¼¼ ¼ÂÆÃ
if( ( IsAir() ) ||
( IsHit() && IsDown() && !IsStun() )
|| GetState() == ActorStateEnum::Down )
{
if( IsStandHit( m_HitParam.szActionName.c_str() ) )
{
m_HitParam.szActionName = "Hit_AirBounce";
m_HitParam.vVelocity.y = pMovement->GetLastVelocity()->y * 0.8f;
m_HitParam.vResistance.y = pMovement->GetResistance()->y;
if( m_HitParam.vVelocity.y > 0.f && m_HitParam.vResistance.y >= 0.f )
{
m_HitParam.vResistance.y = -18.f;
}
}
}
return true;
}
void CDnActor::CheckDamageVelocity( DnActorHandle hActor )
{
MAMovementBase *pMovement = GetMovement();
// ¹Ù¶óº¸±â ¼ÂÆÃ
EtVector2 vViewVec = EtVec3toVec2( m_HitParam.vViewVec );
EtVec2Normalize( &vViewVec, &vViewVec );
if( EtVec2LengthSq( &vViewVec ) > 0.f ) {
pMovement->Look( vViewVec );
}
// ¸¸¾à¿¡ ÀüÇô ¶ì¿öÁ®ÀÖ´Â »óŰ¡ ¾Æ´Ô¿¡µÎ Air ÀÎ Hit ¸ð¼ÇÀÌ µé¾î¿ÔÀ» °æ¿ì¸¦ ´ëºñÇØ¼­ ¿©±â¼­ ÀÓÀÇÀÇ ¼öÄ¡·Î ¶ç¾îÁÖ±â·Î ÇÏÀÚ
// (ex. Àü»çÀÇ ´©¿öÀִ³𠶧¸®±âÀÇ °æ¿ì ½ºÅÏÀ¸·Î ¸ÂÀ»°æ¿ì ¶°¾ßÇϴµ¥ y°ªÀ¸·Î °¡¼Óµµ¸¦ ÁÖÁö ¾Ê±â ¶§¹®¿¡ ¶°Àִ»óÅ·Π¿¡´Ï°¡ À¯ÁöµÇ´Â °æ¿ì°¡ ÀÖ´Ù. )
ActorStateEnum HitState = (ActorStateEnum)GetState( m_HitParam.szActionName.c_str() );
if( ( HitState & ActorStateEnum::Air ) && m_HitParam.vVelocity.y == 0.f ) {
m_HitParam.vVelocity.y = 3.f;
m_HitParam.vResistance.y = -18.f;
}
if( m_HitParam.vVelocity.y == 0.f && pMovement->GetVelocity() && pMovement->GetVelocity()->y != 0.f &&
( GetAddHeight() != 0.f ) || ( m_HitParam.szActionName.empty() && ( GetState() & ActorStateEnum::Air ) ) ) {
m_HitParam.vVelocity.y = pMovement->GetVelocity()->y;
m_HitParam.vResistance.y = pMovement->GetResistance()->y;
}
// Weight °¡ 0ÀÌ¸é ¾È¶ß´Â³ðÀÌ´Ù. ±×·¯³ª ½Ã±×³ÎÁß¿¡ Air »óÅ·ΠµÇÀְԵǸé À§ÀÇ ¿¹¿Ü󸮷çƾÀ» ¹«½ÃÇϰԵDZⶫ¿¡
// ¹Ù´Ú¿¡¼­ Air ·Î À¯ÁöµÇ´Â ³ðµéÀÌ »ý±æ¼ö°¡ ÀÖÀ¸´Ï 0ÀγðÀº »óŰ¡ Àý´ë Air ·Î µÇ¸é ¾ÈµÈ´Ù.
if( GetWeight() == 0.f )
{
// ¿Üµý¼¶(301) µ¢Äð Æ®·¦Ã³·³ ¹«°Ô°ª 0.0 À¸·Î ¹Ù²Ù´Â °æ¿ì ´ëÆ÷°°Àº °Å ¸Â¾Æ¼­
// °øÁß¿¡ ¶ß´Â ³Ë¹é ¾×¼ÇÀÌ ³ª¿Ã °æ¿ì ¶¥¿¡ ÂøÁöÇÏÁö ¸øÇÏ´Â ¹ö±×°¡ »ý±æ ¼ö ÀÖÀ¸¹Ç·Î ¼öÁ¤. (#12253)
if( IsAir( m_HitParam.szActionName.c_str() ) )
m_HitParam.szActionName.assign( GetCurrentAction() );
m_HitParam.vVelocity = EtVector3( 0.f, 0.f, 0.f );
m_HitParam.vResistance = EtVector3( 0.f, 0.f, 0.f );
}
pMovement->SetVelocity( m_HitParam.vVelocity );
pMovement->SetResistance( m_HitParam.vResistance );
}
int GetGaussianRandom( int nMin, int nMax, CMultiRoom *pRoom )
{
float f1 = ( _rand(pRoom) % 10001 ) / 10000.f;
float f2 = ( _rand(pRoom) % 10001 ) / 10000.f;
int nResult = (int)( ((nMin+nMax)/2.f) + ( ( sqrt(-2.f*log(f1)) * cos(2.f*3.1415926f*f2) ) * ((nMax-nMin)/6.f) ) );
if( nResult < nMin || nResult > nMax )
nResult = (nMin + nMax) / 2;
return nResult;
};
float GetGaussianRandom( float fMin, float fMax, CMultiRoom *pRoom, float fPrecision = 0.01f )
{
float f1 = ( _rand(pRoom) % 10001 ) / 10000.f;
float f2 = ( _rand(pRoom) % 10001 ) / 10000.f;
float fResult = ((fMin+fMax)/2.f) + ( ( sqrt(-2.f*log(f1)) * cos(2.f*3.1415926f*f2) ) * ((fMax-fMin)/6.f) );
if( fResult < fMin || fResult > fMax )
fResult = (fMin + fMax) / 2;
return fResult;
};
CDnState::ElementEnum CDnActor::CalcHitElementType( bool bUseSkillApplyWeaponElement, CDnState::ElementEnum eSkillElement, bool bUsingSkill )
{
// #33312 ƯÁ¤ »óȲ¿¡¼­ °­Á¦·Î ¼ÂÆÃÇÑ ¼Ó¼ºÀÌ ÀÖ´Ù¸é ÇØ´ç ¼Ó¼ºÀ¸·Î ó¸®.
if( false == m_vlForceSettedHitElement.empty() )
return static_cast<CDnState::ElementEnum>(m_vlForceSettedHitElement.back());
bool bProcessSkill = (m_hProcessSkill ? true : false);
ElementEnum eProcessSkillElement = CDnState::ElementEnum_Amount;
if( m_hProcessSkill )
eProcessSkillElement = m_hProcessSkill->GetElement();
// ¿ÜºÎ¿¡¼­ ½ºÅ³ »ç¿ë Á¤º¸¸¦ °®°í È£ÃâÇØÁÙ ¶§(½ºÅ³·Î ³ª°£ ÇÁ·ÎÁ§Å¸ÀÏ)
if( bUsingSkill )
{
bProcessSkill = bUsingSkill;
eProcessSkillElement = eSkillElement;
}
ElementEnum Type = CDnState::ElementEnum_Amount;
if( bProcessSkill )
{
if( eProcessSkillElement == CDnState::ElementEnum_Amount )
{
if( bUseSkillApplyWeaponElement )
{
if( IsPlayerActor() )
{
Type = ( CDnActor::GetWeapon() ) ? CDnActor::GetWeapon()->GetElementType() : CDnState::ElementEnum_Amount;
}
else if( IsMonsterActor() )
{
Type = static_cast<CDnMonsterActor*>(this)->GetElementType();
}
}
}
else
{
Type = eProcessSkillElement;
}
}
else
{
if( m_ActorType <= ActorTypeEnum::Reserved6 )
Type = ( CDnActor::GetWeapon() ) ? CDnActor::GetWeapon()->GetElementType() : CDnState::ElementEnum_Amount;
else
Type = static_cast<CDnMonsterActor*>(this)->GetElementType();
}
return Type;
}
// »óÅÂÈ¿°ú¿¡ °ü·ÃµÈ ºÎºÐÀº #pragma region À¸·Î Á¢Èû °¡´ÉÇÏ°Ô ¼³Á¤ÇÕ´Ï´Ù
// Visual Studio ¿É¼Ç¿¡¼­ ÆùÆ®¿É¼Ç¿¡ "Ãà¼Ò °¡´É ÅýºÆ®" ºÎºÐ¿¡ »öÁöÁ¤À» ÇØµÎ½Ã¸é °¡µ¶¼ºÀÌ ³ô¾ÆÁý´Ï´Ù.
float CDnActor::PreCalcDamage( CDnDamageBase *pHitter, SHitParam &HitParam, const float fDefenseRate/*=1.f*/, float fStateEffectAttackM /*= -1.0f */ )
{
float fResult = 0.f;
float fHitPer = HitParam.fDamage;
float fAttackPower = 0.0f;
int nDefense = 0;
float fDefenseWeight = 0.0f;
float fElementWeight = 1.f;
float fGausianResultProb = 1.f;
DnActorHandle hHitter = pHitter->GetActorHandle();
CDnState *pState = NULL;
CDnStateBlow *pHitterStateBlow = hHitter->GetStateBlow();
bool bCalcDamageFromStateEffect = ( fStateEffectAttackM != -1.0f );
if( bCalcDamageFromStateEffect == true )
{
if( hHitter )
pState = static_cast<CDnActorState *>(hHitter.GetPointer());
fAttackPower = fStateEffectAttackM;
nDefense = GetDefenseM();
}
else
{
if( hHitter && !HitParam.bFromProjectile )
{
pState = static_cast<CDnActorState *>(hHitter.GetPointer());
}
else
{
if( HitParam.hWeapon )
{
CDnProjectile *pHitterProjectile = static_cast<CDnProjectile*>( HitParam.hWeapon.GetPointer() );
if( pHitterProjectile )
{
pState = pHitterProjectile->GetShooterStateSnapshot().get();
#if defined(PRE_ADD_PROJECTILE_SE_INFO)
CDnStateBlow *pProjectileStateBlow = static_cast<CDnProjectile*>( HitParam.hWeapon.GetPointer() )->GetShooterStateBlow().get();
if( pProjectileStateBlow )
pHitterStateBlow = pProjectileStateBlow;
#endif
}
}
#if !defined(PRE_ADD_PROJECTILE_SE_INFO)
if (hHitter&& hHitter->IsApplyPrefixOffenceSkill())
pState = static_cast<CDnActorState *>(hHitter.GetPointer());
#endif
if( hHitter && pState == NULL )
pState = static_cast<CDnActorState *>(hHitter.GetPointer());
}
}
if( bCalcDamageFromStateEffect == false )
{
int nAttack[2] = { 0, };
switch( HitParam.cAttackType )
{
case 0: // ¹°¸®
{
nAttack[0] = pState->GetAttackPMin();
nAttack[1] = pState->GetAttackPMax();
#pragma region ++ [ ADD DAMAGE BY SELF ( BLOW_109 ) ] ++
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_109 ) )
{
int aiAdditionalPAttack[ 2 ] = { 0 };
DNVector(DnBlowHandle) vlhBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_109, vlhBlows );
int iNumBlow = (int)vlhBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
aiAdditionalPAttack[ 0 ] += int((float)GetAttackPMin() * vlhBlows.at(i)->GetFloatValue());
aiAdditionalPAttack[ 1 ] += int((float)GetAttackPMax() * vlhBlows.at(i)->GetFloatValue());
}
nAttack[ 0 ] += aiAdditionalPAttack[ 0 ];
nAttack[ 1 ] += aiAdditionalPAttack[ 1 ];
}
#pragma endregion
nDefense = GetDefenseP();
}
break;
case 1: // ¸¶¹ý
case 2: //rlkt_test
{
nAttack[0] = pState->GetAttackMMin();
nAttack[1] = pState->GetAttackMMax();
#pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_180 ) ] ++
if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_180) )
{
CDnActorState* pActorState = static_cast<CDnActorState *>(hHitter.GetPointer());
CDnState* pSkillState = pActorState ? pActorState->GetStateStep(1) : NULL;
if (pSkillState)
{
nAttack[0] += pSkillState->GetAttackPMin();
nAttack[1] += pSkillState->GetAttackPMax();
}
}
#pragma endregion
#pragma region ++ [ ADD DAMAGE BY SELF ( BLOW_110 ) ] ++
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_110 ) )
{
int aiAdditionalMAttack[ 2 ] = { 0 };
DNVector(DnBlowHandle) vlhBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_110, vlhBlows );
int iNumBlow = (int)vlhBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
aiAdditionalMAttack[ 0 ] += int((float)GetAttackMMin() * vlhBlows.at(i)->GetFloatValue());
aiAdditionalMAttack[ 1 ] += int((float)GetAttackMMax() * vlhBlows.at(i)->GetFloatValue());
}
nAttack[ 0 ] += aiAdditionalMAttack[ 0 ];
nAttack[ 1 ] += aiAdditionalMAttack[ 1 ];
}
#pragma endregion
nDefense = GetDefenseM();
}
break;
}
#pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_213 ) ] ++
if( pHitterStateBlow && m_pStateBlow->IsApplied(STATE_BLOW::BLOW_213) )
{
int nAddAttack[2] = { 0, };
int HitterAttackP[2] = {pState->GetAttackPMin(), pState->GetAttackPMax()};
DNVector(DnBlowHandle) vlhBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_213, vlhBlows );
int iNumBlow = (int)vlhBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
nAddAttack[ 0 ] += int((float)HitterAttackP[0] * vlhBlows.at(i)->GetFloatValue());
nAddAttack[ 1 ] += int((float)HitterAttackP[1] * vlhBlows.at(i)->GetFloatValue());
}
nAttack[ 0 ] += nAddAttack[ 0 ];
nAttack[ 1 ] += nAddAttack[ 1 ];
}
#pragma endregion
#pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_214 ) ] ++
if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_214) )
{
int nAddAttack[2] = { 0, };
int HitterAttackM[2] = {pState->GetAttackMMin(), pState->GetAttackMMax()};
DNVector(DnBlowHandle) vlhBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_214, vlhBlows );
int iNumBlow = (int)vlhBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
nAddAttack[ 0 ] += int((float)HitterAttackM[0] * vlhBlows.at(i)->GetFloatValue());
nAddAttack[ 1 ] += int((float)HitterAttackM[1] * vlhBlows.at(i)->GetFloatValue());
}
nAttack[ 0 ] += nAddAttack[ 0 ];
nAttack[ 1 ] += nAddAttack[ 1 ];
}
#pragma endregion
#pragma region ++ [ ADD DAMAGE BY HITTER ( BLOW_221 ) ] ++
if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_221))
{
int nAddAttack[2] = { 0, };
int HitterAttackValue[2] = {0, };
switch( HitParam.cAttackType )
{
case 0: //¹°¸® °ø°ÝÀ϶§.
HitterAttackValue[0] = pState->GetAttackPMin();
HitterAttackValue[1] = pState->GetAttackPMax();
break;
case 1: //¸¶¹ý °ø°ÝÀ϶§.
HitterAttackValue[0] = pState->GetAttackMMin();
HitterAttackValue[1] = pState->GetAttackMMax();
break;
}
DNVector(DnBlowHandle) vlhBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_221, vlhBlows );
int iNumBlow = (int)vlhBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
nAddAttack[ 0 ] += int((float)HitterAttackValue[0] * vlhBlows.at(i)->GetFloatValue());
nAddAttack[ 1 ] += int((float)HitterAttackValue[1] * vlhBlows.at(i)->GetFloatValue());
}
nAttack[ 0 ] += nAddAttack[ 0 ];
nAttack[ 1 ] += nAddAttack[ 1 ];
}
#pragma endregion
float fFinalDamageValue[4] =
{
CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue1 ),
CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue2 ),
CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue3 ),
CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FinalDamageValue4 ),
};
float fFValue = GetFinalDamageConstant();
float fFinalDamage1 = (float)( pState->GetFinalDamage() / fFValue ) * fFinalDamageValue[3];
float fFinalDamage2 = powf( (float)( pState->GetFinalDamage() / fFValue ), fFinalDamageValue[1] ) * fFinalDamageValue[2];
float fResultFinalDamage = min( max(fFinalDamage1, fFinalDamage2), fFinalDamageValue[2] );
// 184, 185¹ø °ø°ÝÀÚ ÆÄÀ̳Πµ¥¹ÌÁö ¹°°ø/¸¶°ø ±¸ºÐ Àû¿ë »óÅÂÈ¿°ú
float fResultAdditionalFinalDamage = 0.0f;
if( 0 == HitParam.cAttackType ) // ¹°¸® °ø°Ý
{
#pragma region ++ [ fResultAdditionalFinalDamage BY HITTER ( BLOW_184 ) ] ++
if( pHitterStateBlow && pHitterStateBlow->IsApplied( STATE_BLOW::BLOW_184 ) )
{
DNVector(DnBlowHandle) vlhFinalPDamageBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_184, vlhFinalPDamageBlows );
int iNumBlow = (int)vlhFinalPDamageBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
DnBlowHandle hBlow = vlhFinalPDamageBlows.at( i );
fResultAdditionalFinalDamage += hBlow->GetFloatValue();
}
}
#pragma endregion
}
else if (1 == HitParam.cAttackType || 2 == HitParam.cAttackType) // ¸¶¹ý °ø°Ý// rlkt_test
{
#pragma region ++ [ fResultAdditionalFinalDamage BY HITTER ( BLOW_185 ) ] ++
if( pHitterStateBlow && pHitterStateBlow->IsApplied( STATE_BLOW::BLOW_185 ) )
{
DNVector(DnBlowHandle) vlhFinalPDamageBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_185, vlhFinalPDamageBlows );
int iNumBlow = (int)vlhFinalPDamageBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
DnBlowHandle hBlow = vlhFinalPDamageBlows.at( i );
fResultAdditionalFinalDamage += hBlow->GetFloatValue();
}
}
#pragma endregion
}
float fGausianResult = (float)GetGaussianRandom( nAttack[0], nAttack[1], GetRoom() );
fGausianResultProb = fGausianResult / nAttack[1];
fAttackPower = fGausianResult * fHitPer;
float fDamageRatioBlowValue = 0.f;
#pragma region ++ [ fDamageRatioBlowValue BY HITTER ( BLOW_050 ) ] ++
if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_050))
{
DNVector(DnBlowHandle) vlhDamageRatioBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_050, vlhDamageRatioBlows );
int iNumBlow = (int)vlhDamageRatioBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
DnBlowHandle hBlow = vlhDamageRatioBlows.at( i );
fDamageRatioBlowValue += hBlow->GetFloatValue();
}
}
#pragma endregion
#if defined(PRE_FIX_65287)
//¹ß»çü¿¡ ÀÇÇØ¼­ FinalDamageRate°ªÀÌ ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì´Â ÀÌ ¼³Á¤°ªÀ» »ç¿ë Çϵµ·Ï ÇÑ´Ù.
//½ºÅ³ÀÌ ³¡³ª°í ³ª¸é 50¹ø »óÅÂÈ¿°ú°¡ »ç¶óÁø ´ÙÀ½À̶ó ÀÌ ¼³Á¤°ªÀ» »ç¿ë ÇØ¾ß ÇÔ.
float fShooterFinalDamageRate = 0.0f;
if (HitParam.bFromProjectile)
{
CDnProjectile* pProjectile = static_cast<CDnProjectile*>( HitParam.hWeapon.GetPointer() );
fShooterFinalDamageRate = pProjectile ? pProjectile->GetShooterFinalDamageRate() : 0.0f;
if (fShooterFinalDamageRate != 0.0f)
fDamageRatioBlowValue = fShooterFinalDamageRate;
}
#endif // PRE_FIX_65287
fAttackPower = fAttackPower * ( 1.f + fResultFinalDamage + fDamageRatioBlowValue + fResultAdditionalFinalDamage );
#pragma region ++ [ fAttackPower BY HITTER ( BLOW_074 ) ] ++
// 74¹ø »óÅÂÈ¿°ú. ¹«Á¶°Ç ÃÖ´ë µ¥¹ÌÁö·Î °è»êµÊ..
if( pHitterStateBlow && pHitterStateBlow->IsApplied( STATE_BLOW::BLOW_074 ) )
fAttackPower = (float)nAttack[1];
#pragma endregion
#pragma region ++ [ fAttackPower BY HITTER ( BLOW_209 ) ] ++
// ½Å±Ô ij¸¯ÅÍ(¾ÆÄ«µ¥¹Í °ü·Ã)
// ±âº» °ø°Ý·Â ºñÀ² Áõ°¡..(ÀϹݰø°ÝÀϰæ¿ì¸¸....) // ½ºÅ³À» »ç¿ëÁßÀÌÁö ¾Ê°í , ¹ß»çü°¡ ¾Æ´Ï°Å³ª , ¹ß»çü¶ó¸é ½ºÅ³»ç¿ë ¹ß»çü°¡ ¾Æ´Ò¶§
// ÀÏ´Ü ¾ÆÄ«µ¥¹Í Àΰæ¿ì¸¸ »ç¿ë°¡´É Çϵµ·Ï ¼³Á¤ÀÌ µÇ¾îÀÖ´Â »óÅÂÀÌ´Ù , ´Ù¸¥Å¬·¡½º¿¡ Àû¿ë ÇÒ ¶§´Â ¿¹¿Ü»óȲÀ» Á»´õ Å×½ºÆ® ÇØÁÖ¼¼¿ä
// < Ex> ½ºÅĽº·ù Ȱ¼ºÈ­ µÇ¾îÀÖ´Â »óÅ¿¡¼­ ¿¹¿Ü »óȲ È®ÀÎÇßÀ¸³ª ó¸®ÇÏÁö ¾ÊÀº »óÅ >
if (false == hHitter->IsProcessSkill() && (( HitParam.bFromProjectile && !HitParam.bFromProjectileSkill ) || !HitParam.bFromProjectile ) &&
!hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_121) && !hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_129) //ÇØÅ·½ºÅÙ½º·ù)
)
{
if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_209) )
{
DNVector(DnBlowHandle) vlBlowList;
float fAddtionalAttackPower = 0.f;
pHitterStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_209, vlBlowList);
for (int i=0 ; i< (int)vlBlowList.size(); ++i )
{
if(vlBlowList[i]->GetFloatValue() > 0.f)
{
fAddtionalAttackPower = fAttackPower * vlBlowList[i]->GetFloatValue();
break;
}
}
fAttackPower += fAddtionalAttackPower;
}
}
#pragma endregion
if( fAttackPower < 0.f )
fAttackPower = 0.f;
}
//rlkt_damage!
CDnSkill::SkillInfo *pDmgSkillInfo = NULL;
DnSkillHandle hDmgSkill;
if (HitParam.bFromProjectile && HitParam.hWeapon)
hDmgSkill = static_cast<CDnProjectile*>(HitParam.hWeapon.GetPointer())->GetParentSkill();
else
hDmgSkill = hHitter->GetProcessSkill();
bool bIsPVP = GetGameRoom()->bIsPvPRoom();
if (hDmgSkill)
{
pDmgSkillInfo = const_cast<CDnSkill::SkillInfo*>(hDmgSkill->GetInfo());
if (bIsPVP)
{
CDNGameDataManager::TPVPSkills* nSkillInfo = NULL;
nSkillInfo = g_pDataManager->GetPVPSkillPDamage(pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel);
if (nSkillInfo)
{
printf("hDmgSkill PVP OK atak: %.2f skill:%d lvl:%d\n", fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel);
fAttackPower = (float)(fAttackPower*(float)(nSkillInfo->fPDamage + 1.f));//test
printf("hDmgSkill PVP AFTER OK multi:%.4f atak: %.2f skill:%d lvl:%d\n", nSkillInfo->fPDamage, fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel);
}
} else {
printf("hDmgSkill OK atak: %.2f skill:%d lvl:%d\n", fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel);
TSkillLevelData *pData = g_pDataManager->GetSkillLevelData(pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel);
if (pData)
{
if (pData->nPhyDamage > 0.01f && fAttackPower > 0.001f)
fAttackPower = fAttackPower + (float)(fAttackPower*(float)(pData->nPhyDamage + 1.f));//test
}
printf("hDmgSkill AFTER OK atak: %.2f skill:%d lvl:%d\n", fAttackPower, pDmgSkillInfo->iSkillID, pDmgSkillInfo->iLevel);
}
}
#pragma region ++ [ nDefense BY SELF ( BLOW_101 ~ BLOW_108 ) ] ++
// [OBT] Ãß°¡ ½ºÅ³ È¿°ú ±¸Çö - ¹æ¾î·Â º¯°æ (#7839) ///////////////////////////////////////
STATE_BLOW::emBLOW_INDEX AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_NONE;
switch( HitParam.DistanceType )
{
case CDnDamageBase::DistanceTypeEnum::Melee:
{
if( 0 == HitParam.cAttackType )
{
// ¹°¸® ¹Ð¸® ¹æ¾î·Â Àý´ë º¯°æ : 101
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_101 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_101;
else
// ¹°¸® ¹Ð¸® ¹æ¾î·Â ºñÀ² º¯°æ
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_102 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_102;
}
else
if( 1 == HitParam.cAttackType || 2 == HitParam.cAttackType) //rlkt_test
{
// ¸¶¹ý ¹Ð¸® ¹æ¾î·Â Àý´ë º¯°æ
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_105 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_105;
else
// ¸¶¹ý ¹Ð¸® ¹æ¾î·Â ºñÀ² º¯°æ
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_106 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_106;
}
}
break;
case CDnDamageBase::DistanceTypeEnum::Range:
{
if( 0 == HitParam.cAttackType )
{
// ¹°¸® ·¹ÀÎÁö ¹æ¾î·Â Àý´ë º¯°æ : 101
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_103 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_103;
else
// ¹°¸® ·¹ÀÎÁö ¹æ¾î·Â ºñÀ² º¯°æ
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_104 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_104;
}
else
if( 1 == HitParam.cAttackType || 2 == HitParam.cAttackType) //rlkt_test
{
// ¸¶¹ý ·¹ÀÎÁö ¹æ¾î·Â Àý´ë º¯°æ
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_107 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_107;
else
// ¸¶¹ý ·¹ÀÎÁö ¹æ¾î·Â ºñÀ² º¯°æ
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_108 ) )
AppliedDefenseChangeBlowIndex = STATE_BLOW::BLOW_108;
}
}
break;
}
if( STATE_BLOW::BLOW_NONE != AppliedDefenseChangeBlowIndex )
{
switch( AppliedDefenseChangeBlowIndex )
{
// Àý´ë°ª º¯°æ
case STATE_BLOW::BLOW_101:
case STATE_BLOW::BLOW_103:
case STATE_BLOW::BLOW_105:
case STATE_BLOW::BLOW_107:
{
DNVector(DnBlowHandle) vlhDefenseAbChangeBlow;
GetStateBlow()->GetStateBlowFromBlowIndex( AppliedDefenseChangeBlowIndex, vlhDefenseAbChangeBlow );
int iNumBlow = (int)vlhDefenseAbChangeBlow.size();
for( int i = 0; i < iNumBlow; ++i )
{
DnBlowHandle hBlow = vlhDefenseAbChangeBlow.at( i );
int iValue = (int)hBlow->GetFloatValue();
nDefense += iValue;
}
}
break;
// ºñÀ² º¯°æ
case STATE_BLOW::BLOW_102:
case STATE_BLOW::BLOW_104:
case STATE_BLOW::BLOW_106:
case STATE_BLOW::BLOW_108:
{
DNVector(DnBlowHandle) vlhDefenseRtChangeBlow;
GetStateBlow()->GetStateBlowFromBlowIndex( AppliedDefenseChangeBlowIndex, vlhDefenseRtChangeBlow );
float fChangeRatio = 1.0f; // º¹¼ö°³°¡ ÀÖ´Â °æ¿ì¸¦ °¨¾ÈÇØ¼­ 100%¸¦ ³Ñ¾î°¡´Â ¼öÄ¡¸¸ ´©Àû½ÃÄÑÁØ´Ù.
int iNumBlow = (int)vlhDefenseRtChangeBlow.size();
for( int i = 0; i < iNumBlow; ++i )
{
DnBlowHandle hBlow = vlhDefenseRtChangeBlow.at( i );
fChangeRatio += (hBlow->GetFloatValue()-1.0f);
}
nDefense += int( (float)nDefense*fChangeRatio );
}
break;
}
}
#pragma endregion
float fDefensePower = 1.f;
#if defined(PRE_ADD_SKILLBUF_RENEW)
//¸ðµç °ø°Ý·Â °è»ê¿¡´Â ¹æ¾î·ÂÀÌ Àû¿ë µÈ´Ù.
fDefenseWeight = hHitter->GetDefenseConstant();
fDefensePower = nDefense / fDefenseWeight;
if( fDefensePower < 0.f ) fDefensePower = 0.f;
else if( fDefensePower > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax ) )
fDefensePower = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax );
fDefensePower = 1.f - fDefensePower;
//Å©¸®Æ¼ÄÃÀÎ °æ¿ì AttackPower¸¦ ¼³Á¤µÈ »ó¼ö°ªÀ» Àû¿ë½ÃŲ´Ù.
if (HitParam.HitType == CDnWeapon::Critical)
{
//#57510 PvP¿¡¼­ Å©¸®Æ¼Äà µ¥¹ÌÁö 1.5
float fCriticalIncValue = 1.0f;
if( GetGameRoom()->bIsPvPRoom() == true )
fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease_PVP );
else
fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease );
fAttackPower = fAttackPower * fCriticalIncValue;
}
#else // PRE_ADD_SKILLBUF_RENEW
if( HitParam.HitType == CDnWeapon::Critical )
{
fDefensePower = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease );
}
else
{
fDefenseWeight = hHitter->GetDefenseConstant();
fDefensePower = nDefense / fDefenseWeight;
if( fDefensePower < 0.f ) fDefensePower = 0.f;
else if( fDefensePower > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax ) )
fDefensePower = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DefenseMax );
fDefensePower = 1.f - fDefensePower;
}
#endif // PRE_ADD_SKILLBUF_RENEW
fResult = fAttackPower * fDefensePower;
#pragma region ++ [ fResult *= fChangeRatio BY SELF ( BLOW_134, BLOW_135 ) ] ++
// ¹°¸®/¸¶¹ý µ¥¹ÌÁö º¯°æ #12354, #12353 ///////////////////////////////////////////
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_134 ) && 0 == HitParam.cAttackType )
{
DNVector( DnBlowHandle ) vlhBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_134, vlhBlows );
float fChangeRatio = 1.0f; // º¹¼ö°³°¡ ÀÖ´Â °æ¿ì¸¦ °¨¾ÈÇØ¼­ 100%¸¦ ³Ñ¾î°¡´Â ¼öÄ¡¸¸ ´©Àû½ÃÄÑÁØ´Ù.
#ifdef PRE_ADD_BUFF_STATE_LIMIT
float fBuffStateRatioValue = 1.f;
#endif
for( int i = 0; i < (int)vlhBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhBlows.at( i );
float fValue = hBlow->GetFloatValue();
fChangeRatio += (fValue-1.0f);
#ifdef PRE_ADD_BUFF_STATE_LIMIT
if( hBlow->GetAddBlowStateType() == CDnActorState::AddBlowStateType::Equip_Buff_Level )
fBuffStateRatioValue += (fValue-1.0f);
#endif
}
#ifdef PRE_ADD_BUFF_STATE_LIMIT
float fMinLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Physical_Min );
float fMaxLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Physical_Max );
if(IsPlayerActor())
{
if( fChangeRatio < fMinLimit ) //#77817 À¯Àú°¡ ¹Þ´Â µ¥¹ÌÁö Àϰæ¿ì¿¡´Â ÃÑ µ¥¹ÌÁö °¨¼Ò·®À» ±âÁØÀ¸·Î ¼³Á¤.
fChangeRatio = fMinLimit;
}
else if(IsMonsterActor())
{
if( fBuffStateRatioValue > fMaxLimit )
fChangeRatio += -fBuffStateRatioValue + fMaxLimit;
}
#else
float fDamageChangeClampLowestRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DamageChangeClampLowestRatio );
if( fChangeRatio < fDamageChangeClampLowestRatio )
fChangeRatio = fDamageChangeClampLowestRatio;
#endif
if(fChangeRatio < 0)
fChangeRatio = 0.f;
fResult *= fChangeRatio;
}
else if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_135 ) && 1 == HitParam.cAttackType
|| IsAppliedThisStateBlow(STATE_BLOW::BLOW_135) && 2 == HitParam.cAttackType) //rlkt_test
{
DNVector( DnBlowHandle ) vlhBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_135, vlhBlows );
float fChangeRatio = 1.f;
#ifdef PRE_ADD_BUFF_STATE_LIMIT
float fBuffStateRatioValue = 1.f;
#endif
for( int i = 0; i < (int)vlhBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhBlows.at( i );
float fValue = hBlow->GetFloatValue();
fChangeRatio += (fValue-1.0f);
#ifdef PRE_ADD_BUFF_STATE_LIMIT
if( hBlow->GetAddBlowStateType() == CDnActorState::AddBlowStateType::Equip_Buff_Level )
fBuffStateRatioValue += (fValue-1.0f);
#endif
}
#ifdef PRE_ADD_BUFF_STATE_LIMIT
float fMinLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Magical_Min );
float fMaxLimit = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::Change_DamageTaken_Magical_Max );
if(IsPlayerActor())
{
if( fChangeRatio < fMinLimit ) //#77817 À¯Àú°¡ ¹Þ´Â µ¥¹ÌÁö Àϰæ¿ì¿¡´Â ÃÑ µ¥¹ÌÁö °¨¼Ò·®À» ±âÁØÀ¸·Î ¼³Á¤.
fChangeRatio = fMinLimit;
}
else if(IsMonsterActor())
{
if( fBuffStateRatioValue > fMaxLimit )
fChangeRatio += -fBuffStateRatioValue + fMaxLimit;
}
#else
float fDamageChangeClampLowestRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::DamageChangeClampLowestRatio );
if( fChangeRatio < fDamageChangeClampLowestRatio )
fChangeRatio = fDamageChangeClampLowestRatio;
#endif
if(fChangeRatio < 0)
fChangeRatio = 0.f;
fResult *= fChangeRatio;
}
#pragma endregion
#pragma region ++ [ fResult += fResult * fChangeRatio BY SELF ( BLOW_268 ) ] ++
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
if (IsAppliedThisStateBlow( STATE_BLOW::BLOW_268 ))
{
DNVector( DnBlowHandle ) vlhBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_268, vlhBlows );
float fChangeRatio = 0.0f;
for( int i = 0; i < (int)vlhBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhBlows.at( i );
if (hBlow && hBlow->IsEnd() == false)
{
CDnDamageChagneBlow* pDamageChageBlow = static_cast<CDnDamageChagneBlow*>(hBlow.GetPointer());
if (pDamageChageBlow && pDamageChageBlow->IsActivated() == true && pDamageChageBlow->GetLeftCoolTime() > 0.0f)
{
fChangeRatio += pDamageChageBlow->GetDamageRate();
}
}
}
if (fChangeRatio >= 0.0f)
{
fResult += fResult * fChangeRatio;
}
}
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
#pragma endregion
if( HitParam.HasElement != CDnActorState::ElementEnum_Amount )
{
fElementWeight = 1.f;
fElementWeight = ( ( 1.f + pState->GetElementAttack( HitParam.HasElement ) ) * ( 1.f - GetElementDefense( HitParam.HasElement ) ) );
#ifndef PRE_ADD_BUFF_STATE_LIMIT
fElementWeight = max( fElementWeight, CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::ElementMinRevision ) );
#endif
fResult *= fElementWeight;
}
// Å©¸®Æ¼Äà ÀúÇ× °è»êÇØ¼­ ´ë¹ÌÁö ±ï¾ÆÁØ´Ù. (ºê·¹ÀÌÅ· Æ÷ÀÎÆ®(½´ÆÛ¾Æ¸Ó ºê·¹ÀÌÅ©)°¡ ¼³Á¤µÇ¾î ÀÖÁö ¾Ê¾Æ¾ßÇÔ)
if( HitParam.HitType == CDnWeapon::Critical && false == HitParam.bBreakSuperAmmor)
{
float fCriticalValue = hHitter->GetCriticalConstant();
float fCriticalResistProb = GetCriticalResistance() / fCriticalValue;
if( fCriticalResistProb > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalResistanceMax ) )
fCriticalResistProb = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalResistanceMax );
if( _rand(GetRoom())%100 < (int)( fCriticalResistProb * 100.f ) ) {
#if defined(PRE_FIX_51491)
//Å©¸®Æ¼Ä÷Π¹ß»ýÇß´ø µ¥¹ÌÁö °¡»ê °ªÀ» ¾ø¾Ø´Ù..
//#57510 PvP¿¡¼­ Å©¸®Æ¼Äà µ¥¹ÌÁö 1.5
float fCriticalIncValue = 1.0f;
if( GetGameRoom()->bIsPvPRoom() == true )
fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease_PVP );
else
fCriticalIncValue = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalIncrease );
fResult = fResult / fCriticalIncValue;
#else
fResult *= CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalResistance );
#endif // PRE_FIX_51491
m_HitParam.HitType = CDnWeapon::CriticalRes;
}
}
#pragma region ++ [ pComboDamageLimitBlow BY SELF ( BLOW_242 ) ] ++
// #52332 ÀÏÁ¤ HIT¼ö ÀÌÈÄ¿¡ µ¥¹ÌÁö °¨¼ÒµÇ´Â È¿°ú ±¸Çö
// 242¹ø »óÅÂÈ¿°ú Àû¿ëµÇ¾î ÀÖ´Â °æ¿ì, Áö±Ý µ¥¹ÌÁö °è»ê¿¡ »ç¿ëµÈ ½ºÅ³/¾×Å͸¦ ÀÌ¿ëÇØ¼­ HitÄ«¿îÆ® Á¦ÇѰªÀ» °»½ÅÇÑ´Ù..
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_242 ) )
{
CDnSkill::SkillInfo *pSkillInfo = NULL;
DnSkillHandle hSkill;
if (HitParam.bFromProjectile && HitParam.hWeapon)
hSkill = static_cast<CDnProjectile*>( HitParam.hWeapon.GetPointer() )->GetParentSkill();
else
hSkill = hHitter->GetProcessSkill();
if (hSkill)
pSkillInfo = const_cast<CDnSkill::SkillInfo*>(hSkill->GetInfo());
DNVector(DnBlowHandle) vlBlows;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_242, vlBlows );
int nBlowCount = (int)vlBlows.size();
for (int i = 0; i < nBlowCount; ++i)
{
DnBlowHandle hBlow = vlBlows[i];
if (hBlow)
{
CDnComboDamageLimitBlow* pComboDamageLimitBlow = dynamic_cast<CDnComboDamageLimitBlow*>(hBlow.GetPointer());
if (pComboDamageLimitBlow)
pComboDamageLimitBlow->UpdateHitCount(pSkillInfo, HitParam);
}
}
}
#pragma endregion
// »óÅÂÈ¿°ú¿¡¼­ Ãß°¡ µ¥¹ÌÁö¸¦ ÁÙ ¼ö ÀÖÀ½.
fResult += m_pStateBlow->OnCalcDamage( fResult, m_HitParam );
#if defined(PRE_FIX_59680)
//¼­¸Õ ÆÛÆêÀÇ OnCalcDamage¸¦ È£Ãâ ÇÒ¶§ ÁÖÀÎ ¾×ÅÍÀÇ StateBlowÀÇ OnCalcDamageµµ È£ÃâÀÌ µÇ¾î¾ß ÁÖÀÎ ¾×ÅÍ µ¥¹ÌÁö Àû¿ëµÉ¶§ È¿°ú°¡ Á¤»ó Àû¿ëµÈ´Ù.
//Ŭ·¹¸¯ÀÇ È¦¸®½¯µåÀÇ °æ¿ì Àڽſ¡°Ô CDnAddStateOnHitBlow(178) »óÅÂÈ¿°ú°¡ Àû¿ëµÇ°í, ÀÌÈÄ¿¡ ¼­¸ÕÆÛÆêÀÌ ¼Òȯ µÉ°æ¿ì, ¼­¸ÕÆÛÆêÀº ÀÌ »óÅÂÈ¿°ú¸¦
//°¡Áö°í ÀÖÁö ¾Ê´Ù. ±×·¡¼­ ¼­¸ÕÆÛÆêÀ¸·Î µ¥¹ÌÁö°¡ Ŭ·¹¸¯¿¡ Àû¿ëµÇÁö¸¸ µ¥¹ÌÁö¿¡ ÀÇÇÑ HPÁõ°¡ »óÅÂÈ¿°ú´Â ¹ßµ¿µÇÁö ¾Ê´Â´Ù.
if (IsMonsterActor())
{
DnActorHandle hSummonerActor;
CDnStateBlow *pOwnerStateBlow = NULL;
CDnMonsterActor* pMonsterActor = dynamic_cast<CDnMonsterActor*>(m_MySmartPtr.GetPointer());
if (pMonsterActor && pMonsterActor->IsSummonedMonster() && pMonsterActor->IsPuppetSummonMonster())
hSummonerActor = pMonsterActor->GetSummonerPlayerActor();
if(hSummonerActor)
pOwnerStateBlow = hSummonerActor->GetStateBlow();
if (pOwnerStateBlow)
pOwnerStateBlow->OnCalcDamage(fResult, m_HitParam);
}
#endif // PRE_FIX_59680
// OnTargetHit½Ã µ¥¹ÌÁöÈ®ÀÎÀ» À§ÇØ [2011/02/15 semozz]
m_HitParam.nCalcDamage = (int)fResult;
hHitter->GetStateBlow()->OnTargetHit( GetMySmartPtr() );
#pragma region ++ [ fResult -= fAbsorbDamage BY SELF ( BLOW_243 ) ] ++
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_243 ) )
{
float fAbsorbDamage = 0.f;
int nAbsorbSP = 0;
DNVector( DnBlowHandle ) vlhManaShieldBlow;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_243, vlhManaShieldBlow );
for( DWORD n=0; n<vlhManaShieldBlow.size(); n++ )
{
CDnManaShieldBlow* pManShieldBlow = static_cast<CDnManaShieldBlow*>(vlhManaShieldBlow[n].GetPointer());
pManShieldBlow->CalcManaShield( fResult , fAbsorbDamage , nAbsorbSP );
}
if( nAbsorbSP > GetSP() )
{
fAbsorbDamage -= (fAbsorbDamage * (nAbsorbSP - GetSP()) / nAbsorbSP);
nAbsorbSP = GetSP();
}
if( fAbsorbDamage > fResult )
fAbsorbDamage = fResult;
fResult -= fAbsorbDamage;
SetSP( GetSP() -nAbsorbSP );
RequestHPMPDelta( ElementEnum::ElementEnum_Amount, -nAbsorbSP, UINT_MAX, true , true );
}
#pragma endregion
#pragma region ++ [ fResult = 0.0f; BY SELF ( BLOW_051 ) ] ++
#if defined(PRE_FIX_61382)
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_051))
{
DNVector(DnBlowHandle) vlhTransmitBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_051, vlhTransmitBlows );
int iNumBlow = (int)vlhTransmitBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
CDnTransmitDamageBlow* pTransmitDamageBlow = static_cast<CDnTransmitDamageBlow*>(vlhTransmitBlows[i].GetPointer());
//µ¥¹ÌÁö Àü´ÞµÇ´Â ¾×ÅÍÀÇ È÷Æ® ¿©ºÎ¸¦ È®ÀÎ ÇØ¼­ È÷Æ® °¡´ÉÀ϶§¸¸ µ¥¹ÌÁö Àü´ÞÇÑ´Ù.
DnActorHandle hTargetActor = pTransmitDamageBlow->GetActorHandle();
bool isEnableTransmitDamage = false;
if (hTargetActor)
{
if (hTargetActor->IsMonsterActor())
{
CDnMonsterActor* pMonsterActor = static_cast<CDnMonsterActor*>(hTargetActor.GetPointer());
isEnableTransmitDamage = pMonsterActor ? pMonsterActor->IsEnableNoDamage() == false : true;
}
else
isEnableTransmitDamage = true;
}
//µ¥¹ÌÁö Àü´Þ °¡´É ÇÏ¸é µ¥¹ÌÁö Àü´Þ ½ÃŲ´Ù.
if (isEnableTransmitDamage == true)
pTransmitDamageBlow->TransmitDamage( fResult , m_HitParam );
}
//µ¥¹ÌÁö Àü´Þ ÇÏ°í ³ª¼­ µ¥¹ÌÁö 0À¸·Î ¸®¼Â ½ÃÅ´..
fResult = 0.0f;
}
#endif // PRE_FIX_61382
#pragma endregion
#pragma region ++ [ STAGE DAMAGE LIMIT ] ++
#ifdef PRE_ADD_STAGE_DAMAGE_LIMIT
CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" );
if( pTask && pTask->GetStageDamageLimit()->fDamageLimit > 0.f )
{
if( hHitter )
{
CDnPlayerActor *pPlayerActor = NULL;
if( hHitter->IsPlayerActor() )
{
pPlayerActor = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
}
else if( hHitter->IsMonsterActor() )
{
CDnMonsterActor *pMonsterActor = static_cast<CDnMonsterActor*>(hHitter.GetPointer());
if( pMonsterActor && pMonsterActor->GetSummonerPlayerActor() )
pPlayerActor = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
}
if( pPlayerActor )
{
bool bNotifyInterface = false;
float fBaseAttackPower = 0.f;
if( HitParam.cAttackType == 0)
{
fBaseAttackPower = pState->GetAttackPMax() * fGausianResultProb * fHitPer;
bNotifyInterface = pPlayerActor->GetDamageLimitInfo()->bPhysicalAttack;
}
else if (HitParam.cAttackType == 1)
{
fBaseAttackPower = pState->GetAttackMMax() * fGausianResultProb * fHitPer;
bNotifyInterface = pPlayerActor->GetDamageLimitInfo()->bMagicalAttack;
}
else if (HitParam.cAttackType == 2) //rlkt_test
{
fBaseAttackPower = pState->GetAttackMMax() * fGausianResultProb * fHitPer;
bNotifyInterface = pPlayerActor->GetDamageLimitInfo()->bMagicalAttack;
}
if( fResult > (fBaseAttackPower * pTask->GetStageDamageLimit()->fDamageLimit) )
{
fResult = (fBaseAttackPower * pTask->GetStageDamageLimit()->fDamageLimit);
#ifdef PRE_ADD_STAGE_LIMIT_INTERFACE
if( bNotifyInterface == true )
HitParam.bStageLimit = true;
#endif
}
}
}
}
#endif
#pragma endregion
if( fResult < 0.f )
fResult = 0.f;
return fResult;
}
float CDnActor::CalcDamage( CDnDamageBase *pHitter, SHitParam &HitParam )
{
float fResult = PreCalcDamage( pHitter, HitParam );
#if defined( NODAMAGE ) || defined( STRESS_TEST )
return fResult;
#endif
#if defined(PRE_ADD_MISSION_COUPON)
INT64 nSaveHP = m_nHP;
SetHP((INT64)( m_nHP - fResult ));
m_nHP = (INT64)( nSaveHP - fResult );
#else
m_nHP = (INT64)( m_nHP - fResult );
#endif
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
if (IsAppliedThisStateBlow( STATE_BLOW::BLOW_268 ))
{
float fHpRate = 1.0f;
if (m_nMaxHP > 0)
fHpRate = (float)m_nHP / (float)m_nMaxHP;
DNVector( DnBlowHandle ) vlhBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_268, vlhBlows );
float fChangeRatio = 0.0f;
for( int i = 0; i < (int)vlhBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhBlows.at( i );
if (hBlow && hBlow->IsEnd() == false)
{
CDnDamageChagneBlow* pDamageChageBlow = static_cast<CDnDamageChagneBlow*>(hBlow.GetPointer());
if (pDamageChageBlow)
{
float fHPLimit = pDamageChageBlow->GetHpLimit();
if (fHpRate < fHPLimit &&
pDamageChageBlow->IsActivated() == false &&
pDamageChageBlow->GetLeftCoolTime() == 0.0f)
{
pDamageChageBlow->ApplyDamageChange();
}
}
}
}
}
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
return fResult;
}
void CDnActor::Die( DnActorHandle hHitter )
{
// ¸ó½ºÅÍ ¸·Å¸Ä£ °Íµµ CP Á¡¼ö ó¸®ÇؾßÇØ¼­ À̰÷¿¡¼­ ´ëü ½ÃÄÑ ÁØ´Ù.
if( hHitter && hHitter->IsMonsterActor() && IsMonsterActor() )
{
DnActorHandle hSummonMasterPlayerActor = static_cast<CDnMonsterActor*>(hHitter.GetPointer())->GetSummonerPlayerActor();
if( hSummonMasterPlayerActor )
hHitter = hSummonMasterPlayerActor;
}
#if defined( PRE_ADD_58761 )
// Á×¾úÀ»‹š ·Î±× ³²±â±â
CDNGameRoom *pRoom = GetGameRoom();
if( pRoom && CDnWorld::GetInstance(pRoom).GetMapSubType() == EWorldEnum::MapSubTypeNest)
{
if( hHitter && hHitter->IsMonsterActor() && IsPlayerActor() )
{
DnMonsterActorHandle hMonster = hHitter;
int nSkillID = 0;
if(hMonster->GetProcessSkill())
nSkillID = hMonster->GetProcessSkill()->GetClassID();
CDNUserSession *pSession = pRoom->GetUserSession( GetSessionID() );
if (pSession)
pRoom->NestDeathLog( pSession, hMonster->GetMonsterClassID(), nSkillID, pSession->GetUserJob(), pSession->GetLevel());
else
_DANGER_POINT();
}
}
#endif
#if defined(PRE_FIX_44884)
bool bStateBlowProcessed = true;
if (IsDie())
bStateBlowProcessed = m_pStateBlow->OnDie( hHitter );
if (IsDie())
OnDie(hHitter);
#else
OnDie( hHitter );
bool bStateBlowProcessed = m_pStateBlow->OnDie( hHitter );
#endif // PRE_FIX_44884
bool bCheckDie = false;
if( false == bStateBlowProcessed )
{
if( IsStandHit( m_HitParam.szActionName.c_str() ) )
m_HitParam.szActionName = "Die", bCheckDie = true;
if( IsStun( m_HitParam.szActionName.c_str() ) && !IsAir( m_HitParam.szActionName.c_str() ) )
m_HitParam.szActionName = "Die", bCheckDie = true;
if( !bCheckDie ) {
// Ȧµå ½ºÅ³ ¶§¹®¿¡ Stay Á¶°Çµµ Æ÷ÇÔ.. ¾È±×·¯¸é Die ¾×¼ÇÀÌ ¹ßµ¿ÀÌ ¾ÈµÇ¾î¼­ hold ¸Â°í Çѹ濡 Á×À» °æ¿ì Ŭ¶ó¿¡¼­ "stand" ¾×¼ÇÀ¸·Î
// OnDamage ÆÐŶÀ» ¹Þ¾Æ ¼± ä·Î Á×°Ô µÊ..
if( IsStay( m_HitParam.szActionName.c_str() ) )
m_HitParam.szActionName = "Die", bCheckDie = true;
if( IsAir( m_HitParam.szActionName.c_str() ) ) {
if( IsExistAction( "Die_Air" ) ) m_HitParam.szActionName = "Die_Air", bCheckDie = true;
}
if( IsDown( m_HitParam.szActionName.c_str() ) ) {
if( IsExistAction( "Die_Down" ) ) m_HitParam.szActionName = "Die_Down", bCheckDie = true;
}
if( !bCheckDie ) m_HitParam.szActionName = "Die";
}
}
else
{
// ¸ó½ºÅͰ¡ Á×À¸¸é¼­ »ç¿ëÇÏ´Â ½ºÅ³ ¶§¹®¿¡ Die ¾×¼ÇÀÌ ¾Æ´Ï¶ó ±×³É stand ½ÃÅ´. (#16331)
m_HitParam.szActionName = "Stand";
}
m_bEnableNormalSuperAmmor = false;
if (hHitter)
{
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())
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(pCannonMonster->GetMasterPlayerActor().GetPointer());
if( pPlayerActor )
pPlayerActor->OnKillMonster(GetMySmartPtr());
}
}
}
else if (hHitter->IsPlayerActor())
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
if( pPlayerActor )
pPlayerActor->OnKillMonster(GetMySmartPtr());
}
}
// °¢ ÆÄƼ¿øµé¿¡°Ô ¸ó½ºÅͰ¡ Á×¾ú´Ù°í ó¸®ÇØÁÜ.
// NOTE: µ¶°É¸®°í Á×´Â ¼ø°£¿¡ Ŭ¶óÀÌ¾ðÆ®¸¦ ²ô´Ï±ñ ¼­¹ö°¡ Á״´Ù. pTask°¡ ¾²·¹±â°ªÀ¸·Î ³ª¿È..
CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(GetRoom()).GetTask( "GameTask" );
if ( pTask )
{
for( DWORD i=0; i< pTask->GetRoom()->GetUserCount(); i++ )
{
CDNGameRoom::PartyStruct *pStruct = pTask->GetRoom()->GetPartyData(i);
if (!pStruct)
continue;
if( !IsMonsterActor() )
continue;
CDnMonsterActor* pMonster = static_cast<CDnMonsterActor*>(this);
if( pStruct->pSession && pStruct->pSession->GetQuest() )
pStruct->pSession->GetQuest()->OnDieMonster(pMonster->GetMonsterClassID());
}
}
}
void CDnActor::OnDamage( CDnDamageBase *pHitter, SHitParam &HitParam, HitStruct *pHitStruct )
{
//¿©±â µé¾î ¿Â ½ÃÁ¡Àº IsHitable¿¡¼­ üũ µÇ°í µé¾î ¿ÔÀ½.
//µ¥¹ÌÁö ó¸® Àü¿¡ »óÅÂÈ¿°ú¸¦ Á¦°Å..
RemoveStateEffectByHitSignal(pHitStruct);
DnActorHandle hHitterActor = pHitter->GetActorHandle();
if( hHitterActor && hHitterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_183) == false )
{
#if defined(PRE_ADD_PREFIX_SYSTE_RENEW)
hHitterActor->ApplyPrefixOffenceSkillToTarget_New(GetActorHandle());
#else
hHitterActor->ApplyPrefixOffenceSkillToTarget(GetActorHandle());
#endif
}
m_HitParam = HitParam;
DnActorHandle hHitter = pHitter->GetActorHandle();
CDnStateBlow *pHitterStateBlow = hHitter->GetStateBlow();
#if defined(PRE_ADD_PROJECTILE_SE_INFO)
if( hHitter && HitParam.bFromProjectile && HitParam.hWeapon )
{
CDnStateBlow *pProjectileStateBlow = static_cast<CDnProjectile*>( HitParam.hWeapon.GetPointer() )->GetShooterStateBlow().get();
if( pProjectileStateBlow )
pHitterStateBlow = pProjectileStateBlow;
}
#endif
#ifdef PRE_ADD_EXPORT_DPS_INFORMATION
if( CDnDPSReporter::IsActive() && hHitter && hHitter->IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>( hHitter.GetPointer());
if(CDnDPSReporter::GetInstance().IsEnabledUser(pPlayerActor->GetCharacterDBID()))
CDnDPSReporter::GetInstance().StartReport();
}
float fDPS_DAMAGE = 0;
#endif
CDnWeapon::HitTypeEnum HitType = CDnWeapon::Normal;
// ¸íÁß·ü °è»ê
SetDamageRemainTime( hHitter->GetUniqueID(), HitParam.RemainTime , hHitter->GetCurrentActionIndex() );
SetLastDamageHitUniqueID( hHitter->GetUniqueID(), HitParam.iUniqueID );
m_fStiffDelta = 0.f;
if( m_fDownDelta > 0.f ) m_fLastDownRatio *= 0.5f;
m_fDownDelta = 0.f;
bool bAir = false;
if( IsAir() && IsHit() ) bAir = true;
bool bHitSuccess = CheckDamageAction( hHitter );
// ¹°¸®°ø°ÝÀ¸·Î ¸¶¹ý°ø°ÝÀ¸·Î º¯°æ.. [2011/02/21 semozz]
if (hHitter && hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_180))
{
if (0 == m_HitParam.cAttackType)
{
//BLOW_180ÀÌ °ø°ÝÀÚ¿¡ Àû¿ëµÇ¾îÀÖÀ¸¸é ¸ðµç ¹°¸® °ø°ÝÀ» ¸¶¹ý °ø°ÝÀ¸·Î º¯°æÇÑ´Ù.
m_HitParam.cAttackType = 1;
}
}
if( pHitterStateBlow && pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_182) )
{
//¼Ó¼º °ø°Ý ¼³Á¤ÀÌ µÇÀú ÀÖÁö ¾ÊÀ»¶§¸¸ º¯°æ??
if( m_HitParam.HasElement == CDnActorState::ElementEnum_Amount )
{
DNVector(DnBlowHandle) vlChangeElementBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_182, vlChangeElementBlows );
CDnState::ElementEnum eElementType = CDnState::ElementEnum_Amount;
if (!vlChangeElementBlows.empty())
{
eElementType = CDnState::ElementEnum(int(vlChangeElementBlows.at(0)->GetFloatValue()));
}
if (eElementType != CDnActorState::ElementEnum_Amount)
m_HitParam.HasElement = eElementType;
}
}
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_149 ) == false ) // ¾óÀ½°¨¿Á »óÅÂÈ¿°ú °É·ÈÀ» ¶§´Â OnDefenseAttack À» ¹Þ¾Æ¼­ ó¸®ÇÏ´Â ÆÐ¸µ, ºí·Ï »óÅÂÈ¿°ú 󸮸¦ ÇÏÁö ¾ÊÀ½.
{
CDnState* pAttackerState = NULL;
if( hHitter && !HitParam.bFromProjectile )
{
pAttackerState = static_cast<CDnActorState *>(hHitter.GetPointer());
}
else
{
if( HitParam.hWeapon )
pAttackerState = static_cast<CDnProjectile*>( HitParam.hWeapon.GetPointer() )->GetShooterStateSnapshot().get();
#if !defined(PRE_ADD_PROJECTILE_SE_INFO)
if (hHitter&& hHitter->IsApplyPrefixOffenceSkill())
pAttackerState = static_cast<CDnActorState *>(hHitter.GetPointer());
#endif
if( hHitter && pAttackerState == NULL )
pAttackerState = static_cast<CDnActorState *>(hHitter.GetPointer());
}
#ifdef PRE_ADD_MONSTER_CATCH
bool bCheckOnDefense = true;
if( IsPlayerActor() )
{
// ¸ó½ºÅÍ¿¡ ÀâÈù »óÅ¿¡¼­´Â ½ºÅ³ °ü·Ã ³»¿ëµé ¹«½Ã.
if( static_cast<CDnPlayerActor*>(this)->IsCatchedByMonster() || m_HitParam.bReleaseCatchActor )
bCheckOnDefense = false;
}
// ¶§¸° ³à¼®ÀÎ hActor ¿¡¼­ state ¸¦ °¡Á®´Ù »ç¿ëÇÏ¸é ½ºÅ³ ¾×¼ÇÀÌ ÀÌ¹Ì ³¡³­ »óÅÂÀÏ ¼ö Àֱ⠶§¹®¿¡ Æò¼Ò °ø°Ý·Â/¹æ¾î·ÂÀÏ ¼ö ÀÖÀ¸¹Ç·Î
// ¹ß»çü¿¡ ½Ç¾î¼­ º¸³»´Â °Í±îÁö °í·ÁµÈ pAttackerState ¸¦ »ç¿ëÇÑ´Ù.
// pAttackerState ¸¦ ÇÔ¼ö ³»ºÎ¿¡¼­ »ç¿ëÇÒ °æ¿ì, ¹Ýµå½Ã ³»ºÎ¿¡¼­ NULL Æ÷ÀÎÅÍ Ã¼Å©¸¦ ÇØ¾ß ÇÔ.
if( bCheckOnDefense )
bHitSuccess = m_pStateBlow->OnDefenseAttack( hHitter, pAttackerState, m_HitParam, bHitSuccess );
#else
bHitSuccess = m_pStateBlow->OnDefenseAttack( hHitter, pAttackerState, m_HitParam, bHitSuccess );
#endif
}
// µ¥¹ÌÁö ¹Ý»ç »óÅÂÈ¿°ú¿¡ ÀÇÇØ hitter °¡ ¸ó½ºÅÍÀÎ °æ¿ì Die ó¸®µÇ¾î °´Ã¼°¡ destroy µÉ ¼ö ÀÖ´Ù.
// Ç÷¹À̾îÀÎ °æ¿ì °´Ã¼°¡ ÆÄ±«µÇÁö ¾ÊÀ¸¹Ç·Î CheckDamageVelocity() ÇÔ¼ö°¡ È£ÃâµÇ¾î ÀûÀýÇϰÔ
// Çǰݾ׼ÇÀÌ ³ª¿Ã ¼ö ÀÖµµ·Ï ó¸®ÇÑ´Ù.#23559
// ¸ó½ºÅÍÇÑÅ× ¸ÂÀÚ¸¶ÀÚ µ¥¹ÌÁö ¹Ý»ç·Î ¸ó½ºÅͰ¡ Á×À¸¸é ¼Óµµ °ªÀÌ Á¤È®È÷ ¼ÂÆÃ ¾ÈµÇ¾î µ¿ÀÏÇÑ ¹®Á¦°¡ ³ª¿Ã ¼ö ÀÖÁö¸¸
// ¿ì¼± Ç÷¹À̾îÂʸ¸ ó¸®ÇصдÙ.
if( hHitter->IsMonsterActor() )
{
if( !hHitter || hHitter->IsDie() )
return;
}
bool isBreakSuperArmorBlow = false;
if( bHitSuccess ) {
// °æÁ÷ ½Ã°£ °è»ê
float fStiffResult = 0.f;
if( GetStiffResistance() > 0 ) fStiffResult = ( hHitter->GetStiff() * m_HitParam.fStiffProb ) / GetStiffResistance();
fStiffResult *= CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffRevision );
if( fStiffResult < 0.001f )
fStiffResult = 0.001f; // CPacketCompressStream::FLOAT_SHORT À» »ç¿ëÇϱ⶧¹®¿¡ ¹üÀ§¸¦ ¹þ¾î³ª´Â ÀÛÀº °ªÀÌ µÇÁö¾Êµµ·Ï ¼³Á¤ÇÑ´Ù.
if( fStiffResult <= 0.f )
{
fStiffResult = 0.05f;
}
else
{
float fStiffMax = 0.f;
#if defined PRE_ADD_PVP_STIFF_MAX
if( GetGameRoom()->bIsPvPRoom() == true )
fStiffMax = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax_PVP );
else
fStiffMax = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax );
#else
fStiffMax = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax );
#endif
if( fStiffResult > fStiffMax )
fStiffResult = fStiffMax;
}
m_fStiffDelta = s_fMaxStiffTime * fStiffResult;
// ´Ù¿îµô·¹ÀÌ ·£´ý°ª ¼³Á¤
if( !IsDown() ) {
m_fLastDownRatio = 1.f;
}
float fTemp = ( 3.f * ( 1.f - GetDownDelayProb() ) ) * m_fLastDownRatio;
int nTemp = (int)( fTemp * DOWN_DELAY_RANDOM_RANGE * 100.f );
if( nTemp == 0 ) m_fDownDelta = fTemp;
else m_fDownDelta = fTemp - DOWN_DELAY_RANDOM_RANGE + ( _rand(GetRoom())%( nTemp * 2 ) / 100.f );
if( m_fDownDelta >= 3.f ) m_fDownDelta = 3.f;
if( m_fDownDelta <= 0.01f ) m_fDownDelta = 0.01f;
// Å©¸®Æ¼Äà °è»ê
float fCritical = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalValue );
float fCriticalValue = hHitter->GetLevelWeightValue() * fCritical;
float fCriticalProb = 0.f;
if( fCriticalValue > 0.f )
fCriticalProb = hHitter->GetCritical() / fCriticalValue;
else
g_Log.Log(LogType::_SESSIONCRASH, L"fCriticalValue = 0.f ClassID=%d\n", hHitter->GetClassID() );
float fAddCiriticalValue = 0.0f;
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_250))
{
DNVector( DnBlowHandle ) vlhCriticalIncBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_250, vlhCriticalIncBlows );
int nListCount = (int)vlhCriticalIncBlows.size();
for (int i = 0; i < nListCount; ++i)
{
DnBlowHandle hBlow = vlhCriticalIncBlows[i];
if (hBlow)
fAddCiriticalValue += hBlow->GetFloatValue();
}
}
if( pHitterStateBlow )
{
if( pHitterStateBlow->IsApplied(STATE_BLOW::BLOW_251) )
{
DNVector(DnBlowHandle) vlhCriticalIncBlows;
pHitterStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_251, vlhCriticalIncBlows );
int nListCount = (int)vlhCriticalIncBlows.size();
for (int i = 0; i < nListCount; ++i)
{
DnBlowHandle hBlow = vlhCriticalIncBlows[i];
if (hBlow)
fAddCiriticalValue += hBlow->GetFloatValue();
}
}
}
fCriticalProb += fAddCiriticalValue;
if( fCriticalProb > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax ) )
fCriticalProb = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax );
bool bBreakSuperAmmor = false;
//½´ÆÛ¾Æ¸Óºê·¹ÀÌÅ© »óÅÂÈ¿°ú °É·Á ÀÖ°í, È®·üÀÌ ¸ÂÀ¸¸é Å©¸®Æ¼Ä÷Πº¯°æ.( ¸é¿ªÀÌ ¾Æ´Ï¾î¾ß ÇÑ´Ù..)
if (hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_162) && !IsImmuned(STATE_BLOW::BLOW_162))
{
DNVector( DnBlowHandle ) vlhBreakSuperArmors;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_162, vlhBreakSuperArmors );
float fRate = 0.0f;
DnSkillHandle hSkill;
if (!vlhBreakSuperArmors.empty())
{
const CDnSkill::SkillInfo* pSkillInfo = vlhBreakSuperArmors.at(0)->GetParentSkillInfo();
if (pSkillInfo)
hSkill = hHitter->FindSkill(pSkillInfo->iSkillID);
if (hSkill && CDnSkill::UsingResult::Success == hSkill->CanExecute())
{
fRate = vlhBreakSuperArmors.at(0)->GetFloatValue();
}
}
bBreakSuperAmmor = rand() % 10000 <= (fRate * 10000.0f);
if (bBreakSuperAmmor)
{
fCriticalProb = 1.0f;
m_HitParam.bBreakSuperAmmor = true;
if (hSkill && CDnSkill::Passive == hSkill->GetSkillType())
{
// PassiveSkill ÄðŸÀÓ Ç¥½Ã¸¦ À§ÇÑ ÆÐŶ Àü¼Û...
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
DWORD dwUniqueID = hHitter ? hHitter->GetUniqueID() : -1;
int nSkillID = hSkill->GetClassID();
Stream.Write( &dwUniqueID, sizeof(dwUniqueID) );
Stream.Write( &nSkillID, sizeof(nSkillID));
hHitter->Send(eActor::SC_PASSIVESKILL_COOLTIME, &Stream);
//½ÇÁ¦ ÄðŸÀÓ ½ÃÀÛ.
hSkill->OnBeginCoolTime();
}
//½´ÆÛ¾Æ¸Óºê·¹ÀÌÅ© ÀÌÆåÆ® Ç¥½Ã ÆÐŶ Àü¼Û..
{
//ÀÌÆåÆ® Ç¥½Ã¿ë ÆÐŶÀ» Àü¼Û..
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
DWORD dwUniqueID = hHitter ? hHitter->GetUniqueID() : -1;
STATE_BLOW::emBLOW_INDEX blowIndex = STATE_BLOW::BLOW_162;
bool bShowEffect = true;
Stream.Write( &dwUniqueID, sizeof(dwUniqueID) );
Stream.Write( &blowIndex, sizeof(blowIndex));
Stream.Write( &bShowEffect, sizeof(bShowEffect));
hHitter->Send(eActor::SC_SHOW_STATE_EFFECT, &Stream);
}
}
}
//162¹ø »óÅÂÈ¿°ú¿¡ ÀÇÇØ ½´ÆÛ ¾Æ¸Ó°¡ ±úÁ³´ÂÁö È®ÀÎ
if (bBreakSuperAmmor)
isBreakSuperArmorBlow = true;
//79¹ø »óÅÂÈ¿°ú°¡ °É·Á ÀÖÀ¸¸é ¹«Á¶°Ç ½´ÆÛ ¾Æ¸Ó ±úÁü..
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_079))
isBreakSuperArmorBlow = true;
EtVector3 vVelocity = m_HitParam.vVelocity;
// ½ºÅÏ °è»ê
int nStunProb = (int)( CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunMax ) * 100.f );
if( GetStunResistance() > 0 ) {
float fLocalTemp = powf( (float)( hHitter->GetStun() / GetStunResistance() ), CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunRevisioin ) ) * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunRevision2 );
if( fLocalTemp > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunMax ) )
fLocalTemp = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunMax );
nStunProb = (int)( fLocalTemp * 100.f );
}
bool isAppliedForceSturn = false;
// Ÿ°ÝÀÚ°¡ °­Á¦ ½ºÅÏ »óÅÂÈ¿°ú°¡ ÀÖ´Â »óȲÀ̶ó¸é ÇØ´ç »óÅÂÈ¿°ú ¼öÄ¡·Î ÀÖ´Â È®·ü °ª (0.0~1.0)À» ´õÇÑ´Ù.
if( hHitter && hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_133 ) )
{
DNVector( DnBlowHandle ) vlhStunBlow;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_133, vlhStunBlow );
for( int i = 0; i < (int)vlhStunBlow.size(); ++i )
nStunProb += int(vlhStunBlow.at(i)->GetFloatValue() * 100.0f);
isAppliedForceSturn = true;
}
// if( hHitter->GetStun() > 0 ) nStunProb = (int)( ( ( 1.f - ( hHitter->GetStun() / GetStunResistance() ) ) * 100 ) * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunRevisioin ) );
nStunProb = (int)( nStunProb * m_HitParam.fDamage );
if( _rand(GetRoom())%100 < nStunProb ) {
if( IsStandHit( m_HitParam.szActionName.c_str() ) ) {
m_HitParam.szActionName = "Stun";
}
else if( IsAir( m_HitParam.szActionName.c_str() ) ) {
if( strstr( m_HitParam.szActionName.c_str(), "High" ) == NULL ) {
m_HitParam.szActionName = "Hit_AirUp";
}
vVelocity = m_HitParam.vVelocity * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StunVelocityRevision ) * ( 1.f + pHitStruct->fStunVelocityRevision );
}
else if( IsDown( m_HitParam.szActionName.c_str() ) ) {
m_HitParam.szActionName = "Hit_AirUp";
}
//½ºÅÏÀÌ µÇ´õ¶óµµ Å©¸®Æ¼ÄÃÀÌ ¹ß»ýµÇ¾î¾ß ÇÔ.
//±×·¡¼­ STATE_BLOW::BLOW_133 »óÅÂÈ¿°ú°¡ ´Ù¸é StunÀ¸·Î ¹«Á¶°Ç ¼³Á¤Çϰí
//STATE_BLOW::BLOW_133»óÅÂÈ¿°ú°¡ ÀÖ°í, hitTypeÀÌ ¼³Á¤µÇ¾î ÀÖÀ¸¸é hitTypeÀ» SturnÀ¸·Î ¹Ù²ÙÁö ¸»°í À¯Áö
if (!isAppliedForceSturn)
HitType = CDnWeapon::Stun;
else if (HitType == CDnWeapon::Normal)
HitType = CDnWeapon::Stun;
m_fStiffDelta = 0.f;
}
if ( m_HitParam.HasElement == CDnActorState::Fire && IsAppliedThisStateBlow(STATE_BLOW::BLOW_042)) // È÷Æ® ¼Ó¼ºÀÌ È­¿°À̸ç , È­»ó¿¡ °É·ÁÀÖ´Â »óÅÂÀ̶ó¸é
{
if (hHitter && hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_222)) // ¶§¸°³à¼®ÀÌ È­¿°¼Ó¼º Å©¸® »óÅÂÈ¿°ú¸¦ µé°íÀÖ´Ù¸é.
{
DNVector( DnBlowHandle ) vBurnCriticalBlows;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_222, vBurnCriticalBlows );
if (!vBurnCriticalBlows.empty())
{
if(vBurnCriticalBlows.at(0))
{
CDnBurnCriticalBlow *pBurnCriticalBlow = static_cast<CDnBurnCriticalBlow*>(vBurnCriticalBlows.at(0).GetPointer());
if(pBurnCriticalBlow->GetMultiplyRatio() > 0)
fCriticalProb = fCriticalProb + ( fCriticalProb * ( (float)pBurnCriticalBlow->GetMultiplyRatio() * 1/100 ) );
if(pBurnCriticalBlow->GetAddValueRatio() > 0)
fCriticalProb = fCriticalProb + (pBurnCriticalBlow->GetAddValueRatio() / fCriticalValue);
if( fCriticalProb > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax ) )
fCriticalProb = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalMax );
}
}
}
}
//½ºÅÏÈ®·ü °è»ê ÀÌÈÄ Å©¸®Æ¼Äà Ȯ·ü °è»êÀ¸·Î º¯°æ.
if( _rand(GetRoom())%100 < (int)( fCriticalProb * 100.f ) ) {
vVelocity = m_HitParam.vVelocity * CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CriticalVelocityRevision ) * ( 1.f + pHitStruct->fCriticalVelocityRevision );
HitType = CDnWeapon::Critical;
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
//Å©¸®Æ¼ÄÃÀÎ °æ¿ì ÅëÇÕ·¹º§½ºÅ³ÀÇ »óÅÂÈ¿°ú
if (hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_267))
{
DNVector( DnBlowHandle ) vlhBlows;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_267, vlhBlows );
int nCount = (int)vlhBlows.size();
for( int i = 0; i < (int)vlhBlows.size(); ++i )
{
CDnAddCriticalRateBlow* pBlow = static_cast<CDnAddCriticalRateBlow*>(vlhBlows[i].GetPointer());
if (pBlow && pBlow->IsActivated() == false && pBlow->GetLeftCoolTime() == 0.0f)
pBlow->ApplyCriticalIncBlow();
}
}
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
//rlkt_mastery!
//printf("%s, OnCriticalHit Passive %d \n ", __FUNCTION__, 7529);
//mastery 1 dark avenger
/* CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
boost::shared_ptr<IDnObserverNotifyEvent> pEvent(IDnObserverNotifyEvent::Create(EVENT_ONCRITICALHIT));
pEvent->SetSkillID(hHitter->GetProcessSkill()->GetClassID());
pPlayer->Notify(pEvent);*/
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
if (pPlayer && pPlayer->IsPlayerActor()) {
printf("%s Notify EVENT_ONCRITICALHIT\n",__FUNCTION__);
boost::shared_ptr<IDnObserverNotifyEvent> pEvent(IDnObserverNotifyEvent::Create(EVENT_ONCRITICALHIT));
pEvent->SetSkillID(pPlayer->GetLastUsedSkill());
pPlayer->Notify(pEvent);
//boost::shared_ptr<IDnObserverNotifyEvent> pEvent(IDnObserverNotifyEvent::Create(EVENT_ONCRITICALHIT));
////pEvent->SetSkillID(pPlayer->GetLastUsedSkill());
//pPlayer->Notify(pEvent);
}
/* CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
shared_ptr<IDnObserverNotifyEvent> pNotifyEvent(new CDnOnCriticalHitMessage);
shared_ptr<CDnOnCriticalHitMessage> pOnCriticalEvent = shared_polymorphic_downcast<CDnOnCriticalHitMessage>(pNotifyEvent);
pOnCriticalEvent->SetSkillID(hHitter->GetProcessSkill()->GetClassID());
pPlayer->Notify(pNotifyEvent);*/
}
// ¿¡¾î ÄÞº¸ °è»ê
if( IsAir() && IsHit() ) {
m_nAirComboCount++;
hHitter->OnAirCombo( m_nAirComboCount );
}
else m_nAirComboCount = 0;
m_HitParam.vVelocity = vVelocity;
}
else HitType = CDnWeapon::Defense;
m_HitParam.HitType = HitType;
// µ¥¹ÌÁö °è»ê
switch( HitType ) {
case CDnWeapon::Normal:
case CDnWeapon::Critical:
case CDnWeapon::Stun:
case CDnWeapon::CriticalRes:
{
// ¹«°Ô¿¡ µû¶ó °¡¼Óµµ ÁÙ¿©ÁØ´Ù.
if( GetWeight() > 0.f )
m_HitParam.vVelocity.y /= GetWeight();
if( GetWeight() > 1.f ) {
float fTemp = m_HitParam.vVelocity.z;
float fTest = CalcMovement( fTemp, 1.f, FLT_MAX, FLT_MIN, m_HitParam.vResistance.z );
if( m_HitParam.vVelocity.z * fTest > 0.f ) {
m_HitParam.vVelocity.x /= powf( 1.1f, GetWeight() );
m_HitParam.vVelocity.z /= powf( 1.1f, GetWeight() );
}
}
// ´ë¹ÌÁö »ó°ü°ü°è Ã¼Å©ÇØ¿ä
int nDamageType = m_HitParam.nDamageType;
// #13885 À̽´ °ü·Ã.
if( hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_086 ) )
{
// ÆÀ ¹ÝÀü »óÅÂÈ¿°ú Çϳª¸¸ Àû¿ëµÈ´Ù.
DNVector( DnBlowHandle ) vlReverseTeamBlows;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_086, vlReverseTeamBlows );
_ASSERT( false == vlReverseTeamBlows.empty() );
if( false == vlReverseTeamBlows.empty() )
{
DnBlowHandle hBlow = vlReverseTeamBlows.front();
CDnReverseTeamBlow* pReverseTeamBlow = static_cast<CDnReverseTeamBlow*>(hBlow.GetPointer());
if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_CHANGE == pReverseTeamBlow->GetType() )
{
switch( nDamageType )
{
case 0: // Enemy -> Friend
nDamageType = 1;
break;
case 1: // Friend -> Enemy
nDamageType = 0; // #50166 À̽´°ü·Ã Hittalbe¿¡¼­¸¸ ó¸®ÇÑ´Ù.
break;
case 2: // All -> All
break;
}
}
else
if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_ALL == pReverseTeamBlow->GetType() )
{
// Ÿ°Ý´ë»ó all ·Î ¹Ù²ãÁÜ.
nDamageType = 2;
}
}
}
//rlkt_damage
bool bCalcDamage = true;
float fDamage = 0.f;
switch( nDamageType )
{
case 0: // Enemy
if( GetTeam() == hHitter->GetTeam() ) bCalcDamage = false;
break;
case 1: // Friend
if( GetTeam() != hHitter->GetTeam() ) bCalcDamage = false;
break;
case 2: // All
break;
}
if( bCalcDamage )
{
fDamage = CalcDamage( hHitter, m_HitParam );
#ifdef PRE_ADD_EXPORT_DPS_INFORMATION
fDPS_DAMAGE = fDamage;
#endif
}
// Á×¾ú³ª üũ
if( GetHP() <= 0.f )
Die( hHitter );
if (fDamage > 0.0f && //µ¥¹ÌÁö°¡ ÀÖ°í
GetHP() > 0.0f && //»ç¸ÁÀÌ ¾Æ´Ï°í
!IsAppliedThisStateBlow(STATE_BLOW::BLOW_183)) //Á¢µÎ¾î »óÅÂÈ¿°ú ¹«½Ã(±¸¿ï¸ðµå) ¾Æ´Ñ°æ¿ì)
{
#if defined(PRE_ADD_PREFIX_SYSTE_RENEW)
ProcessPrefixDefenceSkill_New(hHitterActor);
#else
ProcessPrefixDefenceSkill(hHitterActor);
#endif // PRE_ADD_PREFIX_SYSTE_RENEW
}
bool bSuccessNormalDamage = true;
int nSuperAmmorTime = 0;
if( !IsDie() ) {
// Skill Super Ammor Check
// if( m_HitParam.nSkillSuperAmmorIndex == -1 || ( m_HitParam.nSkillSuperAmmorIndex != -1 && m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] > 0 ) {
bool bApplySuperAmmor = false;
if( m_HitParam.nSkillSuperAmmorIndex != -1 && m_HitParam.nSkillSuperAmmorIndex < 0)
break;
if( m_HitParam.nSkillSuperAmmorIndex == -1 ) {
bApplySuperAmmor = true;
}
else if( m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] > 0 ) {
int nAmmorDamage = m_HitParam.nSkillSuperAmmorDamage;// * (( HitType == CDnWeapon::Critical ) ? 2 : 1);
// ½´ÆÛ ¾Æ¸Ó º¸È£ »óÅ ȿ°ú°¡ Àû¿ë µÇ¾î ÀÖÀ¸¸é ½´ÆÛ ¾Æ¸Ó °è»ê ¾ÈÇÔ.[2010/12/28 semozz]
bool isApplySuperArmorShield = false;
isApplySuperArmorShield = this->IsAppliedThisStateBlow(STATE_BLOW::BLOW_156);
// [2011/02/09 semozz]
// °¡µð¾ð Æ÷½ºÀÇ Shield»óÅÂÈ¿°ú°¡ Àû¿ë µÇ¾î ÀÖÀ»¶§µµ ½´ÆÛ¾Æ¸Ó´Â ±úÁöÁö ¾Ê´Â´Ù.
// ½´ÆÛ¾Æ¸Ó º¸È£°ü·ÃÀÌ ¿ì¼±¼øÀ§°¡ °¡Àå ³ô´Ù.
if (!isApplySuperArmorShield)
isApplySuperArmorShield = this->IsAppliedThisStateBlow(STATE_BLOW::BLOW_055);
//½´ÆÛ¾Æ¸Ó ºê·¹ÀÌÅ© »óÅÂÈ¿°ú Àû¿ëµÇ¾î ÀÖÀ¸¸é ¹«Á¶°Ç ½´ÆÛ¾Æ¸Ó 0À¸·Î
if (isBreakSuperArmorBlow)
{
m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] = 0;
}
else if (!isApplySuperArmorShield)
{
//////////////////////////////////////////////////////////////////////////
// 142¹ø ½´ÆÛ¾Æ¸Ó °ø°Ý·Â ºñÀ² »óÅÂÈ¿°ú
if( hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_142 ) )
{
DNVector(DnBlowHandle) vlBlows;
float fValue = 1.0f;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_142, vlBlows );
for( int i = 0; i < (int)vlBlows.size(); ++i )
{
DnBlowHandle hBlow = vlBlows.at( i );
fValue += (hBlow->GetFloatValue() - 1.0f);
}
nAmmorDamage = int((float)nAmmorDamage * fValue);
}
//////////////////////////////////////////////////////////////////////////
m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] -= nAmmorDamage;
}
if( m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] <= 0 ) {
m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] = 0;
hHitter->OnBreakSkillSuperAmmor( m_HitParam.nSkillSuperAmmorIndex, m_nLastUpdateSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex], nAmmorDamage );
OnBreakSkillSuperAmmor( m_HitParam );
}
else bApplySuperAmmor = true;
}
if( bApplySuperAmmor ) {
bSuccessNormalDamage = false;
nSuperAmmorTime = m_nSkillSuperAmmorTime;
// ´ë¹ÌÁö °¨¼è½ÃÄÑÁØ´Ù.
SetHP( GetHP() + (INT64)( fDamage * m_fSkillSuperAmmorDamageDecreaseProb ) );
#ifdef PRE_ADD_EXPORT_DPS_INFORMATION
fDPS_DAMAGE += (int)( fDamage * m_fSkillSuperAmmorDamageDecreaseProb );
#endif
}
// Normal Super Ammor Check
if( m_bEnableNormalSuperAmmor == true ) {
if( m_HitParam.fDurability >= m_fBreakNormalSuperAmmorDurability )
m_bEnableNormalSuperAmmor = false;
else {
bSuccessNormalDamage = false;
nSuperAmmorTime = m_nNormalSuperAmmorTime;
}
}
if( pHitStruct->nSuperAmmorTime > 0 ) nSuperAmmorTime = pHitStruct->nSuperAmmorTime;
}
bool bSuperAmmorReset = true;
//////////////////////////////////////////////////////////////////////////
// ¾ÆÄ«µ¥¹Í Æ÷½º ¾Æ¿ô ½ºÅ³ ó¸® [2011/07/04 semozz]
// ¹«°Ô°ª Á¦ÇÑ °ªÀÌ ÀÖ°í, ¼³Á¤µÈ ¹«°Ô°ª º¸´Ù ¾×ÅÍÀÇ ¹«°Ô°¡ Àû´Ù¸é ½´ÆÛ¾Æ¸Ó »ó°ü ¾øÀÌ ¹°¸®°ª Àû¿ë
if( 0 < m_HitParam.nWeightValueLimit )
{
if( (float)m_HitParam.nWeightValueLimit >= GetWeight() )
{
//¹°¸®°ª Àû¿ëÀ» À§Çؼ­ bSuccessNormalDamage´Â true·Î º¯°æÇϰí.
bSuccessNormalDamage = true;
//½´ÆÛ¾Æ¸Ó °ª ¸®¼ÂÀº ¾ÈµÇµµ·ÏÇÑ´Ù..
bSuperAmmorReset = false;
//½´ÆÛ¾Æ¸Ó°¡ ±úÁö¸é(0) hitµ¿ÀÛÀ» Çϰí, ½´ÆÛ¾Æ¸Ó°¡ ±úÁöÁö ¾ÊÀ¸¸é Hitµ¿ÀÛÀ» Á¦°Å ÇÑ´Ù.
//#39137 ¸ó½ºÅͰ¡ Á×Àº °æ¿ì´Â ½ºÅµ
if (!IsDie() && m_HitParam.nSkillSuperAmmorIndex>=0 && m_nSkillSuperAmmorValue[m_HitParam.nSkillSuperAmmorIndex] > 0)
m_HitParam.szActionName.clear();
}
}
//////////////////////////////////////////////////////////////////////////
//ÀÌ »óÅÂÈ¿°ú°¡ °É·Á ÀÖ´Â »óÅ¿¡¼­ ÇÇ°Ý µ¿ÀÛÀ» Çϸé Escape¿¡¼­ ¼³Á¤µÈ ÇÇ°Ý µ¿ÀÛÀÌ Áß°£¿¡ Ãë¼ÒµÊ.
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_218))
{
#if defined(PRE_FIX_50007)
//#50007 EscapeÁß¿¡µµ Á×´Â µ¿ÀÛÀ¸·Î´Â º¯°æÀÌ µÇ¾î¾ß ÇÔ.(Dieµ¿ÀÛÀÌ ¾Æ´Ñ °æ¿ì¸¸ Hitµ¿ÀÛ Á¦°Å)
if (strstr(m_HitParam.szActionName.c_str(), "Die") == NULL)
#endif // PRE_FIX_50007
m_HitParam.szActionName.clear();
}
m_HitParam.bSuccessNormalDamage = bSuccessNormalDamage;
m_HitParam.nSuperAmmorDelay = nSuperAmmorTime;
if( bSuccessNormalDamage ) {
m_nNormalSuperAmmorTime = 0;
if (bSuperAmmorReset)
memset( m_nSkillSuperAmmorValue, 0, sizeof(m_nSkillSuperAmmorValue) );
CheckDamageVelocity( hHitter );
// ¸Â¾ÒÀ»¶§ ¸®¼ÂÇÒ°Íµé ¸®¼Â
MAMovementBase *pMovement = GetMovement();
if( pMovement ) {
pMovement->ResetMove();
pMovement->ResetLook();
}
if( !m_HitParam.szActionName.empty() )
{
#ifdef PRE_FIX_81750
CDnChangeStandActionBlow::ReleaseStandChangeSkill( GetActorHandle(), true );
#endif
SetActionQueue( m_HitParam.szActionName.c_str(), 0, 3.f, 0.f, false );
}
}
else {
int nDelay = (int)( nSuperAmmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) );
if( nDelay > 0 ) {
SetPlaySpeed( (DWORD)( nSuperAmmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) ), 0.03f );
if( m_HitParam.hWeapon && m_HitParam.hWeapon->GetEquipType() != CDnWeapon::Arrow )
{
#ifdef PRE_FIX_HITSTIFF
// ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°ú°¡ ¿ì¼± 󸮴ë»óÀ̹ǷΠ»óÅÂÈ¿°ú Àû¿ëÁßÀ̶ó¸é SetPlaySpeed() ÇÔ¼ö ¹«½Ã.
if( false == (0 < hHitter->GetFrameStopRefCount() || hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 )) )
{
hHitter->SetPlaySpeed( 100, 0.03f );
}
#else
hHitter->SetPlaySpeed( 100, 0.03f );
#endif // #ifdef PRE_FIX_HITSTIFF
}
}
m_HitParam.szActionName.clear();
}
}
break;
case CDnWeapon::Defense:
m_HitParam.vVelocity *= 0.5f;
m_HitParam.vVelocity.y = 0.f;
if( m_HitParam.hWeapon && m_HitParam.hWeapon->GetEquipType() != CDnWeapon::Arrow )
{
//#ifdef PRE_FIX_HITSTIFF
// ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°ú°¡ ¿ì¼± 󸮴ë»óÀ̹ǷΠ»óÅÂÈ¿°ú Àû¿ëÁßÀ̶ó¸é SetPlaySpeed() ÇÔ¼ö ¹«½Ã.
if( false == (0 < hHitter->GetFrameStopRefCount() || hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 )) )
{
hHitter->SetPlaySpeed( 100, 0.03f );
}
//#else
// hHitter->SetPlaySpeed( 100, 0.03f );
//#endif // #ifdef PRE_FIX_HITSTIFF
}
CheckDamageVelocity( hHitter );
// ¿¡´µ ½Ã۱¸
if( !m_HitParam.szActionName.empty() )
SetActionQueue( m_HitParam.szActionName.c_str(), 0, 3.f, 0.f, false );
break;
}
// OutputDebug( "µ¥¹ÌÁö : %s, %.2f, %.2f ( %.2f, %.2f )\n", m_HitParam.szActionName.c_str(), m_HitParam.vVelocity.y, m_HitParam.vResistance.y, GetVelocity() ? GetVelocity()->y :0.f, GetResistance() ? GetResistance()->y : 0.f);
// ¹«±â ¼Ò¸®, ÆÄƼŬ µîÀ» ó¸®Çϱâ À§ÇØ ÄÝÇØÁØ´Ù.
if( m_HitParam.hWeapon ) {
m_HitParam.hWeapon->OnHitSuccess( GetMySmartPtr(), HitType, m_HitParam.vPosition, m_HitParam.bFirstHit );
if( HitParam.hWeapon->GetWeaponType() & CDnWeapon::Projectile ) {
CDnProjectile *pProjectile = static_cast<CDnProjectile *>(HitParam.hWeapon.GetPointer());
if( pProjectile ) pProjectile->OnDamageSuccess( GetMySmartPtr(), m_HitParam );
else HitParam.hWeapon->SetDestroy();
}
}
// ½ºÅ³ ½ÃÀüÁß Çǰݽà ½ºÅ³ Ãë¼Ò.
if( false == m_HitParam.szActionName.empty() )
{
// ½ºÅ³ ¾×¼Ç Áß Çǰݽà ½ºÅ³ Ãë¼Ò¿¡ ´ëÇÑ °ÍÀº IsProcessSkill() ·Î üũÇÏÁö ¾Ê°í °´Ã¼ÀÇ Á¸Àç À¯¹«¸¸ üũÇÑ´Ù.
// IsFinished() ·Î ³»ºÎ¿¡¼­ üũÇϸé PlayAniProcess ³»ºÎ¿¡¼­ GetCurrentAction() ÀÌ ¾×¼Ç Å¥ °ªÀ» ¿ì¼±Çؼ­
// ¾ò¾î¿À±â ¶§¹®¿¡ À§¿¡¼­ Çǰݾ׼ÇÀÌ SetActionQueue·Î ¼ÂÆÃµÇ¸é ½ºÅ³ÀÌ ³¡³­ °ÍÀ¸·Î ÆÇ´ÜµÇ¾î ¾Æ·¡ ±¸¹®ÀÌ ½ÇÇàµÇÁö ¾Ê´Â´Ù.
if( m_hProcessSkill )
{
// ¿À¶ó ½ºÅ³ ½ÃÀü Áß.. ±×·¯´Ï±î »óÅÂÈ¿°ú ´Ù µé¾î°¡±â ÀÌÀü¿¡ Ÿ°ÝµÇ¾ú´Ù¸é ¿À¶ó ½ºÅ³ÀÌ ¿ÂÀüÈ÷ »ç¿ëµÈ °ÍÀÌ ¾Æ´Ô
if( IsEnabledAuraSkill() && m_hProcessSkill->IsAuraOn() )
{
//#41352 ¿À¶ó ½ºÅ³ Ãë¼ÒµÉ¶§ Ŭ¶óÀÌ¾ðÆ®·Î Ãë¼Ò ÆÐŶÀ» Àü¼ÛÇØ¾ßÇÔ..
CmdFinishAuraSkill(m_hAuraSkill->GetClassID());
OnSkillAura( m_hAuraSkill, false );
m_hProcessSkill.Identity();
OutputDebug( "### ¿À¶ó½ºÅ³ ÇǰݴçÇØ¼­ ĵ½½µÊ!!\n" );
}
else
{
m_hCanceledSkill = m_hProcessSkill;
m_hProcessSkill->OnEnd( CDnActionBase::m_LocalTime, 0.f );
m_hProcessSkill.Identity();
}
}
}
// ÇöÀç ¿ÀÅä ÆÐ½Ãºê ½ºÅ³Àº ÇǰݵǾúÀ» ¶§ ¹Û¿¡ ¹ßµ¿µÉ ¶§°¡ ¾øÀ½.
UseAutoPassiveSkill( 0, 0.0f );
if( hHitter ) hHitter->OnHitSuccess( CDnActionBase::m_LocalTime, GetMySmartPtr(), pHitStruct );
#ifdef PRE_ADD_EXPORT_DPS_INFORMATION
if( CDnDPSReporter::IsActive() && hHitter && hHitter->IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>( hHitter.GetPointer());
if(CDnDPSReporter::GetInstance().IsEnabledUser(pPlayerActor->GetCharacterDBID()))
{
DNVector(DnActorHandle) hVecList;
ScanActor( GetRoom(), *hHitter->GetPosition() , 500.f , hVecList );
CDnDPSReporter::GetInstance().ApplyAreaMonsterCount( (int)hVecList.size() );
CDnDPSReporter::GetInstance().ApplyBaseData( &m_HitParam , fDPS_DAMAGE );
CDnDPSReporter::GetInstance().ApplyTargetData(GetActorHandle());
CDnDPSReporter::GetInstance().EndReport();
}
}
#endif
}
void CDnActor::RequestDamage( CDnDamageBase *pHitter, int nSeed, INT64 nDamage )
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
char cHitterType = pHitter->GetDamageObjectType();
DWORD dwUniqueID = pHitter->GetDamageObjectUniqueID();
ASSERT( dwUniqueID != -1 && "À߸øµÈ DamageBase ¾ÆÀ̵ð" );
bool bSendWeaponSerialID = false;
DWORD dwWeaponUniqueID = -1;
INT64 nWeaponSerialID = -1;
int nActionIndex = GetElementIndex( m_HitParam.szActionName.c_str() );
if( m_HitParam.hWeapon ) {
if( m_HitParam.hWeapon->GetSerialID() == -1 )
dwWeaponUniqueID = m_HitParam.hWeapon->GetUniqueID();
else {
bSendWeaponSerialID = true;
nWeaponSerialID = m_HitParam.hWeapon->GetSerialID();
}
}
INT64 nCurrentHP = GetHP();
Stream.Write( &nSeed, sizeof(int) );
Stream.Write( &cHitterType, sizeof(char) );
Stream.Write( &dwUniqueID, sizeof(DWORD) );
Stream.Write( &bSendWeaponSerialID, sizeof(bool) );
if( bSendWeaponSerialID ) Stream.Write( &nWeaponSerialID, sizeof(INT64) );
else Stream.Write( &dwWeaponUniqueID, sizeof(DWORD) );
Stream.Write( &nActionIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
Stream.Write( &nDamage, sizeof(INT64) );
Stream.Write( &nCurrentHP, sizeof(INT64) ); // ÀÏ´Ü ³Ö¾î³ñ´Ï´Ù.
Stream.Write( &m_HitParam.HitType, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( ( GetVelocity() ) ? GetVelocity() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( ( GetResistance() ) ? GetResistance() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( &m_HitParam.vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( &EtVec3toVec2(m_HitParam.vViewVec), sizeof(EtVector2), CPacketCompressStream::VECTOR2_SHORT );
Stream.Write( &m_HitParam.bFirstHit, sizeof(bool) );
//Stream.Write( &m_HitParam.nBoneIndex, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
Stream.Write( &m_fStiffDelta, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 10000.f );
Stream.Write( &m_fDownDelta, sizeof(float), CPacketCompressStream::FLOAT_SHORT, 1000.f );
Stream.Write( &m_HitParam.nSuperAmmorDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
Stream.Write( &m_HitParam.bSuccessNormalDamage, sizeof(bool) );
Stream.Write( &m_HitParam.DistanceType, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
// #32722 Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ½ºÅ³ »ç¿ëÇÑ´Ù´Â ÆÐŶÀÌ µµÂøÇϱâ Àü¿¡ ¼­¹ö¿¡¼­ ÇÇ°ÝµÉ °æ¿ì Ŭ¶óÀÌ¾ðÆ®¸¸ ½ºÅ³ ¾×¼ÇÀÌ Äµ½½µÇ´Â °Í ¼öÁ¤.
int iCanceledSkillID = 0;
if( IsPlayerActor() )
{
if( m_hCanceledSkill )
{
iCanceledSkillID = m_hCanceledSkill->GetClassID();
m_hCanceledSkill.Identity();
}
else
if( IsDie() ) // ½ºÅ³ ¾²´Ù°¡ Á×Àº °æ¿ì¿£ CanceledSkillID ¸¦ -1 ·Î º¸³»Á༭ Ŭ¶óÂÊ¿¡¼­ ¾Ë ¼ö ÀÖµµ·Ï ÇÑ´Ù.
{
iCanceledSkillID = -1;
}
}
Stream.Write( &iCanceledSkillID, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
//////////////////////////////////////////////////////////////////////////
// ÀÓ½Ã
// ToDo : ÁØ¿µ¾¾²²¼­ ³ªÁß¿¡ ºÁÁÖ¼Å¾ß ÇÔ. Àӽ÷Π¾ÈÁ×°Ô¸¸ ¸·¾ÆµÒ.
int nSuperArmorValue = 0;
// Ç÷¹À̾îÀÇ ½´ÆÛ¾Æ¸Ó°¡ 33000 ±îÁö µÇ´Â °æ¿ì°¡ ÀÖ¾î ¾ÐÃàÇÏÁö ¾Ê°í ¼­¹ö¿¡¼­ º¸³À´Ï´Ù. (#10065)
Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int) );
Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nLastUpdateSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int) );
//Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
//Stream.Write( (m_HitParam.nSkillSuperAmmorIndex >= 0 && m_HitParam.nSkillSuperAmmorIndex <= 3) ? &m_nLastUpdateSkillSuperAmmorValue[ m_HitParam.nSkillSuperAmmorIndex ] : &nSuperArmorValue, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
// Combo ½ÌÄí
Stream.Write( &m_HitParam.HasElement, sizeof(int), CPacketCompressStream::INTEGER_CHAR );
#if defined( PRE_ADD_LOTUSGOLEM )
Stream.Write( &m_HitParam.bIgnoreShowDamage, sizeof(bool) );
#endif // #if defined( PRE_ADD_LOTUSGOLEM )
#ifdef PRE_ADD_STAGE_LIMIT_INTERFACE
Stream.Write( &m_HitParam.bStageLimit, sizeof(bool) );
#endif
switch( pHitter->GetDamageObjectType() ) {
case DamageObjectTypeEnum::Actor:
{
DnActorHandle hActor = pHitter->GetActorHandle();
if( !hActor ) break;
if( dwUniqueID >= 100000 ) {
CDnPlayerActor *pPlayer = ( hActor->IsPlayerActor() ) ? static_cast<CDnPlayerActor*>(hActor.GetPointer()) : NULL;
if( !pPlayer ) break;
int nComboCount = pPlayer->GetComboCount();
int nComboDelay = pPlayer->GetComboDelay();
Stream.Write( &nComboCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
Stream.Write( &nComboDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
}
// (#11415) À̽´ °ü·Ã, ¼ÒȯµÈ ·¼¸¯ÀÌ °ø°ÝÇÏ´Â °Íµµ ÄÞº¸ Ä«¿îÆ®¿¡ Æ÷ÇÔ½ÃŲ´Ù.
// Á÷Á¢ Ç÷¹À̾°Ô¼­ ¼ÒȯµÈ ¸ó½ºÅÍ Å¸ÀÔÀÎÁö ±¸ºÐÇØ¼­ ¸Â´Ù¸é ÆÐŶ¿¡ ½Ç¾î¼­ º¸³½´Ù.
// Ŭ¶óÂÊ¿¡¼­µµ ¸¶Âù°¡Áö·Î ÆÇ´Ü.
else if( hActor->IsMonsterActor() )
{
CDnMonsterActor* pMonsterActor = static_cast<CDnMonsterActor*>(hActor.GetPointer());
// ·¼¸¯(¼Òȯ¸÷)ÀÌ hit ÇßÀ» °æ¿ì ¼ÒȯÇÑ Ç÷¹À̾°Ô ÄÞº¸ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù. (#11415)
DnActorHandle hSummonMasterPlayer = pMonsterActor->GetSummonerPlayerActor();
if( hSummonMasterPlayer && hSummonMasterPlayer->IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(hSummonMasterPlayer.GetPointer());
int nComboCount = pPlayerActor->GetComboCount();
int nComboDelay = pPlayerActor->GetComboDelay();
Stream.Write( &nComboCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
Stream.Write( &nComboDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
}
else
if( CDnActorState::Cannon == pMonsterActor->GetActorType() )
{
// ´ëÆ÷ ¸ó½ºÅͰ¡ hit ÇßÀ» °æ¿ì ¸¶½ºÅÍ ¾×ÅÍÀÇ ÄÞº¸ Ä«¿îÆ®¸¦ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù. (#25778)
CDnCannonMonsterActor* pCannonMonster = static_cast<CDnCannonMonsterActor*>( pMonsterActor );
DnActorHandle hPlayerActor = pCannonMonster->GetMasterPlayerActor();
int nComboCount = 0;
int nComboDelay = 0;
if( hPlayerActor && hPlayerActor->IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(hPlayerActor.GetPointer());
int nComboCount = pPlayerActor->GetComboCount();
int nComboDelay = pPlayerActor->GetComboDelay();
}
Stream.Write( &nComboCount, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
Stream.Write( &nComboDelay, sizeof(int), CPacketCompressStream::INTEGER_SHORT );
}
}
}
break;
case DamageObjectTypeEnum::Prop:
break;
}
OnDamageWriteAdditionalPacket( &Stream );
Send( eActor::SC_ONDAMAGE, &Stream );
// #31022 Â÷Á® »óÅÂÈ¿°ú¿¡¼­ µ¹¸° ¾×¼ÇÀÇ hit ½Ã±×³Î·Î ¸ÂÀº °æ¿ì ¸¶Áö¸· µ¥¹ÌÁö·Î ±â·ÏÇÏÁö ¾Ê´Â´Ù.
// È­¿° »óÅÂÈ¿°ú¿¡¼­ ÆÛ°¡¼­ ¾²´Âµ¥ ¿µÇâÀ» ÁÖÁö ¾Ê±â À§ÇØ..
DnActorHandle hHitter = pHitter->GetActorHandle();
if( hHitter && false == hHitter->IsOnSignalFromChargerSE() )
m_iLastDamage = nDamage;
}
void CDnActor::OnRequestHPMPDelta( /*IN OUT*/ INT64& nHPMPDelta, const DWORD dwHitterUniqueID, bool bIsMPDelta /* = false */ )
{
if( false == bIsMPDelta && 0 < nHPMPDelta )
{
// 141¹ø Ä¡·áºñÀ²º¯°æ »óÅÂÈ¿°ú.
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_141 ) )
{
DNVector(DnBlowHandle) vlBlows;
float fValue = 1.0f;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_141, vlBlows );
for( int i = 0; i < (int)vlBlows.size(); ++i )
{
DnBlowHandle hBlow = vlBlows.at( i );
fValue += (hBlow->GetFloatValue() - 1.0f);
}
nHPMPDelta = INT64((float)nHPMPDelta * fValue);
}
}
}
// ¼­¹öÂÊ HP/MP ´Â ¹Ù²îÁö ¾ÊÀ¸¹Ç·Î ¹Ýµå½Ã µû·Î ¼­¹öÀÇ HPµµ Á¶ÀýÇØÁÙ °Í!
#ifdef PRE_FIX_77172
void CDnActor::RequestHPMPDelta( ElementEnum eElement, INT64 nHPMPDelta, const DWORD dwHitterUniqueID, bool bIsMPDelta /*= false */,
bool bShowValue, CDnDamageBase::SHitParam* pHitParam/* = NULL*/, bool bKeepJumpMovement /*=false*/ )
#else // PRE_FIX_77172
void CDnActor::RequestHPMPDelta( ElementEnum eElement, INT64 nHPMPDelta, const DWORD dwHitterUniqueID, bool bIsMPDelta /*= false */, bool bShowValue, CDnDamageBase::SHitParam* pHitParam/* = NULL*/ )
#endif // PRE_FIX_77172
{
OnRequestHPMPDelta( nHPMPDelta, dwHitterUniqueID, bIsMPDelta );
#if defined(PRE_FIX_59680)
//¼­¸Õ ÆÛÆêÀÇ TransmitDamageBlow(51)¿¡ ÀÇÇØ¼­ Á¤»óÀûÀÎ Hit½Ã±×³Î 󸮰¡ ¾ÈµÇ´Â °æ¿ì RecoverHPByAttack(248) »óÅÂÈ¿°ú°¡ Á¤»ó 󸮵ÇÁö ¾Ê´Â Çö»ó ¹ß»ýµÊ.
//51¹ø »óÅÂÈ¿°ú¿¡¼­ ÁÖÀÎ ¾×ÅÍ·Î µ¥¹ÌÁö 󸮸¦ ÀÌÂÊ ÇÔ¼ö È£Ãâ·Î Çϴµ¥, ¿©±â¼­ HitParam°ª¿¡ µ¥¹ÌÁö¸¦ ¼³Á¤ ÇØ ³õ¾Æ¾ß 248¹ø »óÅÂÈ¿°ú¿¡¼­ Á¤»óÀûÀ¸·Î
//HPȸº¹À» ÇÒ ¼ö ÀÖ´Ù.(248¹ø »óÅÂÈ¿°ú¿¡¼­ TargetActor°¡ SummonMonsterÀÏ °æ¿ì ÁÖÀÎ ¾×ÅÍÀÇ HitParam Á¤º¸¸¦ ¾ò¾î ¿Í¾ß ÇÔ.)
if (bIsMPDelta == false)
{
m_HitParam.nCalcDamage = -nHPMPDelta;
}
#endif // PRE_FIX_59680
BYTE pBuffer[ 32 ];
CPacketCompressStream Stream( pBuffer, 32 );
Stream.Write( &eElement, sizeof(ElementEnum), CPacketCompressStream::INTEGER_CHAR );
Stream.Write( &nHPMPDelta, sizeof(INT64) );
Stream.Write( &dwHitterUniqueID, sizeof(DWORD) );
Stream.Write( &bIsMPDelta, sizeof(bool) );
Stream.Write( &bShowValue, sizeof(bool) );
#if defined(PRE_FIX_59308)
int nHitType = pHitParam ? pHitParam->HitType : CDnWeapon::Normal;
Stream.Write( &nHitType, sizeof(int) );
#endif // PRE_FIX_59308
#ifdef PRE_FIX_77172
Stream.Write( &bKeepJumpMovement, sizeof(bool) );
#endif // PRE_FIX_77172
Send( eActor::SC_SETHPMP_DELTA, &Stream );
}
// È®·ü ¹ßµ¿À¸·Î ¾î¶² ÀÏÀ» ¼öÇàÇÏ´Â »óÅÂÈ¿°ú°¡ ¼­¹ö·ÎºÎÅÍ ¹ßµ¿µÇ¾ú´Ù°í Ŭ¶óÇÑÅ× ¾Ë·ÁÁÜ. ÇöÀç ¼­¹ö¿¡¼­ Ŭ¶ó·Î ½î±â¸¸ ÇÒ¶§ »ç¿ëµÊ.
// ÇöÀç ÆäÀÌ¹é ¸¶³ª¿¡¼­ »ç¿ëÁß.
void CDnActor::RequestSEProbSuccess( int iSkillID, STATE_BLOW::emBLOW_INDEX eBlowIndex )
{
BYTE pBuffer[ 16 ];
CPacketCompressStream Stream( pBuffer, 16 );
Stream.Write( &iSkillID, sizeof(int) );
Stream.Write( &eBlowIndex, sizeof(STATE_BLOW::emBLOW_INDEX) );
Send( eActor::SC_STATEEFFECT_PROB_SUCCESS, &Stream );
}
void CDnActor::RequestCooltimeReset( int iSkillID )
{
BYTE pBuffer[ 4 ];
CPacketCompressStream Stream( pBuffer, 16 );
Stream.Write( &iSkillID, sizeof(int) );
Send( eActor::SC_COOLTIME_RESET, &Stream );
}
bool CDnActor::Compare_PreStateOrder( CDnActor::PreStateStruct &a, CDnActor::PreStateStruct &b )
{
return ( a.nOffset < b.nOffset ) ? true : false;
}
void CDnActorActionStateCache::LoadAction( CDnActor* pActor, const char* szFullPathName, \
std::vector<CEtActionBase::ActionElementStruct*>* pVecActionElementList, \
std::vector<std::vector<CDnActor::PreStateStruct>>& ActionState, \
std::vector<std::vector<CDnActor::PreStateStruct>>& ActionCustomState, \
std::vector<std::vector<CDnActor::PreStateStruct>>& CanMoveState )
{
// ij½¬ µÇ¾î ÀÖ´Â Á¤º¸°¡ ÀÖ´ÂÁö È®ÀÎ
{
//CPerformanceLog log("loadaction-cache");
std::map<std::string,SData>::iterator itor;
{
ScopeLock<CSyncLock> lock(m_Lock);
itor = m_mRepository.find( szFullPathName );
}
if( itor != m_mRepository.end() )
{
ActionState.reserve( (*itor).second.VecPreActionState.size() );
ActionCustomState.reserve( (*itor).second.VecPreActionCustomState.size() );
CanMoveState.reserve( (*itor).second.VecPreCanMoveState.size() );
ActionState = (*itor).second.VecPreActionState;
ActionCustomState = (*itor).second.VecPreActionCustomState;
CanMoveState = (*itor).second.VecPreCanMoveState;
return;
}
}
SData data;
int nValue = 0;
std::vector<CDnActor::PreStateStruct> VecList;
CEtActionSignal *pSignal;
for( DWORD i=0; i< pVecActionElementList->size(); i++ )
{
// STE_State
VecList.clear();
for( int j=0; ; j++ )
{
nValue = 0;
pSignal = pActor->GetSignal( i, STE_State, j );
if( pSignal )
{
StateStruct *pStruct = (StateStruct *)pSignal->GetData();
nValue = CDnActorState::s_nActorStateIndex[pStruct->nStateOne] |
CDnActorState::s_nActorStateIndex[pStruct->nStateTwo] |
CDnActorState::s_nActorStateIndex[pStruct->nStateThree];
}
else
break;
VecList.push_back( CDnActor::PreStateStruct( nValue, pSignal->GetStartFrame() ) );
}
if( VecList.empty() )
VecList.push_back( CDnActor::PreStateStruct( nValue, 0 ) );
else
std::sort( VecList.begin(), VecList.end(), pActor->Compare_PreStateOrder );
data.VecPreActionState.push_back( VecList );
// STE_CustomState
VecList.clear();
for( int j=0; ; j++ )
{
nValue = 0;
pSignal = pActor->GetSignal( i, STE_CustomState, j );
if( pSignal ) {
CustomStateStruct *pStruct = (CustomStateStruct *)pSignal->GetData();
nValue = CDnActorState::s_nActorStateIndex[pStruct->nStateOne] |
CDnActorState::s_nActorStateIndex[pStruct->nStateTwo] |
CDnActorState::s_nActorStateIndex[pStruct->nStateThree];
}
else
break;
VecList.push_back( CDnActor::PreStateStruct( nValue, pSignal->GetStartFrame() ) );
}
if( VecList.empty() )
VecList.push_back( CDnActor::PreStateStruct( nValue, 0 ) );
else
std::sort( VecList.begin(), VecList.end(), pActor->Compare_PreStateOrder );
data.VecPreActionCustomState.push_back( VecList );
// STE_CanMove
VecList.clear();
for( int j=0; ; j++ )
{
nValue = 0;
pSignal = pActor->GetSignal( i, STE_CanMove, j );
if( pSignal )
{
CanMoveStruct *pStruct = (CanMoveStruct *)pSignal->GetData();
nValue = pStruct->bCanMove;
}
else
break;
VecList.push_back( CDnActor::PreStateStruct( nValue, pSignal->GetStartFrame() ) );
}
if( VecList.empty() )
VecList.push_back( CDnActor::PreStateStruct( nValue, 0 ) );
else
std::sort( VecList.begin(), VecList.end(), pActor->Compare_PreStateOrder );
data.VecPreCanMoveState.push_back( VecList );
}
// ij½¬Á¤º¸ ±â·Ï
{
ScopeLock<CSyncLock> lock(m_Lock);
m_mRepository.insert( std::make_pair(szFullPathName, data) );
}
ActionState.reserve( data.VecPreActionState.size() );
ActionCustomState.reserve( data.VecPreActionCustomState.size() );
CanMoveState.reserve( data.VecPreCanMoveState.size() );
ActionState = data.VecPreActionState;
ActionCustomState = data.VecPreActionCustomState;
CanMoveState = data.VecPreCanMoveState;
}
bool CDnActor::LoadAction( const char *szFullPathName )
{
bool bResult = CDnActionBase::LoadAction( szFullPathName );
if( !bResult ) return false;
CDnActorActionStateCache::GetInstance().LoadAction( this, szFullPathName, m_pVecActionElementList, m_VecPreActionState, m_VecPreActionCustomState, m_VecPreCanMoveState );
return bResult;
}
void CDnActor::FreeAction()
{
CDnActionBase::FreeAction();
SAFE_DELETE_VEC( m_VecPreActionState );
}
void CDnActor::LinkWeapon( int nEquipIndex )
{
switch( m_hWeapon[nEquipIndex]->GetEquipType() ) {
case CDnWeapon::Sword:
case CDnWeapon::Axe:
case CDnWeapon::Hammer:
case CDnWeapon::SmallBow:
case CDnWeapon::BigBow:
case CDnWeapon::CrossBow:
case CDnWeapon::Staff:
case CDnWeapon::Book:
case CDnWeapon::Orb:
case CDnWeapon::Puppet:
case CDnWeapon::Mace:
case CDnWeapon::Flail:
case CDnWeapon::Wand:
case CDnWeapon::Shield:
case CDnWeapon::Gauntlet:
m_hWeapon[nEquipIndex]->LinkWeapon( GetMySmartPtr(), nEquipIndex );
break;
case CDnWeapon::Arrow:
m_hWeapon[nEquipIndex]->LinkWeapon( GetMySmartPtr(), m_hWeapon[0] );
break;
}
}
void CDnActor::AttachWeapon( DnWeaponHandle hWeapon, int nEquipIndex, bool bDelete )
{
#if defined(PRE_ADD_50907)
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_237))
{
if (IsChangeWeaponLock() == true)
{
//¹«±â ÇØÁ¦ »óÅÂÈ¿°ú°¡ Àû¿ë µÈ ½ÃÁ¡Àε¥ ¹«±â ÀåÂøÀÌ µÇ´Â °æ¿ì¶ó¸é ÀÌ ½ÃÁ¡¿¡ º¯°æÀº ¾ÈµÇµµ·Ï ½ºÅµÇϰí,
//OrigWeapon ¹«±â Á¤º¸¸¦ °»½ÅÇÑ´Ù.
SetOrigWeaponWhenDisarmament(hWeapon, bDelete);
return;
}
}
#endif // PRE_ADD_50907
if( m_hWeapon[nEquipIndex] ) {
DetachWeapon( nEquipIndex );
}
m_hWeapon[nEquipIndex] = hWeapon;
m_bSelfDeleteWeapon[nEquipIndex] = bDelete;
m_hWeapon[nEquipIndex]->CreateObject();
LinkWeapon( nEquipIndex );
#if defined(PRE_ADD_50907)
if (IsSkipOnAttatchDetachWeapon() == true)
return;
#endif // PRE_ADD_50907
MASkillUser::OnAttachWeapon( m_hWeapon[ nEquipIndex ], nEquipIndex );
}
void CDnActor::DetachWeapon( int nEquipIndex )
{
if( !m_hWeapon[nEquipIndex] ) return;
#if defined(PRE_ADD_50907)
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_237))
{
if (IsChangeWeaponLock() == true)
return;
}
#endif // PRE_ADD_50907
m_hWeapon[nEquipIndex]->FreeObject();
m_hWeapon[nEquipIndex]->UnlinkWeapon();
if( m_bSelfDeleteWeapon[nEquipIndex] ) {
SAFE_RELEASE_SPTR( m_hWeapon[nEquipIndex] );
m_bSelfDeleteWeapon[nEquipIndex] = false;
}
m_hWeapon[nEquipIndex].Identity();
#if defined(PRE_ADD_50907)
if (IsSkipOnAttatchDetachWeapon() == true)
return;
#endif // PRE_ADD_50907
MASkillUser::OnDetachWeapon( m_hWeapon[ nEquipIndex ], nEquipIndex );
}
void CDnActor::ShowWeapon( int nEquipIndex, bool bShow )
{
if( m_hWeapon[nEquipIndex] )
m_hWeapon[nEquipIndex]->ShowWeapon( bShow );
}
bool CDnActor::IsStay( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Stay ) ? true : false;
return false;
}
bool CDnActor::IsMove( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Move ) ? true : false;
return false;
}
bool CDnActor::IsAttack( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Attack ) ? true : false;
return false;
}
bool CDnActor::IsHit( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Hit ) ? true : false;
return false;
}
bool CDnActor::IsAir( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Air ) ? true : false;
return false;
}
bool CDnActor::IsDown( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Down ) ? true : false;
return false;
}
bool CDnActor::IsStun( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Stun ) ? true : false;
return false;
}
bool CDnActor::IsStiff( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionState[nIndex][0].nState & ActorStateEnum::Stiff ) ? true : false;
return false;
}
bool CDnActor::IsFly( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionCustomState[nIndex][0].nState & ActorCustomStateEnum::Custom_Fly ) ? true : false;
return false;
}
bool CDnActor::IsGround( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return ( m_VecPreActionCustomState[nIndex][0].nState & ActorCustomStateEnum::Custom_Ground ) ? true : false;
return false;
}
bool CDnActor::IsStandHit( const char *szActionName )
{
int nIndex;
int nState = 0;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) nState = m_VecPreActionState[nIndex][0].nState;
else return false;
if( nState == ActorStateEnum::Hit || nState == ( ActorStateEnum::Hit | ActorStateEnum::Stiff ) ) return true;
return false;
}
int CDnActor::GetState( const char *szActionName )
{
int nIndex;
if( ( nIndex = GetElementIndex( szActionName ) ) != -1 ) return m_VecPreActionState[nIndex][0].nState;
return 0;
}
int CDnActor::GetState( int nElementIndex )
{
if( nElementIndex < 0 || nElementIndex >= (int)m_VecPreActionState.size() ) return 0;
return m_VecPreActionState[nElementIndex][0].nState;
}
// SetPlaySpeed ¿Í´Â º°°³·Î ÇÁ·¹ÀÓ º¯°æ, ÇÁ·¹ÀÓ Á¤Áö »óÅÂÈ¿°ú°¡ Begin/End µÉ ¶§ ¸¶´Ù ¾÷µ¥ÀÌÆ® µÇ´Â ÇÔ¼öÀÌ´Ù.
// Àû¿ëµÈ ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°úÀÇ °ªµéÀ» ¸ð¾Æ ÇѲ¨¹ø¿¡ °ªÀ» ´õÇØ¼­ ¼ÂÆÃÇØÁØ´Ù.
// FrameStop »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é ¾Æ¿¹ 0 ÇÁ·¹ÀÓÀ¸·Î ó¸®.
// ¸¸¾à »óÅÂÈ¿°ú°¡ ºñ¾îÀÖ´Ù¸é 60 ÇÁ·¹ÀÓÀ¸·Î º¹±¸½ÃÄÑÁØ´Ù.
// SetPlaySpeed ¿Í´Â º°°³·Î µ¹¾Æ°¡Áö¸¸ ProcessPlaySpeed() ¿¡¼­ Á¾·áµÈ ÈÄ¿¡ ÀÌ ÇÔ¼ö¸¦ Çѹø ´õ È£ÃâÇØ¼­ »óÅÂÈ¿°úµé·Î
// ¿µÇâÀ» ¹Þ´Â ÃÖÁ¾ ÇÁ·¹ÀÓÀ» ´Ù½Ã ¾÷µ¥ÀÌÆ® ÇØÁÖ¾î¾ß ÇÑ´Ù. µû¶ó¼­ »óÅÂÈ¿°úÂÊ¿¡¼­´Â SetPlaySpeed ÇÔ¼ö¸¦ »ç¿ëÇØ¼­´Â ¾ÈµÈ´Ù.
void CDnActor::UpdateFPS( void )
{
// ÇÁ¶ø ¾×ÅÍ´Â process ¸¦ µ¹Áö ¾Ê±â ¶§¹®¿¡ playspeed Á¶ÀýÇÏ¸é ¾ÈµÈ´Ù. #26354
if( ActorTypeEnum::PropActor == GetActorType() )
return;
float fFrameRatio = 1.0f;
if( m_bModifyPlaySpeed )
{
fFrameRatio = m_fPlaySpeed;
float fPrevFPS = CDnActionBase::m_fFPS;
CDnActionBase::SetFPS( 60.f * fFrameRatio );
for( DWORD i=0; i<m_hVecLastHitListByRemainTime.size(); i++ )
{
if( m_hVecLastHitListByRemainTime[i] )
{
// ¸ÕÀú 60 ÇÁ·¹ÀÓ ±âÁØÀ¸·Î ¿ø»ó º¹±¸ ½ÃŲ ÈÄ
float fFrame = ( ( m_hVecLastHitListByRemainTime[i]->GetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * fPrevFPS;
// »õ·Î Àû¿ëµÉ ÇÁ·¹ÀÓ ½ºÇǵå·Î RemainTime Àç °è»ê.
m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / ( CDnActionBase::m_fFPS) * 1000.f ) );
}
}
}
else
{
ResetPlaySpeed();
// ÇÁ·¹ÀÓ Á¤Áö »óÅÂÈ¿°ú. Çϳª¶óµµ °É·ÁÀÖ´Ù¸é ¸ðµç ÇÁ·¹ÀÓ Á¤Áö.
if( 0 < GetFrameStopRefCount() )
{
float fPrevFPS = CDnActionBase::m_fFPS;
CDnActionBase::SetFPS( 0.0f );
fFrameRatio = 0.0f;
}
else
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 ) ||
IsAppliedThisStateBlow( STATE_BLOW::BLOW_144 ) ||
IsAppliedThisStateBlow( STATE_BLOW::BLOW_220)
)
{
#ifdef PRE_ADD_SLOW_DEBUFF_LIMIT
float fBuffFrameRatio = 0.0f;
#endif // PRE_ADD_SLOW_DEBUFF_LIMIT
// ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°úµéÀÇ °ªÀ» ¸ð¾Æ¼­ Àû¿ë.
DNVector( DnBlowHandle ) vlhFrameBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_025, vlhFrameBlows );
for( int i = 0; i < (int)vlhFrameBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhFrameBlows.at( i );
#ifdef PRE_ADD_SLOW_DEBUFF_LIMIT
if( hBlow->GetAddBlowStateType() == AddBlowStateType::Equip_Buff_Level )
fBuffFrameRatio += hBlow->GetFloatValue();
else
fFrameRatio += hBlow->GetFloatValue();
#else // PRE_ADD_SLOW_DEBUFF_LIMIT
fFrameRatio += hBlow->GetFloatValue();
#endif // PRE_ADD_SLOW_DEBUFF_LIMIT
}
// #27320 µ¿»ó »óÅÂÈ¿°úµµ ÇÁ·¹ÀÓ ´À·ÁÁüÀÇ È¿°ú°¡ ÀÖ´Ù.
vlhFrameBlows.clear();
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_144, vlhFrameBlows );
for( int i = 0; i < (int)vlhFrameBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhFrameBlows.at( i );
#ifdef PRE_ADD_SLOW_DEBUFF_LIMIT
if( hBlow->GetAddBlowStateType() == AddBlowStateType::Equip_Buff_Level )
fBuffFrameRatio += static_cast<CDnFrostbiteBlow*>(hBlow.GetPointer())->GetFrameBlowArg();
else
fFrameRatio += static_cast<CDnFrostbiteBlow*>(hBlow.GetPointer())->GetFrameBlowArg();
#else // PRE_ADD_SLOW_DEBUFF_LIMIT
fFrameRatio += static_cast<CDnFrostbiteBlow*>(hBlow.GetPointer())->GetFrameBlowArg();
#endif // PRE_ADD_SLOW_DEBUFF_LIMIT
}
vlhFrameBlows.clear();
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_220, vlhFrameBlows );
for( int i = 0; i < (int)vlhFrameBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhFrameBlows.at( i );
#ifdef PRE_ADD_SLOW_DEBUFF_LIMIT
if( hBlow->GetAddBlowStateType() == AddBlowStateType::Equip_Buff_Level )
fBuffFrameRatio += hBlow->GetFloatValue();
else
fFrameRatio += hBlow->GetFloatValue();
#else // PRE_ADD_SLOW_DEBUFF_LIMIT
fFrameRatio += hBlow->GetFloatValue();
#endif // PRE_ADD_SLOW_DEBUFF_LIMIT
}
#ifdef PRE_ADD_SLOW_DEBUFF_LIMIT
if( GetGameRoom() && GetGameRoom()->bIsPvPRoom() )
{
if( fBuffFrameRatio < CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Min ) )
fBuffFrameRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Min );
else if( fBuffFrameRatio > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Max ) )
fBuffFrameRatio = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FrameSpeedRatio_Limit_Max );
}
fFrameRatio += fBuffFrameRatio;
#endif // PRE_ADD_SLOW_DEBUFF_LIMIT
if( fFrameRatio < 0.0f )
fFrameRatio = 0.0f;
float fPrevFPS = CDnActionBase::m_fFPS;
CDnActionBase::SetFPS( 60.0f * fFrameRatio );
for( DWORD i=0; i<m_hVecLastHitListByRemainTime.size(); i++ )
{
if( m_hVecLastHitListByRemainTime[i] )
{
// ¸ÕÀú 60 ÇÁ·¹ÀÓ ±âÁØÀ¸·Î ¿ø»ó º¹±¸ ½ÃŲ ÈÄ
float fFrame = ( ( m_hVecLastHitListByRemainTime[i]->GetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * fPrevFPS;
// »õ·Î Àû¿ëµÉ ÇÁ·¹ÀÓ ½ºÇǵå·Î RemainTime Àç °è»ê.
m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / ( CDnActionBase::m_fFPS ) * 1000.f ) );
}
}
}
else
{
fFrameRatio = 1.0f;
float fPrevFPS = CDnActionBase::m_fFPS;
// ¿ø»óº¹±¸
CDnActionBase::SetFPS( 60.0f );
for( DWORD i=0; i<m_hVecLastHitListByRemainTime.size(); i++ )
{
if( m_hVecLastHitListByRemainTime[i] )
{
float fFrame = ( ( m_hVecLastHitListByRemainTime[i]->GetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * fPrevFPS;
if( m_hVecLastHitListByRemainTime[i] )
m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / ( CDnActionBase::m_fFPS ) * 1000.f ) );
}
}
m_hVecLastHitListByRemainTime.clear();
}
}
if( IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(this);
pPlayerActor->OnChangePlaySpeed( 0, fFrameRatio );
}
}
void CDnActor::AddedFrameStop( void )
{
++m_iFrameStopRefCount;
// #28345 ¸ó½ºÅÍÀÎ °æ¿ì AI ¸¦ ²¨ÁÖÁö ¾ÊÀ¸¸é ÇÁ·¹ÀÓ ¸ØÃçÁø µ¿¾È ¾×¼ÇÀÌ »õ·Î ¼ÂÆÃµÇ¸é¼­
// 0 ÇÁ·¹ÀÓÀ¸·Î ¹Ù²î¾î¹ö¸®´Â ¹®Á¦°¡ »ý±è.
if( IsMonsterActor() )
{
static_cast<CDnMonsterActor*>(this)->SetAIState( MAAiReceiver::Disable, false );
}
UpdateFPS();
};
void CDnActor::RemovedFrameStop( void )
{
m_iFrameStopRefCount--;
if( m_iFrameStopRefCount < 0 )
m_iFrameStopRefCount = 0;
// #28345 ¸ó½ºÅÍÀÎ °æ¿ì AI ¸¦ ²¨ÁÖÁö ¾ÊÀ¸¸é ÇÁ·¹ÀÓ ¸ØÃçÁø µ¿¾È ¾×¼ÇÀÌ »õ·Î ¼ÂÆÃµÇ¸é¼­
// 0 ÇÁ·¹ÀÓÀ¸·Î ¹Ù²î¾î¹ö¸®´Â ¹®Á¦°¡ »ý±è.
if( IsMonsterActor() )
{
if( 0 == m_iFrameStopRefCount )
{
static_cast<CDnMonsterActor*>(this)->SetAIState( MAAiReceiver::Threat, false );
}
}
UpdateFPS();
};
void CDnActor::SetPlaySpeed( DWORD dwFrame, float fSpeed )
{
//// ÇÁ·¹ÀÓ º¯°æ »óÅÂÈ¿°ú°¡ ¿ì¼± 󸮴ë»óÀ̹ǷΠ»óÅÂÈ¿°ú Àû¿ëÁßÀ̶ó¸é SetPlaySpeed() ÇÔ¼ö ¹«½Ã.
//if( 0 < GetFrameStopRefCount() || IsAppliedThisStateBlow( STATE_BLOW::BLOW_025 ) )
// return;
if( m_bModifyPlaySpeed == true )
return;
// ÇÁ¶ø ¾×ÅÍ´Â process ¸¦ µ¹Áö ¾Ê±â ¶§¹®¿¡ playspeed Á¶ÀýÇÏ¸é ¾ÈµÈ´Ù. #26354
if( ActorTypeEnum::PropActor == GetActorType() )
return;
m_bModifyPlaySpeed = true;
m_PlaySpeedStartTime = CDnActionBase::m_LocalTime;
m_dwPlaySpeedTime = dwFrame;
m_fPlaySpeed = fSpeed;
UpdateFPS();
}
void CDnActor::ProcessPlaySpeed( LOCAL_TIME LocalTime, float fDelta )
{
if( m_bModifyPlaySpeed == false ) return;
if( m_PlaySpeedStartTime == 0 ) m_PlaySpeedStartTime = LocalTime;
if( LocalTime - m_PlaySpeedStartTime > m_dwPlaySpeedTime )
{
//m_bModifyPlaySpeed = false; // ResetPlaySpeed ÇÔ¼ö ³»ºÎ¿¡¼­ È£ÃâµÊ.
ResetPlaySpeed();
UpdateFPS();
return;
}
}
// #15065 À̽´ °ü·Ã.
// °áºù ½Ã ÇÁ·¹ÀÓ ¸ØÃß´Â °Í SetPlaySpeed ÇÔ¼ö È£ÃâÇÒ ¶§ ÀÌ¹Ì Å¸°Ý¶§¹®¿¡ Àá±ñ PlaySpeed Á¶Á¤µÇ´Â ŸÀ̹ÖÀÏ ¶§°¡ À־
// ÇÔ¼öÈ£ÃâÀÌ ¾ÃÈú ¶§°¡ ÀÖ´Ù. CDnFreezingBlow::OnBegin() ¿¡¼­ SetPlaySpeed() È£ÃâÇϱâ Àü¿¡ ¸®¼Â½Ã۰í È£ÃâÇÑ´Ù.
void CDnActor::ResetPlaySpeed()
{
if( m_bModifyPlaySpeed == false )
return;
for( DWORD i=0; i<m_hVecLastHitListByRemainTime.size(); i++ ) {
if( m_hVecLastHitListByRemainTime[i] ) {
float fFrame = ( ( m_hVecLastHitListByRemainTime[i]->GetDamageRemainTime( GetUniqueID() ) - CDnActionBase::m_LocalTime ) / 1000.f ) * CDnActionBase::m_fFPS;
m_hVecLastHitListByRemainTime[i]->SetDamageRemainTime( GetUniqueID(), CDnActionBase::m_LocalTime + (LOCAL_TIME)( fFrame / 60.f * 1000.f ) );
}
}
CDnActionBase::SetFPS( 60.f );
if( IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(this);
pPlayerActor->OnChangePlaySpeed( 0, 60.0f / CDnActionBase::m_fFPS );
}
// Note: SignalEndTime ÀÌ º¹±¸ ½ÃÄÑÁØ ³ðµéÀº ¿©±â¼­ ³¯¸³´Ï´Ù.
//m_hVecLastHitListByRemainTime.clear();
m_bModifyPlaySpeed = false;
}
void CDnActor::SyncClassTime( LOCAL_TIME LocalTime )
{
CDnActionBase::m_LocalTime = LocalTime;
MASkillUser::m_LocalTime = LocalTime;
}
void CDnActor::OnClash( EtVector3 &vPosition, OnClashFloorCheckType bFloorClash )
{
if( !IsDie() && IsHit() && ( IsAir() || IsDown() ) && !IsStun() ) {
float fDecrease = 0.85f;
if( GetVelocity()->x != 0.f ) {
SetVelocityX( -GetVelocity()->x * fDecrease );
SetResistanceX( -GetResistance()->x );
}
if( GetVelocityValue()->z < -120.f ) {
float fVelocityValue = GetVelocityValue()->z; // ÀÏÁ¤ ÀÌ»óÀÇ Ãæ°ÝÀÏ °æ¿ì¿¡´Â »è°¨ÇØÁØ´Ù. Áö±Ý»óÅ¿¡¼± 300 ÀÌ ÃÖÀû..
if( fVelocityValue < -300.f ) fVelocityValue = -300.f;
float fYVel = 5.f + ( -fVelocityValue * 0.01f );
// if( fYVel > 8.f ) fYVel = 8.f;
// if( fVelocityValue >
// OutputDebug( "PrevVel Z : %.2f PrevVel Y : %.2f - %.2f\n", GetVelocity()->z, GetVelocity()->y, GetVelocityValue()->z );
SetVelocityZ( -GetVelocity()->z * ( 1.35f - ( 1.f / 4.f * ( -fVelocityValue * 0.01f ) ) ) );
SetResistanceZ( -GetResistance()->z );
SetVelocityY( fYVel );
SetResistanceY( -18.f );
// OutputDebug( "Vel Z : %.2f Vel Y : %.2f\n", GetVelocity()->z, GetVelocity()->y );
// OutputDebug( "Res Z : %.2f Res Y : %.2f\n", GetResistance()->z, GetResistance()->y );
EtVector3 vLook;
vLook = -m_Cross.m_vZAxis;
vLook.y = 0.f;
EtVec3Normalize( &vLook, &vLook );
Look( EtVector2( vLook.x, vLook.z ) );
if( IsDie() ) SetActionQueue( "Die_Air", 0, 0.f );
else SetActionQueue( "Hit_AirUp", 0, 0.f );
if( m_HitParam.hWeapon ) {
m_HitParam.hWeapon->OnHitSuccess( GetMySmartPtr(), CDnWeapon::Stun, vPosition, true );
}
}
else {
if( GetVelocity()->z != 0.f ) {
SetVelocityZ( -GetVelocity()->z * fDecrease );
SetResistanceZ( -GetResistance()->z );
}
}
}
}
bool CDnActor::IsHittable( DnActorHandle hHitter, LOCAL_TIME LocalTime, HitStruct *pHitSignal, int iHitUniqueID /*= -1*/ )
{
#if !defined( _FINAL_BUILD )
if( bIsIgnoreHit() ) return false;
#endif // #if !defined( _FINAL_BUILD )
bool isSelfCheck = false;
isSelfCheck = pHitSignal ? (pHitSignal->isSelfCheck?true:false) : false;
//ÀڽŠüũ°¡ ¼³Á¤µÇ¾î ÀÖÁö ¾ÊÀ»¶§¸¸(false°¡ ±âº». ƯÁ¤(¿Î½º ½ºÅ³...)¿¡¼­¸¸ true·Î ¼³Á¤.
//true·Î ¼³Á¤µÇ¾î ÀÖÀ¸¸é Àڽŵµ Hitó¸®..
if (false == isSelfCheck)
if( hHitter == GetMySmartPtr() ) return false;
if( IsDie() ) return false;
CDnActorState::ActorTypeEnum actorType = GetActorType();
if( actorType == CDnActorState::Npc ) return false;
//ActorType [0:All/1:User/2:Monster]
if (pHitSignal)
{
switch(pHitSignal->nActorType)
{
case 1: //User(Àû¿ë ´ë»óÀÌ À¯ÀúÀε¥ ÇöÀç actor°¡ À¯Àú°¡ ¾Æ´Ï¶ó¸é)
{
if (!IsPlayerActor())
return false;
}
break;
case 2: //Monster(Àû¿ë ´ë»óÀÌ ¸ó½ºÅÍ Àε¥ ¸ó½ºÅͰ¡ ¾Æ´Ï¶ó¸é)
{
if (!IsMonsterActor())
return false;
}
break;
}
}
if( GetLastDamageHitUniqueID( hHitter->GetUniqueID() ) != -1 )
{
if( GetLastDamageHitUniqueID( hHitter->GetUniqueID() ) == iHitUniqueID )
if( GetDamageRemainTime( hHitter->GetUniqueID() ) >= LocalTime )
return false;
}
else if( GetDamageRemainTime( hHitter->GetUniqueID() ) >= LocalTime )
{
bool bIsChangedByInputAction = false;
// #69997 ÀÌÀü ¾×¼Ç¿¡¼­ ¹ß»ýÇÑ È÷Æ®½Ã±×³ÎÀÌ ´ÙÀ½¾×¼Ç¿¡µµ ¿µÇâÀ» ¹ÌÄ¡´Â ºÎºÐ ¼öÁ¤.
if( m_nLastDamageHitterActionIndex > 0 && m_nLastDamageHitterActionIndex != hHitter->GetCurrentActionIndex() )
{
if( hHitter->GetProcessSkill() )
{
bIsChangedByInputAction = hHitter->GetProcessSkill()->IsChainInputAction( hHitter->GetCurrentAction() );
}
}
if( bIsChangedByInputAction == false && hHitter->IsOnSignalFromChargerSE() == false )
{
return false;
}
}
// hit ½Ã±×³Î ±¸°£°ú ÆÀ¸¸ Á¦´ë·Î üũµÈ´Ù¸é 149¹ø ¾óÀ½°¨¿Á »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é ¹«Á¶°Ç ¸Âµµ·Ï µÈ´Ù. //
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_149 ) && pHitSignal )
{
//¾óÀ½°¨¿ÁÀÌ´õ¶óµµ »óÅÂÈ¿°ú ÇÊÅͰ¡ Àû¿ë µÇ¾î ÀÖÀ¸¸é ¸ÕÀú ÇÊÅÍ Àû¿ë üũ
if( pHitSignal->StateEffectFilter != 0 )
{
// ÇöÀç ¿¤¸®¸àÅ»·ÎµåÀÇ ¾ÆÀ̽à ÇÁ·¢¼Ç¿¡¼­¸¸ ¿¹¿ÜÀûÀ¸·Î 2°¡ÁöÀÇ »óÅÂÈ¿°ú ÇÊÅ͸µÀ» °É°í Àִµ¥
// µÑ Áß¿¡ Çϳª¸¸ hit µÇ±æ ¿øÇϱ⠶§¹®¿¡ ¸ÕÀú üũµÈ °ÍÀº ´ÙÀ½ ÇÊÅ͸µ¿¡ °É¸®Áö ¾Êµµ·Ï ÇÑ´Ù. #28747
// ¿¹¿Ü Á¶°Ç¿¡ °É¸®Áö ¾ÊÀ¸¸é ÀϹÝÀûÀ¸·Î ó¸®ÇÔ.
if( false == hHitter->CheckHitSignalStateEffectFilterException( GetUniqueID(), pHitSignal->StateEffectFilter) )
{
return false;
}
else
if( false == m_pStateBlow->IsApplied( (STATE_BLOW::emBLOW_INDEX)pHitSignal->StateEffectFilter ) )
{
return false;
}
}
int nOriginalTeam = GetOriginalTeam();
int nHitterTeam = hHitter->GetTeam();
//¾óÀ½ °¨¿Á »óÅ¿¡¼­´Â Àû¿¡°Ô´Â ¸ÂÀ¸¸é ¾ÈµÇ°í, ¾Æ±º¿¡°Ô´Â ¸Â¾Æ¾ß ÇÑ´Ù.??
if (nOriginalTeam != nHitterTeam)
return false;
else
{
//Àû¿¡°Ô ¶§¸®´Â °æ¿ì Àε¥.. ÀڽŠÀ̶ó¸é
if (pHitSignal->nTargetType == 0 && GetMySmartPtr() == hHitter->GetMySmartPtr() )
return false;
//¾óÀ½ °¨¿Á »óÅ¿¡¼­´Â ¾Æ±º¿¡°Ô´Â ¹«Á¶°Ç ¸Â¾Æ¾ß ÇÑ´Ù..
return true;
}
}
//////////////////////////////////////////////////////////////////////////
// ignorecanhit °¡ ²¨Á®ÀÖ°í ¹«Àû »óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é ¸ÂÁö ¾Ê´Â´Ù.
if( pHitSignal )
{
if( pHitSignal->bIgnoreCanHit == TRUE )
{
DNVector(DnBlowHandle) vBlows;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_099, vBlows );
for( int i = 0; i < (int)vBlows.size(); ++i )
{
if( vBlows[i]->GetFloatValue() == -1 )
return false;
}
}
else if( m_pStateBlow->IsApplied(STATE_BLOW::BLOW_099) )
{
return false;
}
#if !defined(PRE_FIX_73833)
// ¹«°Ô°ª Á¦ÇÑ °ªÀÌ ÀÖ´Ù¸é ÁöÁ¤µÈ ¹«°Ô°ª ÀÌÇϰ¡ µÇ¾úÀ» ¶§¸¸ ¸Â´Â´Ù.
if( 0 < pHitSignal->nWeightValueLimit )
{
if( (float)pHitSignal->nWeightValueLimit < GetWeight() )
return false;
}
#endif
}
else if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_099 ) )
return false;
if( hHitter->GetProcessSkill() )
{
bool bResist = false;
if( !IsHittableSkill( hHitter->GetProcessSkill()->GetClassID() , bResist ) )
{
if( bResist )
{
SendAddSEFail( CDnStateBlow::ADD_FAIL_BY_IMMUNE , STATE_BLOW::BLOW_154 );
}
return false;
}
}
#if defined(PRE_ADD_50923)
//¹«Àû »óÅÂÈ¿°ú Typeº° Àû¿ëÀÌ µÇ¾î ÀÖÀ¸¸é
if ( m_pStateBlow->IsApplied(STATE_BLOW::BLOW_239))
{
DNVector(DnBlowHandle) vResult;
m_pStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_239, vResult);
//¹«Àû Type °ªµéÀ» ¸®½ºÆ®·Î ´ã¾Æ ³õ´Â´Ù.
std::map<int, int> invincibleTypeList;
for( UINT i=0 ; i<vResult.size() ; ++i )
{
DnBlowHandle hBlow = vResult.at( i );
if( !hBlow )
continue;
CDnInvincibleTypeBlow* pInvincibleTypeBlow = static_cast<CDnInvincibleTypeBlow*>(hBlow.GetPointer());
if (NULL == pInvincibleTypeBlow)
continue;
int nInvincibleTypeValue = pInvincibleTypeBlow->GetInvincibleTypeValue();
invincibleTypeList.insert(std::make_pair(nInvincibleTypeValue, nInvincibleTypeValue));
}
if (hHitter->IsAppliedThisStateBlow(STATE_BLOW::BLOW_240))
{
DNVector(DnBlowHandle) vResultImmunByType;
CDnStateBlow *pHitterStateBlow = hHitter->GetStateBlow();
if (pHitterStateBlow)
pHitterStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_240, vResultImmunByType);
for( UINT i=0 ; i<vResultImmunByType.size() ; ++i )
{
DnBlowHandle hBlow = vResultImmunByType.at( i );
if( !hBlow )
continue;
CDnImmuneByType* pImmuneTypeBlow = static_cast<CDnImmuneByType*>(hBlow.GetPointer());
if (NULL == pImmuneTypeBlow)
continue;
int nImmuneTypeValue = pImmuneTypeBlow->GetImmuneTypeValue();
std::map<int, int>::iterator findIter = invincibleTypeList.find(nImmuneTypeValue);
if (findIter != invincibleTypeList.end())
invincibleTypeList.erase(findIter);
}
//¹«Àû Type ¹«½Ã »óÅÂÈ¿°ú·Î ÀüºÎ Á¦°Å°¡ µÇ¾î¾ß HitµÉ ¼ö ÀÖ´Ù.
//¸®½ºÆ®°¡ ³²¾Æ ÀÖ´Ù¸é ¹«½Ã »óÅÂÈ¿°ú°¡ ¾øÀ¸¹Ç·Î HitµÉ ¼ö ¾ø´Ù.
if (invincibleTypeList.empty() == false)
return false;
}
//¹«Àû »óÅÂÈ¿°ú Type ¹«½Ã »óÅÂÈ¿°ú°¡ Hitter¿¡ Àû¿ë µÇ¾î ÀÖÁö ¾ÊÀ¸¸é HitµÉ ¼ö ¾ø´Ù.
else
return false;
}
#endif // PRE_ADD_50923
// ¾×¼ÇÅø¿¡¼­ »óÅÂÈ¿°ú ÇÊÅ͸µÀÌ ÁöÁ¤µÇ¾îÀÖÀ¸¸é üũÇÑ´Ù.
if( pHitSignal )
{
#ifdef PRE_ADD_HITDIRECTION
EtVector3 vDir = *GetPosition() - *hHitter->GetPosition();
EtVec3Normalize( &vDir, &vDir );
switch( pHitSignal->CheckHitDirection )
{
// front
case 1:
{
// ÇǰÝÀÚ°¡ ¶§¸° ³ðÀ» ¹Ù¶óº¸°í ÀÖ´Â °æ¿ì hit ó¸®.
float fDot = EtVec3Dot( &vDir, &(m_Cross.m_vZAxis) );
if( fDot >= -0.1f ) // ¹üÀ§´Â ÇǰÝÀÚ(ÀϹÝÀûÀÎ °æ¿ì Ç÷¹À̾î)¿¡°Ô À¯¸®ÇÏ°Ô ¼³Á¤.
return false;
}
break;
// back
case 2:
{
// ÇǰÝÀÚ°¡ ¶§¸° ³ðÀ» µîÁö°í ÀÖ´Â °æ¿ì hit ó¸®.
float fDot = EtVec3Dot( &vDir, &(m_Cross.m_vZAxis) );
if( fDot < 0.1f )
return false;
}
break;
}
#endif // #ifdef PRE_ADD_HITDIRECTION
#if defined(PRE_ADD_57090)
//////////////////////////////////////////////////////////////////////////
//#57090 ƯÁ¤ ´ë»óÀÌ °ø°Ý´çÇÏÁö ¾Ê°Ô ÇÏ´Â ±â´É - ¼³Á¤µÈ »óÅÂÈ¿°ú°¡ Àû¿ë µÇ¾î ÀÖÀ¸¸é È÷Æ® µÇÁö ¾ÊÀ½.
//StateEffectFilterº¸´Ù ¿ì¼± °Ë»ç...
std::vector<string> vlTokens;
string strArgument = pHitSignal->szUnStateEffectFilter ? pHitSignal->szUnStateEffectFilter : "";
TokenizeA( strArgument, vlTokens, ";" );
if (vlTokens.empty() == false)
{
int nTokenSize = (int)vlTokens.size();
for (int i = 0; i < nTokenSize; ++i)
{
STATE_BLOW::emBLOW_INDEX emBlowIndex = (STATE_BLOW::emBLOW_INDEX)atoi(vlTokens[i].c_str());
if( true == m_pStateBlow->IsApplied( emBlowIndex ) )
{
return false;
}
}
}
//////////////////////////////////////////////////////////////////////////
#endif // PRE_ADD_57090
if( pHitSignal->StateEffectFilter != 0 )
{
// ÇöÀç ¿¤¸®¸àÅ»·ÎµåÀÇ ¾ÆÀ̽à ÇÁ·¢¼Ç¿¡¼­¸¸ ¿¹¿ÜÀûÀ¸·Î 2°¡ÁöÀÇ »óÅÂÈ¿°ú ÇÊÅ͸µÀ» °É°í Àִµ¥
// µÑ Áß¿¡ Çϳª¸¸ hit µÇ±æ ¿øÇϱ⠶§¹®¿¡ ¸ÕÀú üũµÈ °ÍÀº ´ÙÀ½ ÇÊÅ͸µ¿¡ °É¸®Áö ¾Êµµ·Ï ÇÑ´Ù. #28747
// ¿¹¿Ü Á¶°Ç¿¡ °É¸®Áö ¾ÊÀ¸¸é ÀϹÝÀûÀ¸·Î ó¸®ÇÔ.
if( false == hHitter->CheckHitSignalStateEffectFilterException( GetUniqueID(), pHitSignal->StateEffectFilter) )
{
return false;
}
else
if( false == m_pStateBlow->IsApplied( (STATE_BLOW::emBLOW_INDEX)pHitSignal->StateEffectFilter ) )
{
return false;
}
}
#ifdef PRE_ADD_MONSTER_CATCH
// ¸ó½ºÅÍ¿¡ ÀâÈù°ÇÁö üũÇÏ´Â Ç÷¡±×°¡ ÄÑÁ® ÀÖ´Ù¸é ¸ó½ºÅÍ¿¡°Ô ÀâÈù °æ¿ì¸¸ ±¸ºÐ.
if( TRUE == pHitSignal->bIsCatchedActor )
{
if( IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(this);
if( false == pPlayerActor->IsCatchedByMonster() )
{
return false;
}
}
}
#endif // #ifdef PRE_ADD_MONSATER_CATCH
// ÁÖº¯¿¡ ³»°¡ ¼ÒȯÇÑ ·¼¸¯ ¸ó½ºÅÍÀÎÁö ¾Æ´ÑÁö ±¸ºÐÇØÁÜ. ¼îÅ© ¿Àºê ·¼¸¯ ½ºÅ³¿¡¼­ »ç¿ëÇÔ.
if( TRUE == pHitSignal->bUseMyRelicFilter )
{
bool bIsMyRelicMonster = hHitter->IsMyRelicMonster( GetMySmartPtr() );
if( bIsMyRelicMonster )
return true;
else
return false;
}
// #13885 À̽´ °ü·Ã.
int nTargetType = pHitSignal->nTargetType;
if( hHitter->IsAppliedThisStateBlow( STATE_BLOW::BLOW_086 ) )
{
// ÆÀ ¹ÝÀü »óÅÂÈ¿°ú Çϳª¸¸ Àû¿ëµÈ´Ù.
DNVector( DnBlowHandle ) vlReverseTeamBlows;
hHitter->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_086, vlReverseTeamBlows );
_ASSERT( false == vlReverseTeamBlows.empty() );
if( false == vlReverseTeamBlows.empty() )
{
DnBlowHandle hBlow = vlReverseTeamBlows.front();
CDnReverseTeamBlow* pReverseTeamBlow = static_cast<CDnReverseTeamBlow*>(hBlow.GetPointer());
if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_CHANGE == pReverseTeamBlow->GetType() )
{
switch( nTargetType )
{
case 0: // Enemy -> Friend
nTargetType = 1;
break;
case 1: // Friend -> Enemy
{
// #50166 Æø¹ß°ü·Ã ½Ã±×³ÎÀº ±âÁ¸»óŸ¦ À¯ÁöÇϵµ·Ï ÇÑ´Ù.
if(pHitSignal->fDamageProb > 0)
nTargetType = 1;
else
nTargetType = 0;
}
break;
case 2: // All -> All
{
// #51871 À̽´°ü·Ã All ŸÀÔÀÏ °æ¿ì¿¡µµ µ¥¹ÌÁö°¡ Àִ°æ¿ì ¿µÇâÀ» ³¢Ä¡Áö ¾Êµµ·Ï ¼³Á¤ÇÕ´Ï´Ù.
if(pHitSignal->fDamageProb > 0)
nTargetType = 1;
}
break;
}
}
else
if( CDnReverseTeamBlow::HIT_SIGNAL_TARGET_ALL == pReverseTeamBlow->GetType() )
{
// Ÿ°Ý´ë»ó all ·Î ¹Ù²ãÁÜ.
nTargetType = 2;
}
}
}
switch( nTargetType )
{
case 0: // Enemy
if( GetTeam() == hHitter->GetTeam() ) return false;
if( GetMySmartPtr() == hHitter->GetMySmartPtr() ) return false;
if( false == pHitSignal->bIgnoreCanHit &&
false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_138 ) )
{
if( !CDnActorState::IsHittable() )
return false;
}
break;
case 1: // Friend
if( GetTeam() != hHitter->GetTeam() ) return false;
#ifdef PRE_FIX_63315
// #63315 - TargetType ÀÌ Friend ÀÏ °æ¿ì¿¡µµ Hittable °Ë»çÇϵµ·Ï Ãß°¡.
if( false == pHitSignal->bIgnoreCanHit &&
false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_138 ) )
{
if( !CDnActorState::IsHittable() )
return false;
}
#endif // PRE_FIX_63315
break;
case 2: // All
// CanHit ½Ã±×³ÎÀÌ false ÀÏ ¶§ hit ½Ã±×³Î targettype ÀÌ all ÀÌ¶óµµ Àû±ºÀº hit µÇÁö ¾Êµµ·Ï ¼öÁ¤. (#10570)
if( GetTeam() != hHitter->GetTeam() )
{
// Hit ½Ã±×³Î¿¡ CanHit ¹«½ÃÇÏ´Â Ç÷¡±× ÄÑÁ® ÀÖÀ¸¸é ¹«Á¶°Ç ¸ÂÀ» ¼ö ÀÖ´Â »óÅ·ΠÆÇ´Ü.
// 138¹ø »óÅÂÈ¿°ú °É·ÈÀ» ¶§µµ ¸¶Âù°¡Áö. (#19619)
if( false == pHitSignal->bIgnoreCanHit &&
false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_138 ) )
{
if( !CDnActorState::IsHittable() )
return false;
}
}
break;
}
switch( pHitSignal->nStateCondition )
{
case 0: // Normal
if( GetState() == CDnActorState::Down ) return false;
break;
case 1: // Down
if( !( GetState() & CDnActorState::Down ) ) return false;
break;
case 2: // Normal + Down
break;
case 3: // All
break;
}
}
return true;
}
bool CDnActor::IsHittableSkill( int iSkillIndex , bool &bSendResist )
{
// ƯÁ¤ ½ºÅ³¿¡ ´ëÇÑ ¹«Àû ó¸® [2010/11/22 semozz]
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_154 ) )
{
DNVector(DnBlowHandle) vResult;
m_pStateBlow->GetStateBlowFromBlowIndex(STATE_BLOW::BLOW_154, vResult);
for( UINT i=0 ; i<vResult.size() ; ++i )
{
DnBlowHandle hBlow = vResult.at( i );
if( hBlow )
{
CDNInvincibleAtBlow* pInvincibleAtBlow = static_cast<CDNInvincibleAtBlow*>(hBlow.GetPointer());
if ( pInvincibleAtBlow && pInvincibleAtBlow->IsInvincibleAt(iSkillIndex) )
{
bSendResist = pInvincibleAtBlow->IsEnableSendResist();
return false;
}
}
}
}
return true;
}
void CDnActor::Show( bool bShow )
{
m_bShow = bShow;
}
void CDnActor::ResetActor()
{
Show( true );
m_fDownDelta = 0.f;
m_fDieDelta = 0.f;
m_fStiffDelta = 0.f;
m_mapLastDamageTime.clear();
m_mapLastHitUniqueID.clear();
m_nLastDamageHitterActionIndex = 0;
m_LastHitSignalTime = 0;
m_nLastHitSignalIndex = -1;
m_bModifyPlaySpeed = false;
m_PlaySpeedStartTime = 0;
m_dwPlaySpeedTime = 0;
m_bEnableNormalSuperAmmor = false;
m_nNormalSuperAmmorTime = 0;
m_fBreakNormalSuperAmmorDurability = 0.f;
// CDnActionBase::SetFPS( 60.f );
CDnActionBase::ResetActionBase();
MAActorRenderBase::ResetActorRenderBase();
ResetMove();
ResetLook();
SetVelocity( EtVector3( 0.f, 0.f, 0.f ) );
SetResistance( EtVector3( 0.f, 0.f, 0.f ) );
SetAddHeight( 0.f );
SetMagnetLength( 0.f );
SetMagnetDir( EtVector2( 0.f, 0.f ) );
m_vlForceSettedHitElement.clear();
if( IsCustomAction() ) ResetCustomAction();
SetActionQueue( "Stand", 0, 0.f, 0.f, false, false );
}
void CDnActor::ProcessCollision( EtVector3 &vMove )
{
m_pMovement->PushAndCollisionCheck( vMove );
}
void CDnActor::ProcessState( LOCAL_TIME LocalTime, float fDelta )
{
CDnActorState::ProcessState( LocalTime, fDelta );
// #48950 ½´¸Ó¾Æ¸Ó°¡ ±úÁø °æ¿ì¿£ MoveY ½Ã±×³Î °ª ¸®¼ÂÇØÁØ´Ù.
if( IsHit() )
{
ResetMoveYDistance();
}
if( m_pStateBlow &&
false == IsNpcActor() )
{
m_pStateBlow->Process( LocalTime, fDelta );
ProcessReservedRemoveBlows();
ExecuteKillAfterProcessStateBlow();
}
}
void CDnActor::SendAddSEFail( int iAddSEResult, STATE_BLOW::emBLOW_INDEX emBlowIndex )
{
BYTE pBuffer[ 16 ];
CPacketCompressStream Stream( pBuffer, 16 );
Stream.Write( &iAddSEResult, sizeof(int) );
Send( eActor::SC_ADD_STATE_EFFECT_DENIED, &Stream );
}
void CDnActor::PushSummonMonster( DnMonsterActorHandle hMonster, const SummonMonsterStruct* pSummonMonsterStruct, bool bReCreateFollowStageMonster/* = false*/ )
{
//if( bReCreateFollowStageMonster )
// return;
if( 0 == pSummonMonsterStruct->nGroupID )
{
m_listSummonMonster.push_back( hMonster );
}
}
bool CDnActor::bIsCanSummonMonster( const SummonMonsterStruct* pSummonMonsterStruct )
{
// 0 ÀÌ¸é °³Ã¼¼ö Á¦ÇÑÀ» ÇÏÁö ¾Ê°Ú´Ù´Â °ÍÀÓ~!
if( pSummonMonsterStruct->nMaxCount == 0 )
return true;
// ±×·ì ID °¡ Á¤ÀǵǾî ÀÖ´Ù¸é ±×·ì map ÀÇ ¸®½ºÆ®¸¦ ã¾Æ¼­ ó¸®.
int iCount = 0;
if( IsPlayerActor() && 0 < pSummonMonsterStruct->nGroupID )
{
if( 0 < m_mapSummonMonsterByGroup.count( pSummonMonsterStruct->nGroupID ) )
{
std::list<DnMonsterActorHandle>& listSummonedGroupMonster = m_mapSummonMonsterByGroup[ pSummonMonsterStruct->nGroupID ];
for( std::list<DnMonsterActorHandle>::iterator itor=listSummonedGroupMonster.begin(); itor!=listSummonedGroupMonster.end(); )
{
DnMonsterActorHandle hMonster = *itor;
if( hMonster )
{
++iCount;
++itor;
}
else
itor = listSummonedGroupMonster.erase( itor );
}
if( iCount < pSummonMonsterStruct->nMaxCount )
return true;
}
else
return true;
}
else
{
for( std::list<DnMonsterActorHandle>::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end() ; )
{
DnMonsterActorHandle hMonster = *itor;
if( hMonster )
{
if( hMonster->GetMonsterClassID() == pSummonMonsterStruct->MonsterID )
++iCount;
++itor;
}
else
itor = m_listSummonMonster.erase( itor );
}
if( iCount < pSummonMonsterStruct->nMaxCount )
return true;
}
return false;
}
int CDnActor::AddStateBlow( STATE_BLOW::emBLOW_INDEX emBlowIndex, const CDnSkill::SkillInfo* pParentSkill,
int nDurationTime, const char *szParam, bool bOnPlayerInit/* = false*/, bool bCheckCanBegin/* = true*/ , bool bEternity /*=false*/ )
{
// ºÎȰ Á¦¿ÜÇϰí Á×¾úÀ» ¶© »óÅÂÈ¿°ú Ãß°¡ ¾ÈµÊ
// PvP ¶ó¿îµå¸ðµå ¶ó¿îµå Àç½ÃÀ۽à Á×Àº»óÅ¿¡¼­ »óÅÂÈ¿°ú¸¦ °É¾îÁÙ¶§ bOnPlayerInit = true ·Î ³Ñ¾î¿Í¼­ Die üũ ¾ÈÇÔ. by ±è¹ä
if( false == bOnPlayerInit )
if( IsDie() && STATE_BLOW::emBLOW_INDEX::BLOW_057 != emBlowIndex ) return -1;
if( !m_pStateBlow ) return -1;
int iAddSEResult = m_pStateBlow->CanAddThisBlow( pParentSkill, emBlowIndex );
switch( iAddSEResult )
{
case CDnStateBlow::ADD_FAIL_BY_IMMUNE:
{
// ½ÇÆÐÇÑ ÀÌÀ¯¿¡ µû¶ó..
SendAddSEFail( iAddSEResult, emBlowIndex );
return -1;
}
break;
case CDnStateBlow::ADD_FAIL_BY_DIED:
OutputDebug( "[Add State Effect Failed by die]\n" );
return -1;
case CDnStateBlow::ADD_FAIL_BY_INVINCIBLE:
OutputDebug( "[Add State Effect Failed by Invincible]\n" );
return -1;
case CDnStateBlow::ADD_FAIL_BY_REVIVAL:
OutputDebug( "[Add State Effect Failed by Revival blow!]\n" );
return -1;
case CDnStateBlow::ADD_FAIL_BY_GUILDBLOW_PRIORITY:
return -1;
case CDnStateBlow::ADD_FAIL_BY_PROB_SKILL_INVINCIBLE:
OutputDebug( "[Add State Effect Failed by Prob Skill Invincible]\n" );
return -1;
case CDnStateBlow::ADD_FAIL_BY_COMBOLIMITBLOW:
OutputDebug( "[Add State Effect Failed by ComboLimitBlow]\n" );
return -1;
}
//¼Óµµ¸¦ º¯°æÇÏ´Â È¿°ú Àû¿ëµÉ¶§ AccelÈ¿°ú ÀÌ¹Ì Àû¿ë µÇ¾î ÀÖ´Ù¸é
//AccelÈ¿°ú´Â Á¦°Å(STATE_END?)µÈ´Ù..
switch(emBlowIndex)
{
case STATE_BLOW::BLOW_076:
case STATE_BLOW::BLOW_025:
case STATE_BLOW::BLOW_144:
{
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_220))
{
DNVector(DnBlowHandle) vlhFrameBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_220, vlhFrameBlows );
for( int i = 0; i < (int)vlhFrameBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhFrameBlows.at(i);
if (hBlow)
hBlow->SetState(STATE_BLOW::STATE_END);
}
}
}
break;
}
#if defined(PRE_ADD_50923)
//240»óÅÂÈ¿°ú´Â Çϳª¾¿¸¸ Àû¿ëµÇ¾î¾ß ÇÑ´Ù. »õ·Î¿î 240¹ø »óÅÂÈ¿°ú°¡ µé¾î ¿À¸é ±âÁ¸°Å
//Á¦°Å Çϵµ·ÏÇÑ´Ù.
if (emBlowIndex == STATE_BLOW::BLOW_240)
{
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_240))
{
DNVector(DnBlowHandle) vlhFrameBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_240, vlhFrameBlows );
for( int i = 0; i < (int)vlhFrameBlows.size(); ++i )
{
DnBlowHandle hBlow = vlhFrameBlows.at(i);
if (hBlow)
hBlow->SetState(STATE_BLOW::STATE_END);
}
}
}
#endif // PRE_ADD_50923
DnBlowHandle hBlow = m_pStateBlow->CreateStateBlow( GetMySmartPtr(), pParentSkill, emBlowIndex, nDurationTime, szParam );
if( !hBlow )
return -1;
// È®·üÀÌ ÀÖ´Â »óÅÂÈ¿°ú´Â È®·ü¿¡ °É¸®¸é »óÅÂÈ¿°ú ¾È °É¸².
// Ŭ¶óÂÊ¿¡µµ ¿Ö »óÅÂÈ¿°ú Ãß°¡°¡ ½ÇÆÐÇß´ÂÁö ÀÌÀ¯´Â ¾Ë¾Æ¾ß ÇϹǷΠÀÌÀ¯¸¦ ÆÐŶÀ¸·Î º¸³»ÁÜ.
if( bCheckCanBegin && (false == hBlow->CanBegin()) )
{
SendAddSEFail( CDnStateBlow::ADD_FAIL_BY_PROBABILITY, emBlowIndex );
//hBlow->Release();
#if defined(PRE_FIX_49208)
//#49208 ÀÌ¹Ì Àû¿ëµÈ »óÅÂÈ¿°ú°¡ OnBeginÀÌ È£Ãâ µÈ »óÅ¿¡¼­ DuplicatedµÈ »óÅÂÈ¿°ú¸¦ ¿©±â¿¡¼­ ¹Ù·Î DeleteÇØ ¹ö¸®¸é referenceÄ«¿îÆ®°¡ ¾î±ß³ª°Ô µÊ.
if (hBlow->IsDuplicated() == false)
#endif // PRE_FIX_49208
SAFE_RELEASE_SPTR( hBlow );
OutputDebug( "[Add State Effect Failed by probability fail!] BlowIndex: %d\n", emBlowIndex );
return -1;
}
else
{
if( hBlow->IsDuplicated() )
return hBlow->GetBlowID();
else
{
hBlow->SetParentSkillInfo( pParentSkill );
//hBlow->SetParentSkillID( iParentSkillID );
//hBlow->SetParentSkillLevelID( iParentSkillLevelID );
// ¹«Àû »óÅÂÈ¿°ú µé¾î°¡¸é µ¶, ºÒ »óÅÂÈ¿°ú´Â Á¦°ÅÇÑ´Ù..
if( hBlow->GetBlowIndex() == STATE_BLOW::BLOW_099 )
{
// È­»ó°ú Áßµ¶ »óÅÂÈ¿°ú¸¦ Á¦°Å.
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_042 ) ||
IsAppliedThisStateBlow( STATE_BLOW::BLOW_044 ) )
{
DNVector(DnBlowHandle) vlBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_042, vlBlows );
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_044, vlBlows );
for( int i = 0; i < (int)vlBlows.size(); ++i )
{
DnBlowHandle hBlow = vlBlows.at( i );
int iBlowID = hBlow->GetBlowID();
CmdRemoveStateEffectFromID( iBlowID );
}
}
}
hBlow->SetEternity( bEternity );
return m_pStateBlow->AddStateBlow( hBlow );
}
}
}
void CDnActor::DelStateBlow( STATE_BLOW::emBLOW_INDEX emBlowIndex )
{
if( !m_pStateBlow ) return;
m_pStateBlow->RemoveStateBlowByBlowDefineIndex( emBlowIndex );
}
int CDnActor::RemoveStateBlowByBlowDefineIndex( STATE_BLOW::emBLOW_INDEX emBlowIndex )
{
if( !m_pStateBlow ) return -1;
return m_pStateBlow->RemoveStateBlowByBlowDefineIndex( emBlowIndex );
}
void CDnActor::RemoveStateBlowFromID( int nStateBlowID )
{
if( !m_pStateBlow ) return;
m_pStateBlow->RemoveStateBlowFromID( nStateBlowID );
}
void CDnActor::RemoveAllBlow()
{
DNVector(DnBlowHandle) vlAppliedStateBlow;
GetAllAppliedStateBlow( vlAppliedStateBlow );
int iNumStateBlow = (int)vlAppliedStateBlow.size();
for( int iBlow = 0; iBlow < iNumStateBlow; ++iBlow )
m_pStateBlow->RemoveStateBlowFromID( vlAppliedStateBlow.at( iBlow )->GetBlowID() );
ApplyPassiveSkills();
}
void CDnActor::RemoveAllBlowExpectPassiveSkill()
{
DNVector(DnBlowHandle) vlAppliedStateBlow;
GetAllAppliedStateBlow( vlAppliedStateBlow );
int iNumStateBlow = (int)vlAppliedStateBlow.size();
for( int iBlow = 0; iBlow < iNumStateBlow; ++iBlow )
{
DnBlowHandle hBlow = vlAppliedStateBlow.at( iBlow );
if( !hBlow )
continue;
if( bIsPassiveSkill( hBlow ) )
continue;
// ±Ù¿ø ¾ÆÀÌÅÛÀÇ È®·ü ½ºÅ³ ¹«½Ã »óÅÂÈ¿°ú´Â Á׾ ³²¾ÆÀÖ¾î¾ß ÇÑ´Ù.
if( IsShouldRemainBlowWhenDie( hBlow ) )
continue;
m_pStateBlow->RemoveStateBlowFromID( hBlow->GetBlowID() );
}
}
bool CDnActor::IsShouldRemainBlowWhenDie( DnBlowHandle hBlow )
{
bool bResult = false;
if( hBlow )
{
if( hBlow->IsFromSourceItem() )
return true;
if( hBlow->IsEternity() )
return true;
}
return bResult;
}
int CDnActor::GetNumAppliedStateBlow( void )
{
return m_pStateBlow->GetNumStateBlow();
}
DnBlowHandle CDnActor::GetAppliedStateBlow( int iIndex )
{
return m_pStateBlow->GetStateBlow( iIndex );
}
bool CDnActor::IsAppliedThisStateBlow( STATE_BLOW::emBLOW_INDEX iBlowIndex )
{
if( !m_pStateBlow )
return false;
return m_pStateBlow->IsApplied( iBlowIndex );
}
void CDnActor::GetAllAppliedStateBlow(DNVector(DnBlowHandle)& /*IN OUT*/ out)
{
int nSize = m_pStateBlow->GetNumStateBlow();
if( 0 < nSize ) out.reserve( out.capacity() + nSize ); // 20080916 ¼º´É°³¼±
for ( int i = 0 ; i < nSize ; i++ )
{
DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i);
if( hBlow && STATE_BLOW::STATE_END != hBlow->GetBlowState() )
out.push_back(hBlow);
}
}
void CDnActor::GetAllAppliedStateBlowBySkillID(int nSkillID, DNVector(DnBlowHandle)& /*IN OUT*/ out)
{
int nSize = m_pStateBlow->GetNumStateBlow();
if( 0 < nSize ) out.reserve( out.capacity() + nSize ); // 20080916 ¼º´É°³¼±
for ( int i = 0 ; i < nSize ; i++ )
{
DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i);
if( hBlow )
{
const CDnSkill::SkillInfo* pSkillinfo = hBlow->GetParentSkillInfo();
if( pSkillinfo && pSkillinfo->iSkillID == nSkillID &&
STATE_BLOW::STATE_END != hBlow->GetBlowState() )
{
out.push_back(hBlow);
}
}
}
}
void CDnActor::GatherAppliedStateBlowByBlowIndex( STATE_BLOW::emBLOW_INDEX BlowIndex, DNVector(DnBlowHandle)& /*IN OUT*/ out )
{
int iNumStateBlow = m_pStateBlow->GetNumStateBlow();
for( int i = 0; i < iNumStateBlow; ++i )
{
DnBlowHandle hBlow = m_pStateBlow->GetStateBlow( i );
if( hBlow && hBlow->GetBlowIndex() == BlowIndex &&
STATE_BLOW::STATE_END != hBlow->GetBlowState() )
out.push_back( hBlow );
}
}
void CDnActor::OnSkillProjectile( CDnProjectile *pProjectile )
{
MASkillUser::OnSkillProjectile( pProjectile );
if( pProjectile )
{
if( IsProcessSkill() || IsEnabledToggleSkill() )
{
DnSkillHandle hSkill;
if( IsProcessSkill() )
hSkill = m_hProcessSkill;
else
if( IsEnabledToggleSkill() )
hSkill = GetEnabledToggleSkill();
_ASSERT( hSkill && "ÇÁ·ÎÁ§Å¸ÀÏÀ» ½ð ½ºÅ³ÀÌ ¾ø´Ù´Â?" );
pProjectile->SetParentSkill( hSkill );
for( DWORD i = 0; i < hSkill->GetStateEffectCount(); i++ )
{
CDnSkill::StateEffectStruct *pStruct = hSkill->GetStateEffectFromIndex(i);
if( pStruct->ApplyType == CDnSkill::ApplySelf ) continue;
pProjectile->AddStateEffect( *pStruct );
}
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_167 ) )
{
DNVector(DnBlowHandle) vlBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_167, vlBlows );
if( false == vlBlows.empty() )
{
int iForceSkillLevel = (int)vlBlows.front()->GetFloatValue();
pProjectile->SetSummonMonsterForceSkillLevel( iForceSkillLevel );
}
}
//////////////////////////////////////////////////////////////////////////
//¾Ö¾î·Î »þ¿ö ½ºÅ³¿¡ »ç¿ëµÉ »óÅÂÈ¿°ú 󸮸¦ À§Çؼ­ ¹ß»çü°¡ »ý¼º µÉ¶§ ÇöÀç ½ºÅ³ÀÌ ½ÃÀü ÁßÀÎ °æ¿ì ÇØ´ç ½ºÅ³¿¡ ¹ß»çü¸¦ ´ã¾Æ ³õ´Â´Ù.
//ÇöÀç »ç¿ëÁßÀÎ ½ºÅ³ÀÌ 242»óÅÂÈ¿°ú¸¦ °¡Áö°í ÀÖ´Â ½ºÅ³À̸é
if (hSkill)
{
bool bExistState = false;
int nStateEffectCount = hSkill->GetStateEffectCount();
for (int i = 0; i < nStateEffectCount; ++i)
{
CDnSkill::StateEffectStruct* pSE = hSkill->GetStateEffectFromIndex( i );
if (pSE && (STATE_BLOW::emBLOW_INDEX)pSE->nID == STATE_BLOW::BLOW_242)
{
bExistState = true;
break;
}
}
if (bExistState == true)
{
LOCAL_TIME skillStartTime = hSkill->GetSkillStartTime();
pProjectile->SetSkillStartTime(skillStartTime); //¹ß»çü¿¡µµ ½ºÅ³ ½ÃÀÛ ½Ã°£À» ¼³Á¤ ÇØ³õ´Â´Ù.
hSkill->AddProjectile(pProjectile);
}
}
}
#if defined(PRE_FIX_68645)
//129¹ø »óÅÂÈ¿°ú°¡ ÀÖ°í, °­Á¦ ¼Ó¼º ¼³Á¤ÀÌ ÀÖ´Â °æ¿ì ¹ß»çü¿¡ ¼³Á¤ ÇØ ³õ´Â´Ù.
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_129 ) )
{
DNVector(DnBlowHandle) vlhChangeActionSetBlow;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_129, vlhChangeActionSetBlow );
// ¾×¼Ç ¼Â º¯°æ »óÅÂÈ¿°ú´Â ¿©·¯°³ ÀÖÀ» ¼ö ÀÖ´Ù.
int iNumBlow = (int)vlhChangeActionSetBlow.size();
for( int i = 0; i < iNumBlow; ++i )
{
if( !vlhChangeActionSetBlow[i] )
continue;
CDnChangeActionSetBlow* pChangeActionSetBlow = static_cast<CDnChangeActionSetBlow*>( vlhChangeActionSetBlow.at(i).GetPointer() );
if (pChangeActionSetBlow->IsEnable() == true)
{
CDnChangeActionStrProcessor* pProcessor = pChangeActionSetBlow->GetChangeActionStrProcessor(); // ¾×¼Ç º¯°æ ¹ßÇöŸÀÔÀÌ ºñȰ¼ºÈ­ »óÅÂÀ϶§´Â NULL ¸®ÅϵÊ.
if( pProcessor && m_vlForceSettedHitElement.empty() == false)
{
ElementEnum forceElement = (ElementEnum)m_vlForceSettedHitElement[0];
pProjectile->SetForceHitElement(forceElement);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // PRE_FIX_68645
}
}
void CDnActor::OnInitializeNextStage( void )
{
// ÁøÇàÁßÀÎ ÆÐ½Ãºê ¾×¼Ç ½ºÅ³Àº ²¨¹ö¸²
if( m_hProcessSkill )
{
if( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) &&
m_hProcessSkill->GetDurationType() == CDnSkill::Instantly )
{
m_hProcessSkill->OnEnd( 0, 0.0f );
m_hProcessSkill.Identity();
}
}
// ÁøÇàÁßÀÎ ¿À¶ó ½ºÅ³ ¿ª½Ã ²¨¹ö¸²
if( m_hAuraSkill )
{
OnSkillAura( m_hAuraSkill, false );
}
// °áºù »óÅÂÈ¿°ú °É·Á ÀÖ´Âä·Î À̵¿µÇ´Â °æ¿ì´Â °ÅÀÇ ¾ø°ÚÁö¸¸ ¸¸¾à ±×·¸´Ù¸é Á¦°ÅÇÔ.
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_041 ) )
m_pStateBlow->RemoveStateBlowByBlowDefineIndex( STATE_BLOW::BLOW_041 );
RemoveNonAvailableStateBlow();
// Note: ¸Ê À̵¿µÉ ¶§ È£ÃâµÊ. ¸¶Áö¸·À¸·Î ¶§·È´ø ³ðµé ¸®½ºÆ®¸¦ À̰÷¿¡¼­ ÃʱâÈ­ÇØÁÖÁö ¾ÊÀ¸¸é ÀÌÀü ½ºÅ×ÀÌÁö¿¡¼­
// ¶§·È´ø ¾ÖµéÀÌ ³²¾ÆÀÖÀ» ¼ö ÀÖ´Ù. ±×·± »óȲ¿¡¼­ Hit ÇÁ·Î¼¼½º°¡ ÇÔ µ¹¾Æ°¡¸é »¶³².
m_hVecLastHitList.clear();
m_hVecLastHitListByRemainTime.clear();
m_iCantMoveReferenceCount = 0;
m_iCantActionReferenceCount = 0;
// ¸¶Áö¸· Ÿ°ÝµÈ È÷Æ®½Ã±×³Î °ü·Ã Á¤º¸ ¾÷µ¥ÀÌÆ®
m_mapLastDamageTime.clear();
m_mapLastHitUniqueID.clear();
m_nLastDamageHitterActionIndex = 0;
RefreshState();
}
// ¿©±â ÇÔ¼ö ³»¿ëÀÌ ¹Ù²î¸é Ŭ¶óÀÌ¾ðÆ®¿¡¼­µµ SC_START_PVPROUND ÆÐŶ 󸮺κРº¯°æµÇ¾î¾ßÇÑ´Ù.
void CDnActor::OnInitializePVPRoundRestart( void )
{
// ÁøÇàÁßÀÎ ÆÐ½Ãºê ¾×¼ÇÀÌ ÀÖ´Ù¸é Á¾·á.
if( m_hProcessSkill )
{
if( (m_hProcessSkill->GetSkillType() == CDnSkill::Passive || m_hProcessSkill->GetSkillType() == CDnSkill::AutoPassive) &&
m_hProcessSkill->GetDurationType() == CDnSkill::Instantly )
{
m_hProcessSkill->OnEnd( 0, 0.0f );
m_hProcessSkill.Identity();
}
}
// ÁøÇàÁßÀÎ AutoPassive ½ºÅ³ Á¾·á.
EndAutoPassiveSkill( CDnActionBase::m_LocalTime, 0.0f );
// ¾ÆÀÌÅÛ½ºÅ³ Á¾·á
if( m_hItemSkill )
{
if( m_hItemSkill->IsFinished() )
{
m_hItemSkill->OnEnd( 0, 0.f );
deque<DnSkillHandle>::iterator iter = find( m_dqhItemSkillList.begin(), m_dqhItemSkillList.end(), m_hItemSkill );
_ASSERT( m_dqhItemSkillList.end() != iter );
m_dqhItemSkillList.erase( iter );
SAFE_RELEASE_SPTR( m_hItemSkill );
}
}
// ÁøÇàÁßÀÎ ¿À¶ó ½ºÅ³ÀÌ ÀÖ´Ù¸é Á¾·á.
if( m_hAuraSkill )
{
OnSkillAura( m_hAuraSkill, false );
}
// ÁøÇàÁßÀÎ Åä±Û ½ºÅ³ÀÌ ÀÖ´Ù¸é Á¾·á.
if( m_hToggleSkill )
{
OnSkillToggle( m_hToggleSkill, false );
}
// ¸ðµç »óÅÂÈ¿°ú ¸®¼Â
RemoveAllBlowExpectPassiveSkill();
if( IsPlayerActor() )
{
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor*>(this);
pPlayer->RemoveAllBubbles( false );
}
m_hVecLastHitList.clear();
m_hVecLastHitListByRemainTime.clear();
// ¸¶Áö¸· ¶§·È´ø È÷Æ®½Ã±×³Î Á¤º¸ ¾÷µ¥ÀÌÆ®
m_mapLastDamageTime.clear();
m_mapLastHitUniqueID.clear();
m_nLastDamageHitterActionIndex = 0;
for( std::list<DnMonsterActorHandle>::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end() ; itor++ )
{
DnMonsterActorHandle hMonster = *itor;
if( hMonster ) hMonster->CmdSuicide( false, false );
}
SAFE_DELETE_VEC( m_listSummonMonster );
std::list<DnMonsterActorHandle> suicideMonsterList;
map<int, list<DnMonsterActorHandle> >::iterator iter = m_mapSummonMonsterByGroup.begin();
for( iter; iter != m_mapSummonMonsterByGroup.end(); ++iter )
{
// Á¦ÇÑ ½Ã°£ ´Ù µÇ¾î È¥ÀÚ »ç¶óÁø ¼Òȯ ¸ó½ºÅÍ´Â ¸®½ºÆ®¿¡ invalidÇÑ Çڵ鸸 ³²¾Æ ÀÖÀ¸¹Ç·Î °¨¾È.
list<DnMonsterActorHandle>& listSummonedMonsters = iter->second;
list<DnMonsterActorHandle>::iterator iterList = listSummonedMonsters.begin();
for( iterList; iterList != listSummonedMonsters.end(); )
{
if( *iterList )
{
DnMonsterActorHandle hMonster = *iterList;
//CmdSuicideÇÔ¼ö ³»ºÎ¿¡¼­ PlayerActor::OnDieSummonedMonsterÈ£ÃâµÊ.
//ÀÌ ÇÔ¼ö¿¡¼­ m_mapSummonMonsterByGroup/listSummonMonster¸®½ºÆ®¿¡¼­ Á¦°ÅÇÔ.
//±×·¡¼­ CmdSuicideµÉ ³à¼®µéÀ» ¸®½ºÆ®¿¡ ´ã¾Æ¼­ ¾Æ·¡ÂÊ¿¡¼­ ó¸® Çϵµ·Ï ÇÔ..
//hMonster->CmdSuicide( false, false );
suicideMonsterList.push_back(hMonster);
++iterList;
}
else
{
iterList = listSummonedMonsters.erase( iterList );
}
}
}
//À§¿¡¼­ ¸®½ºÆ®¿¡ ´ã¾Æ ³õÀº CmdSuicideµÉ ³à¼®µé ó¸®ÇÑ´Ù.
for( std::list<DnMonsterActorHandle>::iterator itor=suicideMonsterList.begin() ; itor!=suicideMonsterList.end() ; itor++ )
{
DnMonsterActorHandle hMonster = *itor;
if( hMonster ) hMonster->CmdSuicide( false, false );
}
m_mapSummonMonsterByGroup.clear();
}
void CDnActor::ResetStateEffect( int nSkillDurationType )
{
m_pStateBlow->ResetStateBlowBySkillType( nSkillDurationType );
}
void CDnActor::ProcessPress()
{
if( m_nPressLevel == 0 ) return;
if( IsDie() ) return;
if( IsFly() ) return;
if( IsUnderGround() ) return;
DNVector(DnActorHandle) hVecList;
if( m_iLastProcessPressCount > 0 )
hVecList.reserve( m_iLastProcessPressCount );
EtVector3 vAniDist = *GetPosition();
vAniDist.x -= GetAniDistance()->x;
vAniDist.z -= GetAniDistance()->z;
float fScanRadius = 0.0f;
if( m_Press == Press_Circle ) fScanRadius = (float)GetUnitSize() + 50.f;
else if( m_Press == Press_Capsule ) fScanRadius = (float)GetUnitSize()*2.0f + 50.f;
int nCount = ScanActor( GetRoom(), vAniDist, fScanRadius, hVecList );
if( nCount > 0 ) {
for( int i=0; i<nCount; i++ ) {
if( hVecList[i] == GetMySmartPtr() ) continue;
if( hVecList[i]->IsDie() ) continue;
if( hVecList[i]->GetPressLevel() > m_nPressLevel ) continue;
if( hVecList[i]->GetPressLevel() == -1 ) continue;
if( m_Press == Press_NoneSameCircle && hVecList[i]->m_Press == Press_NoneSameCircle ) continue;
ProcessPress( hVecList[i] );
}
m_iLastProcessPressCount = nCount;
}
}
void CDnActor::ProcessPress( DnActorHandle hTarget )
{
EtVector2 Dir;
float Dist = 0.0f;
bool bCheckPress = false;
if( GetPress() == CDnActorState::Press_Circle && hTarget->GetPress() == CDnActorState::Press_Circle ) {
if( CheckPressCircle2Clrcle2( GetMySmartPtr(), hTarget, Dir, Dist ) ) {
hTarget->MoveToWorld( Dir * Dist );
bCheckPress = true;
}
}
else if( GetPress() == CDnActorState::Press_Capsule && hTarget->GetPress() == CDnActorState::Press_Capsule ) {
if( CheckPressCapsule2Capsule2( GetMySmartPtr(), hTarget, Dir, Dist ) ) {
hTarget->MoveToWorld( Dir * Dist );
bCheckPress = true;
}
}
else if( GetPress() == CDnActorState::Press_Capsule && hTarget->GetPress() == CDnActorState::Press_Circle ) {
if( CheckPressCapsule2Circle2( GetMySmartPtr(), hTarget, Dir, Dist ) ) {
hTarget->MoveToWorld( Dir * Dist );
bCheckPress = true;
}
}
else if( GetPress() == CDnActorState::Press_Circle && hTarget->GetPress() == CDnActorState::Press_Capsule ) {
if( CheckPressCapsule2Circle2( hTarget, GetMySmartPtr(), Dir, Dist ) ) {
hTarget->MoveToWorld( -Dir * Dist );
bCheckPress = true;
}
}
if( bCheckPress ) {
if( hTarget->IsPlayerActor() ) {
CDnPlayerActor *pPlayer = (CDnPlayerActor *)hTarget.GetPointer();
if( pPlayer->GetPlayerSpeedHackChecker() )
((CDnPlayerSpeedHackChecker*)pPlayer->GetPlayerSpeedHackChecker())->SetCheckPress( true, Dist );
}
}
}
bool CDnActor::CheckPressCircle2Clrcle2( DnActorHandle hActor1, DnActorHandle hActor2, EtVector2 &Dir, float &Dist )
{
EtVector2 vDir;
int nSumSize;
vDir = EtVec3toVec2( *hActor2->GetPosition() - *hActor1->GetPosition() );
nSumSize = hActor1->GetUnitSize() + hActor2->GetUnitSize();
float fLength = D3DXVec2Length( &vDir );
if( fLength > (float)nSumSize ) return false;
D3DXVec2Normalize( &Dir, &vDir );
Dist = (float)( nSumSize - fLength );
return true;
}
bool CDnActor::CheckPressCapsule2Capsule2( DnActorHandle hActor1, DnActorHandle hActor2, EtVector2 &Dir, float &Dist )
{
// ÀÚ½ÅÀÇ ¿ùµå»ó ĸ½¶¿µ¿ª ±¸Çϰí(Á÷¼±)
int nSizeX = hActor1->GetUnitSizeParam1();
int nSizeZ = hActor1->GetUnitSizeParam2();
EtVector3 vCapsule1, vCapsule2;
int nSumSize = 0;
if( nSizeX < nSizeZ ) {
vCapsule1.x = vCapsule2.x = vCapsule1.y = vCapsule2.y = 0.0f;
vCapsule1.z = (float)(nSizeZ - nSizeX);
vCapsule2.z = -vCapsule1.z;
nSumSize += nSizeX;
}
else {
vCapsule1.z = vCapsule2.z = vCapsule1.y = vCapsule2.y = 0.0f;
vCapsule1.x = (float)(nSizeX - nSizeZ);
vCapsule2.x = -vCapsule1.x;
nSumSize += nSizeZ;
}
EtMatrix matWorld = *hActor1->GetMatEx();
EtVec3TransformCoord( &vCapsule1, &vCapsule1, &matWorld );
EtVec3TransformCoord( &vCapsule2, &vCapsule2, &matWorld );
EtVector2 vLine1, vLine2;
vLine1 = EtVec3toVec2( vCapsule1 );
vLine2 = EtVec3toVec2( vCapsule2 );
// Ÿ°ÙÀÇ ¿ùµå»ó ĸ½¶¿µ¿ª ±¸Çϰí(Á÷¼±)
int nTargetSizeX = hActor2->GetUnitSizeParam1();
int nTargetSizeZ = hActor2->GetUnitSizeParam2();
EtVector3 vTargetCapsule1, vTargetCapsule2;
if( nTargetSizeX < nTargetSizeZ ) {
vTargetCapsule1.x = vTargetCapsule2.x = vTargetCapsule1.y = vTargetCapsule2.y = 0.0f;
vTargetCapsule1.z = (float)(nTargetSizeZ - nTargetSizeX);
vTargetCapsule2.z = -vTargetCapsule1.z;
nSumSize += nTargetSizeX;
}
else {
vTargetCapsule1.z = vTargetCapsule2.z = vTargetCapsule1.y = vTargetCapsule2.y = 0.0f;
vTargetCapsule1.x = (float)(nTargetSizeX - nTargetSizeZ);
vTargetCapsule2.x = -vTargetCapsule1.x;
nSumSize += nTargetSizeZ;
}
EtMatrix matTargetWorld = *hActor2->GetMatEx();
EtVec3TransformCoord( &vTargetCapsule1, &vTargetCapsule1, &matTargetWorld );
EtVec3TransformCoord( &vTargetCapsule2, &vTargetCapsule2, &matTargetWorld );
EtVector2 vTargetLine1, vTargetLine2;
vTargetLine1 = EtVec3toVec2( vTargetCapsule1 );
vTargetLine2 = EtVec3toVec2( vTargetCapsule2 );
if( hActor1 == hActor2 ) return false;
// Á÷¼±°ú Á÷¼± °Å¸®¸¦ ±¸ÇÑ ÈÄ
EtVector2 vPressDir;
float fLength = DistLine2DToLine2D( vLine1, vLine2, vTargetLine1, vTargetLine2, vPressDir );
if( fLength > 0.0f ) {
// ±³Â÷ÇÏÁö ¾Ê´Â´Ù¸é, PressDirÀÌ Á¦´ë·Î µé¾îÀÖÀ» °ÍÀÌ´Ù.
// ±×¸®°í À̶© ÀϹÝÀûÀÎ Á¡°ú Á÷¼±ÀÇ °Å¸®±â ¶§¹®¿¡ SumSize¿Í ºñ±³ÆÇ´ÜÀ» ¼öÇàÇÑ´Ù.
if( fLength > (float)nSumSize ) return false;
Dir = vPressDir;
Dist = (float)( nSumSize - fLength );
}
else {
// ±³Â÷Çϸé
// ù¹øÂ° ¼±ºÐ°ú µÎ¹øÂ° ¼±ºÐÀÇ ¾ç ³¡Á¡À» °¡Áö°í °Å¸®¸¦ Àé ÈÄ
EtVector2 vDir1, vDir2;
float fDist1 = DistPointToLine2D( vTargetLine1, vLine1, vLine2, vDir1 );
float fDist2 = DistPointToLine2D( vTargetLine2, vLine1, vLine2, vDir2 );
// °Å¸®°¡ ªÀº °ÍÀ» ÀúÀå. ¹æÇâÀº ¹Ý´ë·Î ÀúÀå.
if( fDist1 < fDist2 ) {
vPressDir = -vDir1;
fLength = fDist1;
}
else {
vPressDir = -vDir2;
fLength = fDist2;
}
// ±³Â÷ÇÑ´Ù¸é SumSize¿ÍÀÇ °Å¸®ºñ±³´Â ÇÊ¿ä¾ø´Ù.
// ÀÌ¹Ì ±³Â÷µÉÁ¤µµ·Î °ãÃÆ´Ù¸é, ÃּҰŸ®¹ÛÀ¸·Î ¹Ð¾î³»´Â ¹æ¹ý ¿Ü¿£ ¾ø´Ù.
Dir = vPressDir;
Dist = (float)( nSumSize + fLength );
}
return true;
}
bool CDnActor::CheckPressCapsule2Circle2( DnActorHandle hActor1, DnActorHandle hActor2, EtVector2 &Dir, float &Dist )
{
int nSizeX = hActor1->GetUnitSizeParam1();
int nSizeZ = hActor1->GetUnitSizeParam2();
EtVector3 vCapsule1, vCapsule2;
int nSumSize;
if( nSizeX < nSizeZ ) {
vCapsule1.x = vCapsule2.x = vCapsule1.y = vCapsule2.y = 0.0f;
vCapsule1.z = (float)(nSizeZ - nSizeX);
vCapsule2.z = -vCapsule1.z;
nSumSize = nSizeX + hActor2->GetUnitSize();
}
else {
vCapsule1.z = vCapsule2.z = vCapsule1.y = vCapsule2.y = 0.0f;
vCapsule1.x = (float)(nSizeX - nSizeZ);
vCapsule2.x = -vCapsule1.x;
nSumSize = nSizeZ + hActor2->GetUnitSize();
}
EtMatrix matWorld = *hActor1->GetMatEx();
EtVec3TransformCoord( &vCapsule1, &vCapsule1, &matWorld );
EtVec3TransformCoord( &vCapsule2, &vCapsule2, &matWorld );
EtVector2 vLine1, vLine2;
vLine1 = EtVec3toVec2( vCapsule1 );
vLine2 = EtVec3toVec2( vCapsule2 );
EtVector2 vTargetPos = EtVec3toVec2( *hActor2->GetPosition() );
EtVector2 vPressDir;
float fLength = DistPointToLine2D( vTargetPos, vLine1, vLine2, vPressDir );
if( fLength > (float)nSumSize ) return false;
Dir = vPressDir;
Dist = (float)( nSumSize - fLength );
return true;
}
bool CDnActor::bIsObserver()
{
if( GetGameRoom() && GetGameRoom()->bIsPvPRoom() )
{
if( GetTeam() == PvPCommon::Team::Observer )
return true;
}
return false;
}
float CDnActor::SquaredDistance( const EtVector3& vPos, const SAABox& BBox, bool bNear )
{
float fSQDist = 0.0f;
for( int i = 0; i < 3; ++i )
{
// y ÃàÀº ¹«½Ã
if( 1 == i )
continue;
float v = vPos[ i ];
if( bNear ) {
if( v < BBox.Min[ i ] )
fSQDist += (BBox.Min[ i ] - v) * (BBox.Min[ i ] - v);
if( v > BBox.Max[ i ] )
fSQDist += (v - BBox.Max[ i ]) * (v - BBox.Max[ i ]);
}
else {
if( v > BBox.Min[ i ] )
fSQDist += (BBox.Min[ i ] - v) * (BBox.Min[ i ] - v);
if( v < BBox.Max[ i ] )
fSQDist += (v - BBox.Max[ i ]) * (v - BBox.Max[ i ]);
}
}
return fSQDist;
}
void CDnActor::CmdChangeTeam( int nTeam )
{
SetTeam( nTeam );
printf("CDnActor::CmdChangeTeam %d\n",nTeam);
char pBuffer[32];
CPacketCompressStream Stream( pBuffer, sizeof(pBuffer) );
Stream.Write( &m_nTeam, sizeof(int) );
Send( eActor::SC_CMDCHANGETEAM, &Stream );
}
void CDnActor::OnHitFinish( LOCAL_TIME LocalTime, HitStruct *pStruct )
{
if( !pStruct->vSelfVelocity || !pStruct->vSelfResistance ) return;
if( GetVelocity() == NULL || GetResistance() == NULL ) return;
if( EtVec3LengthSq( pStruct->vSelfVelocity ) == 0.f && EtVec3LengthSq( pStruct->vSelfResistance ) == 0.f ) return;
EtVector3 vVelocity = *pStruct->vSelfVelocity;
EtVector3 vResistance = *pStruct->vSelfResistance;
// y °ªÀÌ ±âÁ¸¿¡ Àִµ¥ ¿©±â¼­ µ¤¾î¾º¿ì¸é ¹®Á¦°¡ »ý±æ¼öÀÖÀ¸¹Ç·Î y ´Â º¸Á¤ÇØÁØ´Ù.
if( GetVelocity()->y != 0.f && pStruct->vSelfVelocity->y == 0.f ) {
vVelocity.y = GetVelocity()->y;
vResistance.y = GetResistance()->y;
}
CmdForceVelocity( vVelocity, vResistance );
}
void CDnActor::CmdForceVelocity( EtVector3 &vVelocity, EtVector3 &vResistance )
{
SetVelocity( vVelocity );
SetResistance( vResistance );
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( GetPosition(), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( ( GetVelocity() ) ? GetVelocity() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Stream.Write( ( GetResistance() ) ? GetResistance() : &EtVector3( 0.f, 0.f, 0.f ), sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
Send( eActor::SC_CMDFORCEVELOCITY, &Stream );
}
void CDnActor::CmdChatBalloon( LPCWSTR wszMessage )
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
int nLength = static_cast<int>(wcslen( wszMessage ) * 2);
if( nLength > 120 ) nLength = 120;
Stream.Write( &nLength, sizeof(int) );
Stream.Write( wszMessage, nLength );
Send( eActor::SC_CMDCHATBALLOON, &Stream );
}
#if defined(PRE_ADD_MULTILANGUAGE)
void CDnActor::CmdChatBalloon( int nUIStringIndex )
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &nUIStringIndex, sizeof(int) );
Send( eActor::SC_CMDCHATBALLOON_AS_INDEX, &Stream );
}
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
void CDnActor::CmdShowExposureInfo( bool bShow )
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &bShow, sizeof(bool) );
Send( eActor::SC_SHOWEXPOSUREINFO, &Stream );
}
void CDnActor::CmdForceAddSkill( int nSkillID )
{
AddSkill( nSkillID );
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &nSkillID, sizeof(int) );
Send( eActor::SC_FORCE_ADD_SKILL, &Stream );
}
void CDnActor::CmdForceRemoveSkill( int nSkillId )
{
RemoveSkill( nSkillId );
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &nSkillId, sizeof(int) );
Send( eActor::SC_FORCE_REMOVE_SKILL, &Stream );
}
void CDnActor::OnProjectile( CDnProjectile *pProjectile, ProjectileStruct* pStruct, MatrixEx& LocalCross, int nSignalIndex )
{
int iShootActionIndex = GetElementIndex( GetCurrentAction() );
if( -1 != iShootActionIndex )
pProjectile->SetShootActionIndex( iShootActionIndex );
pProjectile->SetSignalArrayIndex( nSignalIndex );
boost::shared_ptr<ProjectileStruct> pProjectileStruct = boost::shared_ptr<ProjectileStruct>(new ProjectileStruct);
#ifdef PRE_FIX_MEMOPT_SIGNALH
CopyShallow_ProjectileStruct(*pProjectileStruct, pStruct);
#else
*pProjectileStruct = *pStruct;
#endif
pProjectile->SetProjectileSignal( pProjectileStruct );
}
void CDnActor::CmdSyncBlow( CDNUserSession* pGameSession )
{
for( int i=0 ; i<GetNumAppliedStateBlow() ; ++i )
{
DnBlowHandle hBlow = GetAppliedStateBlow( i );
if( hBlow )
{
const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo();
if( !pSkillInfo )
{
_DANGER_POINT();
continue;
}
// #24143 ÆÐ½Ãºê ¹öÇÁ ½ºÅ³ÀÇ »óÅÂÈ¿°úÀÎ °æ¿ì¿£ µ¿±â¸¦ ¸ÂÃßÁö ¾Ê½À´Ï´Ù.
// ÆÐ½Ãºê ½ºÅ³Àº Ŭ¶óÀÌ¾ðÆ®°¡ ³­ÀÔÇßÀ» ¶§ ¹Þ°Ô µÇ´Â ´Ù¸¥ À¯ÀúµéÀÇ ½ºÅ³¸®½ºÆ®¸¦
// ÃʱâÈ­ ÇÒ¶§ ÀÚµ¿À¸·Î Àû¿ëµË´Ï´Ù.
if( CDnSkill::Passive == pSkillInfo->eSkillType &&
CDnSkill::Buff == pSkillInfo->eDurationType &&
CDnSkill::ApplySelf == pSkillInfo->eTargetType )
{
continue;
}
const CPacketCompressStream* pPacket = hBlow->GetPacketStream();
Send( pGameSession, eActor::SC_CMDADDSTATEEFFECT, GetUniqueID(), const_cast<CPacketCompressStream*>(pPacket) );
}
}
}
void CDnActor::OnDie( DnActorHandle hHitter )
{
m_fDieDelta = m_fMaxDieDelta;
}
void CDnActor::UseMP( int iMPDelta )
{
int iResult = m_pStateBlow->OnUseMP( iMPDelta );
SetSP( GetSP() + iResult );
RequestHPMPDelta( ElementEnum::ElementEnum_Amount, iResult, UINT_MAX, true );
}
void CDnActor::RequestDamageFromStateBlow( DnBlowHandle hFromBlow, int iDamage, CDnDamageBase::SHitParam* pHitParam/* = NULL*/ )
{
// ¹«Àû »óÅÂÈ¿°¡ °É·ÁÀÖÀ¸¸é ¹«½Ã.
if( hFromBlow && false == IsAppliedThisStateBlow( STATE_BLOW::BLOW_099 ) )
{
// ÇÏÀÌ·£´õ »óÅÂÈ¿°ú°¡ ÀÖ´Â °æ¿ì Á×Áö ¾Ê¾Æ¾ß ÇÑ´Ù.
float fDamage = (float)iDamage;
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_143 ) )
{
// IsAppliedThisStateBlow() ÇÔ¼ö¿¡¼± true °¡ ¸®ÅϵÇÁö¸¸ Áö¼Ó½Ã°£ÀÌ ´Ù µÈ
// »óÅÂÈ¿°ú´Â GatherAppliedStateBlowByBlowIndex() ¿¡¼­ ¾ò¾î¿ÍÁöÁö ¾ÊÀ¸¹Ç·Î ¸®½ºÆ®°¡ ºñ¾îÀÖÀ» ¼ö µµ ÀÖ´Ù.
DNVector( DnBlowHandle ) vlhHighLanderBlow;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_143, vlhHighLanderBlow );
if( 0 < (int)vlhHighLanderBlow.size() )
{
CDnHighlanderBlow* pHighlanderBlow = static_cast<CDnHighlanderBlow*>(vlhHighLanderBlow.front().GetPointer());
fDamage += pHighlanderBlow->CalcDamage( fDamage );
}
}
CDnSkill::SkillInfo* pParentSkillInfo = const_cast<CDnSkill::SkillInfo*>(hFromBlow->GetParentSkillInfo());
DWORD dwHitterUniqueID = 0;
ElementEnum eElement = ElementEnum::ElementEnum_Amount;
if( pParentSkillInfo )
{
dwHitterUniqueID = pParentSkillInfo->hSkillUser ? pParentSkillInfo->hSkillUser->GetUniqueID() : -1;
eElement = pParentSkillInfo->eSkillElement;
}
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_243 ) )
{
float fAbsorbDamage = 0.f;
int nAbsorbSP = 0;
DNVector( DnBlowHandle ) vlhManaShieldBlow;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_243, vlhManaShieldBlow );
for( DWORD n=0; n<vlhManaShieldBlow.size(); n++ )
{
CDnManaShieldBlow* pManShieldBlow = static_cast<CDnManaShieldBlow*>(vlhManaShieldBlow[n].GetPointer());
pManShieldBlow->CalcManaShield( fDamage , fAbsorbDamage , nAbsorbSP );
}
if( nAbsorbSP > GetSP() )
{
fAbsorbDamage -= (fAbsorbDamage * (nAbsorbSP - GetSP()) / nAbsorbSP);
nAbsorbSP = GetSP();
}
if( fAbsorbDamage > fDamage )
fAbsorbDamage = fDamage;
fDamage -= fAbsorbDamage;
SetSP( GetSP() -nAbsorbSP );
RequestHPMPDelta( ElementEnum::ElementEnum_Amount, -nAbsorbSP, UINT_MAX, true , true );
}
#if defined(PRE_FIX_59347)
//ÆÄÃ÷ ¸ó½ºÅÍ µ¥¹ÌÁö º¸Á¤?À» À§Çؼ­
#ifdef PRE_FIX_67656
ApplyPartsDamage(fDamage, pParentSkillInfo->hSkillUser);
#else
if (GetApplyPartsDamage() == true)
ApplyPartsDamage(fDamage, pParentSkillInfo->hSkillUser);
#endif
//¼Ó¼º Ç¥½Ã
if (pHitParam)
eElement = pHitParam->HasElement;
#endif // PRE_FIX_59347
SetHP( GetHP()-(INT64)fDamage );
#ifdef PRE_FIX_77172
if( hFromBlow->GetBlowIndex() == STATE_BLOW::BLOW_042 )
RequestHPMPDelta( eElement, -(INT64)fDamage, dwHitterUniqueID, false, true, pHitParam, true );
else
RequestHPMPDelta( eElement, -(INT64)fDamage, dwHitterUniqueID, false, true, pHitParam );
#else // PRE_FIX_77172
RequestHPMPDelta( eElement, -(INT64)fDamage, dwHitterUniqueID, false, true, pHitParam );
#endif // PRE_FIX_77172
#ifdef PRE_ADD_EXPORT_DPS_INFORMATION
if( CDnDPSReporter::IsActive() && pParentSkillInfo && pParentSkillInfo->hSkillUser && pParentSkillInfo->hSkillUser->IsPlayerActor() )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>( pParentSkillInfo->hSkillUser.GetPointer());
if(CDnDPSReporter::GetInstance().IsEnabledUser( pPlayerActor->GetCharacterDBID() ))
{
CDnDPSReporter::GetInstance().StartReport();
DNVector(DnActorHandle) hVecList;
ScanActor( GetRoom(), *GetActorHandle()->GetPosition() , 500.f , hVecList );
CDnDPSReporter::GetInstance().ApplyAreaMonsterCount( (int)hVecList.size() );
CDnDPSReporter::GetInstance().ApplyDotDamageData( (int)fDamage , GetActorHandle() , hFromBlow );
CDnDPSReporter::GetInstance().EndReport();
}
}
#endif
}
}
void CDnActor::CmdFreezingPrisonDurablity(int nStateBlowID, float fDuabilityRate, bool bShowGauge)
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
Stream.Write( &nStateBlowID, sizeof(nStateBlowID) );
Stream.Write( &fDuabilityRate, sizeof(fDuabilityRate) );
Stream.Write( &bShowGauge, sizeof(bShowGauge) );
Send( eActor::SC_FREEZINGPRISON_DURABILITY, &Stream );
}
void CDnActor::SendRemoveStateEffectFromID( int nID )
{
char acBuffer[ 32 ];
CPacketCompressStream Stream( acBuffer, sizeof(acBuffer) );
Stream.Write( &nID, sizeof(nID) );
Send( eActor::SC_CMDREMOVESTATEEFFECTFROMID, &Stream );
}
void CDnActor::RemoveResetStateBlow()
{
// [2010/12/15 semozz]
// ÀÌ ÇÔ¼ö È£ÃâÈÄ¿¡ »õ·Î¿î »óÅ ȿ°úµé·Î ´ëüµÇ¾î¾ß Çϱ⶧¹®¿¡
// ¿©±â¼­´Â ¹Ù·Î »óÅ ȿ°úµéÀ» Á¦°Å ÇØ¾ßÇÑ´Ù.
std::map<int, int>::iterator iter = m_vlStateBlowIDToRemove.begin();
for (; iter != m_vlStateBlowIDToRemove.end(); ++iter)
{
//Áï½Ã »óÅÂÈ¿°ú Á¦°Å Çϰí
m_pStateBlow->RemoveImediatlyStateEffectFromID(iter->second);
//Ŭ¶óÀÌ¾ðÆ®·Î »óÅÂÈ¿°ú Á¦°Å ÆÐŶ º¸³¿.
SendRemoveStateEffectFromID(iter->second);
}
m_vlStateBlowIDToRemove.clear();
}
void CDnActor::ForceKnockBack(DnActorHandle hHitter, CDnDamageBase::SHitParam& HitParam)
{
m_HitParam = HitParam;
int nSeed = CRandom::Seed(GetRoom());
_srand( GetRoom(), nSeed );
CDnWeapon::HitTypeEnum HitType = CDnWeapon::Normal;
//////////////////////////////////////////////////////////////////////////
// °æÁ÷ ½Ã°£ °è»ê
float fStiffResult = 0.f;
if( GetStiffResistance() > 0 ) fStiffResult = ( hHitter->GetStiff() * m_HitParam.fStiffProb ) / GetStiffResistance();
fStiffResult *= CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffRevision );
if( fStiffResult <= 0.f ) fStiffResult = 0.05f;
else if( fStiffResult > CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax ) )
fStiffResult = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::StiffMax );
m_fStiffDelta = s_fMaxStiffTime * fStiffResult;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// ´Ù¿îµô·¹ÀÌ ·£´ý°ª ¼³Á¤
if( !IsDown() ) {
m_fLastDownRatio = 1.f;
}
float fTemp = ( 3.f * ( 1.f - GetDownDelayProb() ) ) * m_fLastDownRatio;
int nTemp = (int)( fTemp * DOWN_DELAY_RANDOM_RANGE * 100.f );
if( nTemp == 0 ) m_fDownDelta = fTemp;
else m_fDownDelta = fTemp - DOWN_DELAY_RANDOM_RANGE + ( _rand(GetRoom())%( nTemp * 2 ) / 100.f );
if( m_fDownDelta >= 3.f ) m_fDownDelta = 3.f;
if( m_fDownDelta <= 0.1f ) m_fDownDelta = 0.01f;
//////////////////////////////////////////////////////////////////////////
m_HitParam.HitType = HitType;
// µ¥¹ÌÁö °è»ê
switch( HitType )
{
case CDnWeapon::Normal:
case CDnWeapon::Critical:
case CDnWeapon::Stun:
case CDnWeapon::CriticalRes:
{
// ¹«°Ô¿¡ µû¶ó °¡¼Óµµ ÁÙ¿©ÁØ´Ù.
if( GetWeight() > 0.f )
m_HitParam.vVelocity.y /= GetWeight();
if( GetWeight() > 1.f )
{
float fTemp = m_HitParam.vVelocity.z;
float fTest = CalcMovement( fTemp, 1.f, FLT_MAX, FLT_MIN, m_HitParam.vResistance.z );
if( m_HitParam.vVelocity.z * fTest > 0.f )
{
m_HitParam.vVelocity.x /= powf( 1.1f, GetWeight() );
m_HitParam.vVelocity.z /= powf( 1.1f, GetWeight() );
}
}
bool bSuccessNormalDamage = true;
int nSuperAmmorTime = 0;
m_HitParam.bSuccessNormalDamage = bSuccessNormalDamage;
m_HitParam.nSuperAmmorDelay = nSuperAmmorTime;
memset( m_nSkillSuperAmmorValue, 0, sizeof(m_nSkillSuperAmmorValue) );
OnBreakSkillSuperAmmor( m_HitParam );
if( bSuccessNormalDamage ) {
CheckDamageVelocity( hHitter );
// ¸Â¾ÒÀ»¶§ ¸®¼ÂÇÒ°Íµé ¸®¼Â
MAMovementBase *pMovement = GetMovement();
if( pMovement ) {
pMovement->ResetMove();
pMovement->ResetLook();
}
if( !m_HitParam.szActionName.empty() ) {
SetActionQueue( m_HitParam.szActionName.c_str(), 0, 3.f, 0.f, false );
}
}
}
break;
}
INT64 nDamage = 0;
RequestDamage(hHitter, nSeed, nDamage);
}
void CDnActor::RemoveNonAvailableStateBlow()
{
if (NULL == m_pStateBlow)
return;
CDNGameRoom* pGameRoom = static_cast<CDNGameRoom*>(GetRoom());
CDNUserSession *pUserSession = pGameRoom ? pGameRoom->GetUserSession(GetSessionID()) : NULL;
if (!pUserSession)
return;
const TMapInfo* pMapData = g_pDataManager->GetMapInfo( pUserSession->GetMapIndex() );
if (!pMapData)
return;
//¿ùµå ¸ÊÀÏ °æ¿ì´Â ½ºÅµ
if (GlobalEnum::MAP_WORLDMAP == pMapData->MapType)
return;
// ÇöÀç À¯Àú°¡ ¼ÓÇÑ ¸ÊÀÇ AllowTypeÀ» ¾ò¾î ¿Â´Ù..
int nAllowMapType = pMapData->nAllowMapType;
int nSize = m_pStateBlow->GetNumStateBlow();
for ( int i = 0 ; i < nSize ; i++ )
{
DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i);
if( hBlow && STATE_BLOW::STATE_END != hBlow->GetBlowState() )
{
//»óÅÂÈ¿°úÁß ¾ÆÀÌÅÛ ½ºÅ³¿¡ ÀÇÇÑ »óÅÂÈ¿°úÀÎÁö È®ÀÎÇØ¼­
//»ç¿ëµÈ ¾Æ¾ÆÅÛ ID¸¦ ¾ò¾î ¿Â´Ù.
const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo();
if (pSkillInfo && pSkillInfo->bIsItemSkill)
{
int nItemID = pSkillInfo->nItemID;
const TItemData* pItemData = g_pDataManager->GetItemData(nItemID);
if (pItemData)
{
//ÇöÀç ¸ÊÀÇ AllowMapType°ú ¾ÆÀÌÅÛÀÇ AllowMapType ¼³Á¤ÀÌ ´Ù¸£´Ù¸é
if ((nAllowMapType & pItemData->nAllowMapType) == 0)
{
CmdRemoveStateEffectFromID(hBlow->GetBlowID());
}
}
}
}
}
}
void CDnActor::RemovedActivatedStateBlow( bool bIgnoreItemSkill )
{
if (NULL == m_pStateBlow)
return;
CDNGameRoom* pGameRoom = static_cast<CDNGameRoom*>(GetRoom());
CDNUserSession *pUserSession = pGameRoom ? pGameRoom->GetUserSession(GetSessionID()) : NULL;
if (!pUserSession)
return;
int nSize = m_pStateBlow->GetNumStateBlow();
for ( int i = 0 ; i < nSize ; i++ )
{
DnBlowHandle hBlow = m_pStateBlow->GetStateBlow(i);
if( hBlow && STATE_BLOW::STATE_END != hBlow->GetBlowState() )
{
const CDnSkill::SkillInfo* pSkillInfo = hBlow->GetParentSkillInfo();
if( bIgnoreItemSkill == true && pSkillInfo && pSkillInfo->bIsItemSkill )
continue;
if ( hBlow->IsFromSourceItem() )
continue;
if( hBlow->IsEternity() )
continue;
if ( !bIsPassiveSkill( hBlow ) )
{
CmdRemoveStateEffectFromID(hBlow->GetBlowID());
}
}
}
}
void CDnActor::FindSkillBySkillType(CDnSkill::SkillTypeEnum eSkillType, DNVector(DnSkillHandle)& vlSkillList)
{
#ifndef PRE_FIX_SKILLLIST
for( DWORD i=0; i<m_vlhSkillList.size(); i++ )
{
// Åä±ÛÀ̳ª ¿À¶ó ½ºÅ³À̶ó¸é º°µµÀÇ ¸®½ºÆ®¿¡¼­ »èÁ¦
DnSkillHandle hSkill = m_vlhSkillList.at(i);
if(!hSkill)
continue;
if (eSkillType == hSkill->GetSkillType())
vlSkillList.push_back(hSkill);
}
#else
DWORD dwNumSkill = GetSkillCount();
for( DWORD i = 0; i < dwNumSkill; ++i )
{
DnSkillHandle hSkill = GetSkillFromIndex( i );
if( !hSkill )
continue;
if( eSkillType == hSkill->GetSkillType() )
vlSkillList.push_back( hSkill );
}
#endif // #ifndef PRE_FIX_SKILLLIST
}
void CDnActor::OnLoopAction( float fFrame, float fPrevFrame )
{
/*
if( m_nActionIndex == -1 || m_nVecAniIndexList[m_nActionIndex] == -1 ) return;
MAActorRenderBase *pRenderBase = static_cast<MAActorRenderBase *>(this);
if( !pRenderBase ) return;
ActionElementStruct *pStruct = GetElement( m_nActionIndex );
EtVector3 vDist;
pRenderBase->CalcAniDistance( m_nVecAniIndexList[m_nActionIndex], min( (float)pStruct->dwLength, fFrame ), fPrevFrame, vDist );
pRenderBase->AddAniDistance( vDist );
*/
}
void CDnActor::CmdUpdateStateBlow(int nBlowID)
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
DWORD dwUniqueID = GetUniqueID();
Stream.Write( &dwUniqueID, sizeof(dwUniqueID) );
Stream.Write( &nBlowID, sizeof(nBlowID) );
Send( eActor::SC_CMDUPDATESTATEBLOW, &Stream );
}
void CDnActor::CmdFinishAuraSkill(DWORD nSkillID)
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
DWORD dwUniqueID = GetUniqueID();
Stream.Write( &dwUniqueID, sizeof(dwUniqueID) );
Stream.Write( &nSkillID, sizeof(nSkillID) );
Send( eActor::SC_FINISH_AURASKILL, &Stream );
}
bool CDnActor::IsImmuned(STATE_BLOW::emBLOW_INDEX blowIndex)
{
CDnStateBlow *pStateBlow = GetStateBlow();
if (!pStateBlow)
return false;
return pStateBlow->IsImmuned(blowIndex);
}
void CDnActor::SetAction( const char *szActionName, float fFrame, float fBlendFrame, bool bLoop /* = false */ )
{
CDnActionBase::SetAction( CheckChangeActionBlow( szActionName ), fFrame, fBlendFrame, bLoop );
//µ¿ÀÛ ¹Ù²ð¶§ HitLimitCountÁ¤º¸ ÃʱâÈ­
m_HitLimitCountInfoList.clear();
}
const char *CDnActor::CheckChangeActionBlow( const char *szActionName )
{
const char *szResultActionName = szActionName;
// Move ¾×¼Çµµ ¹Ù²î¾î¾ßÇÒ ¶§°¡ ÀÖÀ¸¹Ç·Î ¾î¿ ¼ö ¾øÀÌ SetAction ÇÔ¼öµµ º¯°æ... ¤Ð¤Ð
// 129¹ø ¾×¼Ç À̸§ ´ëü »óÅÂÈ¿°ú ///////////////////////////////////////////////////////////////////
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_129 ) )
{
DNVector(DnBlowHandle) vlhChangeActionSetBlow;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_129, vlhChangeActionSetBlow );
// ¾×¼Ç ¼Â º¯°æ »óÅÂÈ¿°ú´Â ¿©·¯°³ ÀÖÀ» ¼ö ÀÖ´Ù.
int iNumBlow = (int)vlhChangeActionSetBlow.size();
for( int i = 0; i < iNumBlow; ++i )
{
if( !vlhChangeActionSetBlow[i] )
continue;
CDnChangeActionSetBlow* pChangeActionSetBlow = static_cast<CDnChangeActionSetBlow*>( vlhChangeActionSetBlow.at(i).GetPointer() );
if( STATE_BLOW::STATE_END != pChangeActionSetBlow->GetBlowState() )
{
CDnChangeActionStrProcessor* pProcessor = pChangeActionSetBlow->GetChangeActionStrProcessor();
if( pProcessor )
{
// °ÔÀÓ¼­¹ö ´ýÇÁ È®Àοë.
string strNowActionName( szResultActionName );
const char* pChangeActionName = pProcessor->GetChangeActionName( strNowActionName );
if( pChangeActionName )
szResultActionName = pChangeActionName;
}
}
}
}
// 121¹ø ½ºÅÄµå ¾×¼Ç º¯°æ »óÅÂÈ¿°ú°¡ ÀÖ´Â °æ¿ì. ÇØ´ç ¾×¼ÇÀ¸·Î º¯°æÇØ ÁÜ. ///////////////////////////
if( m_pStateBlow->IsApplied( STATE_BLOW::BLOW_121 ) )
{
if( 0 == strcmp(szResultActionName, "Stand") )
{
DNVector(DnBlowHandle) vlhChangeStandActionBlow;
m_pStateBlow->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_121, vlhChangeStandActionBlow );
if( false == vlhChangeStandActionBlow.empty() )
{
_ASSERT( 1 == vlhChangeStandActionBlow.size() );
if( STATE_BLOW::STATE_END != vlhChangeStandActionBlow.front()->GetBlowState() )
szResultActionName = vlhChangeStandActionBlow.front()->GetValue();
}
}
}
return szResultActionName;
}
void CDnActor::ForceBeginStateBlow(DnBlowHandle hBlow)
{
if (hBlow)
{
hBlow->OnBegin( CDnActionBase::m_LocalTime, 0.0f );
OnBeginStateBlow( hBlow );
// °ð¹Ù·Î end ·Î ¼ÂÆÃÇÏ´Â blow µµ Àֱ⠶§¹®¿¡ üũ.
if( STATE_BLOW::STATE_END != hBlow->GetBlowState() )
hBlow->SetState( STATE_BLOW::STATE_DURATION );
}
}
bool CDnActor::CanUsePrefixSkill()
{
bool isCanUse = false;
// ÆòŸÀ̰ųª ½ºÅ³¿¡ Á¢µÎ¾î ½ºÅ³ ¹ßµ¿ Ç÷¡±×°¡ ¼³Á¤ µÇ¾î ÀÖÀ¸¸é ¹ßµ¿µÊ. [2011/01/31 semozz]
// [2011/02/11 semozz]
// Á¢µÎ¾î ½ºÅ³ ¹ßµ¿ Ç÷¡±× üũ±â´É Á¦°Å
// [2011/03/14 semozz]
// ÇØÅ·½ºÅÙ½º·ù ½ºÅ³Àº ChangeStandAction»óÅ ȿ°ú°¡ Àû¿ë µÇ¾î À־ m_hProcessSkillÀÌ ¾øÁö¸¸ ½ºÅ³ »ç¿ë »óÅÂÀÌ´Ù.
// ChangeStandAction»óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é ÆòŸ°¡ ¾Æ´Ï´Ù..¶ó°í ÀÏ´ÜÀº ÆÇ´ÜÇÑ´Ù..
// Á¢µÎ¾î »óÅÂÈ¿°ú ¹«½ÃÇÏ´Â »óÅÂÈ¿°ú°¡ ÀÖÀ¸¸é Àû¿ë ¾ÈµÊ [2011/03/23 semozz]
isCanUse = (false == IsProcessSkill() && //ÆòŸ
!IsAppliedThisStateBlow(STATE_BLOW::BLOW_121) && !IsAppliedThisStateBlow(STATE_BLOW::BLOW_129) && //ÇØÅ·½ºÅÙ½º·ù
!IsAppliedThisStateBlow(STATE_BLOW::BLOW_183) //Á¢µÎ¾î ¹«½Ã
/* || IsPrefixTriggerSkill()*/);
return isCanUse;
}
void CDnActor::AddStateBlowSignal(DnBlowHandle hBlow)
{
if (m_pStateBlowSignalProcessor && hBlow)
m_pStateBlowSignalProcessor->AddBlow(hBlow);
}
void CDnActor::RemoveStateBlowSignal(DnBlowHandle hBlow)
{
if (m_pStateBlowSignalProcessor && hBlow)
m_pStateBlowSignalProcessor->RemoveBlow(hBlow);
}
void CDnActor::ReserveStealMagicBuff(DnActorHandle hActor, CDnSkill::SkillInfo *pSkillInfo, int nDurationTime, STATE_BLOW::emBLOW_INDEX blowIndex, const char* szValue)
{
StateBlowInfo newBlowInfo;
newBlowInfo.blowIndex = blowIndex;
newBlowInfo.strValue = szValue ? szValue : "";
STEAL_MAGIC_BUFF_INFO_LIST::iterator findIter = m_StealMagicBuffAddList.find(hActor);
if (findIter != m_StealMagicBuffAddList.end())
{
findIter->second.stateBlowList.push_back(newBlowInfo);
}
else
{
StealMagicBuffInfo newInfo;
newInfo.nDurationTime = nDurationTime;
if (pSkillInfo)
newInfo.skillInfo = *pSkillInfo;
newInfo.stateBlowList.push_back(newBlowInfo);
m_StealMagicBuffAddList.insert(STEAL_MAGIC_BUFF_INFO_LIST::value_type(hActor, newInfo));
}
}
void CDnActor::UpdateStealMagicBuff()
{
//±âÁ¸¿¡ Àû¿ëµÈ ½ºÆ¿¸ÅÁ÷¿¡ÀÇÇÑ »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é Á¦°ÅÇϰí..
if (!m_StealMagicBuffList.empty())
{
//Áö¿öÁö´Â »óÅÂÈ¿°úÁß ½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇÑ »óÅÂÈ¿°ú°¡ Áö¿öÁú¶§ ¸®½ºÆ®¿¡ ´ã¾Æ ³õÀº »óÅÂÈ¿°ú¸¦ Á¦°Å ÇÑ´Ù.
STEAL_MAGIC_BUFF_LIST::iterator firstIter = m_StealMagicBuffList.begin();
if (firstIter != m_StealMagicBuffList.end())
{
std::list<int>::iterator iter = firstIter->second.begin();
for (; iter != firstIter->second.end(); )
{
int nBlowID = (*iter);
std::map<int, int>::iterator findIter = m_RemovedStealMagicStateBlowIDList.find(nBlowID);
if (findIter != m_RemovedStealMagicStateBlowIDList.end())
{
iter = firstIter->second.erase(iter);
continue;
}
++iter;
}
}
}
m_RemovedStealMagicStateBlowIDList.clear();
//½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇÑ »óÅÂÈ¿°ú ¿¹¾àµÈ°Ô ¾ø´Ù¸é °Ç³Ê¶Ù°í...
if (m_StealMagicBuffAddList.empty())
return;
//±âÁ¸¿¡ Àû¿ëµÈ ½ºÆ¿¸ÅÁ÷¿¡ÀÇÇÑ »óÅÂÈ¿°ú°¡ ÀÖ´Ù¸é Á¦°ÅÇϰí..
if (!m_StealMagicBuffList.empty())
{
//¾ÆÁ÷ Àû¿ë µÇ¾î ÀÖ´Â »óÅÂÈ¿°ú Á¦°Å ÇÑ´Ù..
STEAL_MAGIC_BUFF_LIST::iterator firstIter = m_StealMagicBuffList.begin();
if (firstIter != m_StealMagicBuffList.end())
{
std::list<int>::iterator iter = firstIter->second.begin();
std::list<int>::iterator endIter = firstIter->second.end();
for (; iter != endIter; ++iter)
{
int nBlowID = (*iter);
//Áï½Ã »óÅÂÈ¿°ú Á¦°Å Çϰí
m_pStateBlow->RemoveImediatlyStateEffectFromID(nBlowID);
//Ŭ¶óÀÌ¾ðÆ®·Î »óÅÂÈ¿°ú Á¦°Å ÆÐŶ º¸³¿.
SendRemoveStateEffectFromID(nBlowID);
}
firstIter->second.clear();
}
m_StealMagicBuffList.clear();
}
//¿¹¾àµÈ ½ºÆ¿¸ÅÁ÷ »óÅÂÈ¿°ú Àû¿ë
//·£´ýÇÏ°Ô Çϳª °ñ¶ó ³»ÀÚ..
int nCount = (int)m_StealMagicBuffAddList.size();
int nSelectIndex = rand() % nCount;
STEAL_MAGIC_BUFF_INFO_LIST::iterator selectedIter = m_StealMagicBuffAddList.begin();
for (int i = 0; i < nSelectIndex; ++i)
++selectedIter;
if (selectedIter != m_StealMagicBuffAddList.end())
{
StealMagicBuffInfo &buffInfo = selectedIter->second;
STATE_BLOW_INFO_LIST::iterator iter = selectedIter->second.stateBlowList.begin();
STATE_BLOW_INFO_LIST::iterator endIter = selectedIter->second.stateBlowList.end();
for (; iter != endIter; ++iter)
{
int nBlowID = CmdAddStateEffect(&buffInfo.skillInfo, iter->blowIndex, buffInfo.nDurationTime, iter->strValue.c_str(), false, false);
AddStealMagicStateBlow(buffInfo.skillInfo.iSkillID, nBlowID);
}
}
m_StealMagicBuffAddList.clear();
}
void CDnActor::AddStealMagicStateBlow(int nSkillID, int nBlowID)
{
STEAL_MAGIC_BUFF_LIST::iterator findIter = m_StealMagicBuffList.find(nSkillID);
if (findIter != m_StealMagicBuffList.end())
{
findIter->second.push_back(nBlowID);
}
else
{
std::list<int> blowIDList;
blowIDList.push_back(nBlowID);
m_StealMagicBuffList.insert(STEAL_MAGIC_BUFF_LIST::value_type(nSkillID, blowIDList));
}
}
void CDnActor::RemoveStealMagicStateBlow(int nDeletedBlowID)
{
//½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇØ Ãß°¡µÈ »óÅÂÈ¿°ú Á¤º¸°¡ ÀÖ´Ù¸é
if (!m_StealMagicBuffList.empty())
{
//Áö±ÝÀº ÇÑ ¾×ÅÍ¿¡¼­¸¸ ½ºÆ¿¸ÅÁ÷À» Çϱ⶧¹®¿¡ begin¿¡ Àִ°͸¸ È®ÀÎ..
STEAL_MAGIC_BUFF_LIST::iterator firstIter = m_StealMagicBuffList.begin();
if (firstIter != m_StealMagicBuffList.end())
{
std::list<int>::iterator iter = firstIter->second.begin();
std::list<int>::iterator endIter = firstIter->second.end();
for (; iter != firstIter->second.end(); )
{
// Áö±Ý Á¦°ÅµÇ´Â »óÅÂÈ¿°úÀÇ BlowID¿Í °°Àº ³à¼®À» ¹ß°ß ÇÏ¸é ¸®½ºÆ®¿¡¼­ Á¦°Å ÇÑ´Ù.
if (nDeletedBlowID == (*iter))
{
m_RemovedStealMagicStateBlowIDList.insert(std::map<int, int>::value_type(nDeletedBlowID, nDeletedBlowID));
break;
}
++iter;
}
}
}
}
void CDnActor::OnEndStateBlow( DnBlowHandle hBlow )
{
//»óÅÂÈ¿°ú Á¦°Å µÉ¶§ ½ºÆ¿¸ÅÁ÷¿¡ ÀÇÇÑ »óÅÂÈ¿°úÀÌ¸é ¸®½ºÆ®¿¡¼­ Á¦°Å Çϱâ À§ÇÑ ÄÚµå
if (!hBlow)
return;
int nDeletedBlowID = hBlow->GetBlowID();
RemoveStealMagicStateBlow(nDeletedBlowID);
}
#ifdef PRE_ADD_MONSTER_CATCH
bool CDnActor::CatchCalcSuperArmor( DnActorHandle hCatcherActor, int iSuperArmorDamage )
{
bool bResult = false;
// ½´ÆÛ¾Æ¸Ó µ¥¹ÌÁö¸¦ Àû¿ëÇϰí 0 ÀÌÇϸé ÀâÈû.
// µ¥¹ÌÁö Àû¿ëÇÏ°í ½´ÆÛ¾Æ¸Ó°¡ ³²¾ÆÀÖ´Ù¸é ÇÁ·¹ÀÓ ´À¸®°Ô ÇÏ°í ÆÐ½º. ÇöÀç ½´ÆÛ¾Æ¸Ó´Â 0¸¸ »ç¿ëÇÔ.
m_nSkillSuperAmmorValue[ 0 ] -= iSuperArmorDamage;
if( m_nSkillSuperAmmorValue[ 0 ] < 0 )
{
bResult = true;
}
else
{
// ¿ì¼± ÇÁ·¹ÀÓ ´À·ÁÁö´Â °Ç »«´Ù.
//// ½´ÆÛ ¾Æ¸Ó·Î ¹öÆÀ.
//int iSuperArmorTime = m_nSkillSuperAmmorTime;
//int iDelay = (int)( iSuperArmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) );
//if( iDelay > 0 )
//{
// SetPlaySpeed( (DWORD)( iSuperArmorTime * ( m_fStiffDelta / s_fMaxStiffTime ) ), 0.03f );
//}
}
return bResult;
}
#endif // #ifdef PRE_ADD_MONSTER_CATCH
bool CDnActor::CheckCollisionHitCondition(const EtVector3& vObjPos, const MatrixEx& objCross, EtVector3 &vTargetPos, float angleAllow)
{
EtVector3 vDir = vTargetPos - vObjPos;
vDir.y = 0.f;
EtVec3Normalize(&vDir, &vDir);
EtVector3 vZVec = objCross.m_vZAxis;
float fDeg = EtToDegree(acos(EtVec3Dot(&vZVec, &vDir)));
if (fDeg > angleAllow)
return false;
return true;
}
DnMonsterActorHandle CDnActor::FindOldSummonMonster(const SummonMonsterStruct* pSummonMonsterStruct)
{
DnMonsterActorHandle hSelectedSummon;
LOCAL_TIME tempTime = 0x7FFFFFFFFFFFFFFF;
if( 0 < pSummonMonsterStruct->nGroupID )
{
if( 0 < m_mapSummonMonsterByGroup.count( pSummonMonsterStruct->nGroupID ) )
{
std::list<DnMonsterActorHandle>& listSummonedGroupMonster = m_mapSummonMonsterByGroup[ pSummonMonsterStruct->nGroupID ];
for( std::list<DnMonsterActorHandle>::iterator itor=listSummonedGroupMonster.begin(); itor!=listSummonedGroupMonster.end(); ++itor)
{
DnMonsterActorHandle hMonster = *itor;
//GroupÀÌ ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì´Â MonsterID¸¦ ºñ±³ ÇÏÁö ¾Ê°í ±×·ì³»¿¡ ÀÖ´Â ¼Òȯ ¸ó½ºÅÍÁß¿¡¼­ ¼Òȯ ½Ã°£ÀÌ Á¦ÀÏ ¿À·¡µÈ ³à¼®À» ¼±Åà Çϵµ·Ï ÇÑ´Ù.
if (!hMonster)
continue;
LOCAL_TIME requestSummonTime = hMonster->GetRequestSummonTime();
if( requestSummonTime < tempTime)
{
hSelectedSummon = hMonster;
tempTime = requestSummonTime;
}
}
}
}
else
{
for( std::list<DnMonsterActorHandle>::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end(); ++itor)
{
DnMonsterActorHandle hMonster = *itor;
if (!hMonster || hMonster->GetMonsterClassID() != pSummonMonsterStruct->MonsterID)
continue;
LOCAL_TIME requestSummonTime = hMonster->GetRequestSummonTime();
if( requestSummonTime < tempTime)
{
hSelectedSummon = hMonster;
tempTime = requestSummonTime;
}
}
}
return hSelectedSummon;
}
void CDnActor::RequestActionChange(int nActionIndex)
{
BYTE pBuffer[ 16 ];
CPacketCompressStream Stream( pBuffer, 16 );
Stream.Write( &nActionIndex, sizeof(int) );
Send( eActor::SC_ACTION_CHANGE, &Stream );
}
const std::list<DnMonsterActorHandle>& CDnActor::GetSummonedMonsterList( void )
{
for( std::list<DnMonsterActorHandle>::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end() ; )
{
if( !(*itor) )
{
itor = m_listSummonMonster.erase( itor );
}
else
{
++itor;
}
}
return m_listSummonMonster;
}
const std::map<int, std::list<DnMonsterActorHandle> >& CDnActor::GetGroupingSummonedMonsterList( void )
{
map<int, list<DnMonsterActorHandle> >::iterator iter = m_mapSummonMonsterByGroup.begin();
for( iter; iter != m_mapSummonMonsterByGroup.end(); ++iter )
{
list<DnMonsterActorHandle>& listSummonedMonsters = iter->second;
list<DnMonsterActorHandle>::iterator iterList = listSummonedMonsters.begin();
for( iterList; iterList != listSummonedMonsters.end(); )
{
if( !(*iterList) )
{
iterList = listSummonedMonsters.erase( iterList );
}
else
{
++iterList;
}
}
}
return m_mapSummonMonsterByGroup;
}
void CDnActor::SendChainAttackProjectile(DnActorHandle hRootAttacker, DWORD dwPrevAttackerActorUniqueID, int iActionIndex, int iProjectileSignalArrayIndex, DnActorHandle hActorToAttack, int iSkillID)
{
if (!hRootAttacker || !hActorToAttack)
return;
BYTE pBuffer[ 256 ];
CPacketCompressStream Stream( pBuffer, 256 );
//
DWORD dwRootAttackerID = hRootAttacker->GetUniqueID();
DWORD dwActorToAttackID = hActorToAttack->GetUniqueID();
Stream.Write(&dwRootAttackerID, sizeof(DWORD));
Stream.Write(&dwPrevAttackerActorUniqueID, sizeof(DWORD));
Stream.Write(&dwActorToAttackID, sizeof(DWORD));
Stream.Write(&iActionIndex, sizeof(int));
Stream.Write(&iProjectileSignalArrayIndex, sizeof(int));
Stream.Write(&iSkillID, sizeof(int));
Send( eActor::SC_CHAINATTACK_PROJECTILE, &Stream );
}
void CDnActor::RemoveStateEffectByHitSignal(HitStruct* pHitStruct)
{
if (NULL == pHitStruct)
return;
//RemoveStateIndex±â´É ¸·À½ ¿äûÀ¸·Î ÀÎÇØ RemoveStateIndex´Â ¹«½Ã Çϵµ·Ï ¼öÁ¤ÇÔ.
#if defined(PRE_FIX_51988)
if (pHitStruct->szRemoveStateIndexList == NULL)
return;
#else
if (pHitStruct->RemoveStateIndex == 0 && pHitStruct->szRemoveStateIndexList == NULL)
return;
#endif // PRE_FIX_51988
#if defined(PRE_FIX_51988)
std::string str = pHitStruct->szRemoveStateIndexList ? pHitStruct->szRemoveStateIndexList : "";
#else
std::string str = FormatA("%d;%s", pHitStruct->RemoveStateIndex, pHitStruct->szRemoveStateIndexList ? pHitStruct->szRemoveStateIndexList : "");
#endif // PRE_FIX_51988
std::vector<std::string> tokens;
std::string delimiters = ";";
//1. »óÅÂÈ¿°ú À妽º ¸®½ºÆ®¿Í Àû¿ë ·¹º§ ±¸ºÐ
TokenizeA(str, tokens, delimiters);
for (int i = 0; i < (int)tokens.size(); ++i)
{
STATE_BLOW::emBLOW_INDEX eBlowIndex = (STATE_BLOW::emBLOW_INDEX)(atoi(tokens[i].c_str()));
if (eBlowIndex == STATE_BLOW::emBLOW_INDEX::BLOW_NONE)
continue;
//ÆÐŶ º¸³»°í...
SendRemoveStateEffect(eBlowIndex);
//¿©±â¼­´Â Á÷Á¢ ¹Ù·Î Áö¿î´Ù...
m_pStateBlow->RemoveImediatlyStateEffectByBlowIndex(eBlowIndex);
}
}
bool CDnActor::ProcessIgnoreHitSignal()
{
bool bIgnoreHitSignal = false;
DnBlowHandle hIgnoreHitSignalBlow;
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_228))
{
DNVector(DnBlowHandle) vecBlowList;
GatherAppliedStateBlowByBlowIndex(STATE_BLOW::BLOW_228, vecBlowList);
for (int i = 0; i < (int)vecBlowList.size(); ++i)
{
DnBlowHandle hBlow = vecBlowList[i];
if (hBlow && hBlow->CanBegin())
{
bIgnoreHitSignal = true;
hIgnoreHitSignalBlow = hBlow;
break;
}
}
}
//È÷Æ® ½Ã±×³Î ¹«½Ã°¡ ¼³Á¤ÀÌ µÇ¸é ÇØ´ç »óÅÂÈ¿°ú ÀÌÆåÆ® Ç¥½Ã¿ë ÆÐŶ ³¯¸®°í ´õÀÌ»ó µ¥¹ÌÁö ó¸® ¾ÈÇϵµ·Ï ÇÑ´Ù.
if (hIgnoreHitSignalBlow && bIgnoreHitSignal == true)
{
BYTE pBuffer[128];
CPacketCompressStream Stream( pBuffer, 128 );
DWORD dwUniqueID = GetUniqueID();
STATE_BLOW::emBLOW_INDEX stateBlowIndex = hIgnoreHitSignalBlow->GetBlowIndex();
bool bShowEffect = true;
Stream.Write( &dwUniqueID, sizeof(dwUniqueID) );
Stream.Write( &stateBlowIndex, sizeof(stateBlowIndex));
Stream.Write( &bShowEffect, sizeof(bShowEffect));
Send(eActor::SC_SHOW_STATE_EFFECT, &Stream);
return true;
}
return false;
}
bool CDnActor::ProcessIgnoreGravitySignal()
{
bool bIgnoreGravitySignal = false;
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_273 ) )
{
DNVector(DnBlowHandle) vecBlowList;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_273, vecBlowList );
for( int i=0; i<(int)vecBlowList.size(); ++i )
{
DnBlowHandle hBlow = vecBlowList[i];
if( hBlow && hBlow->CanBegin() )
{
bIgnoreGravitySignal = true;
break;
}
}
}
return bIgnoreGravitySignal;
}
void CDnActor::AddSkillStateEffect(DnSkillHandle hSkill)
{
m_ApplySkillStateEffectList.push_back(hSkill);
}
void CDnActor::ApplySkillStateEffect()
{
if (m_ApplySkillStateEffectList.empty())
return;
std::vector<DnSkillHandle>::iterator iter = m_ApplySkillStateEffectList.begin();
for (; iter != m_ApplySkillStateEffectList.end(); ++iter)
{
DnSkillHandle hSkill = *(iter);
if (hSkill)
{
DWORD stateCount = hSkill->GetStateEffectCount();
CDnStateBlow *pStateBlow = GetStateBlow();
const CDnSkill::SkillInfo* skillInfo = hSkill->GetInfo();
if (pStateBlow)
{
for (DWORD dwIndex = 0; dwIndex < stateCount; ++dwIndex)
{
CDnSkill::StateEffectStruct *pStateEffect = hSkill->GetStateEffectFromIndex(dwIndex);
if (pStateEffect == NULL || pStateEffect->ApplyType != CDnSkill::StateEffectApplyType::ApplySelf)
continue;
CDnSkill::CanApply eResult = CDnSkill::CanApply::Apply;
eResult = pStateBlow->CanApplySkillStateEffect(skillInfo, *pStateEffect);
if (CDnSkill::CanApply::Fail != eResult)
{
RemoveResetStateBlow();
int nBlowID = CmdAddStateEffect( skillInfo, (STATE_BLOW::emBLOW_INDEX)pStateEffect->nID,
pStateEffect->nDurationTime, pStateEffect->szValue.c_str(), false, false );
//Áö¼Ó ½Ã°£ÀÌ ¾ø´Â »óÅÂÈ¿°úÀÎ °æ¿ì ½ºÅ³¿¡ µî·Ï.
if (-1 != nBlowID && pStateEffect->nDurationTime == -1)
{
hSkill->AddSignalApplyNoPacketStateEffectHandle(nBlowID);
}
}
}
}
}
}
m_ApplySkillStateEffectList.clear();
}
void CDnActor::SendProbInvincibleSuccess( void )
{
BYTE pBuffer[ 4 ] = { 0 };
CPacketCompressStream Stream( pBuffer, 4 );
Send( eActor::SC_PROBINVINCIBLE_SUCCESS, &Stream );
}
EtVector3 CDnActor::FindAutoTargetPos()
{
EtVector3 vTargetPosition = *GetPosition();
if( !m_FindAutoTargetName.empty())
{
int nBoneIndex = GetBoneIndex( m_FindAutoTargetName.c_str() );
if( nBoneIndex != -1 )
{
EtMatrix boneMatrix = GetBoneMatrix(m_FindAutoTargetName.c_str());
vTargetPosition = *(EtVector3*)&boneMatrix._41;
}
}
return vTargetPosition;
}
void CDnActor::ApplyStateEffectSignalProcess( const S_NO_PACKET_SELF_STATEBLOW &StateBlowInfo, ApplyStateEffectStruct* pStruct )
{
// StateBlowÀÇ »ç¿ë ¿©ºÎ È®ÀÎ ¸ÕÀú [2010/11/11 semozz]
if (false == StateBlowInfo.bUsed)
{
CDnSkill::CanApply eResult = CDnSkill::CanApply::Apply;
// [2010/11/11 semozz]
// ¿©±â µî·ÏµÇ¾î ÀÖ´Â ½ºÅ³ÀÇ StateBlowµµ »ç¿ë °¡´ÉÇÑÁö È®ÀÎ ÈÄ CmdAddStateEffect¸¦ È£Ãâ ÇØ¾ß ÇÑ´Ù.
// CDnSkillÀÇ OnBegin¿¡¼­ üũ ½ÃÁ¡¿¡¼­´Â »ç¿ë °¡´ÉÀÌÁö¸¸, ¿©±â È£Ãâ Àü¿¡ ´Ù¸¥ StateBlow°¡ µî·Ï µÇ¾î ÀÖÀ» ¼ö ÀÖ´Ù.
// #20008ÀÇ ÈúÀ» µ¿½Ã¿¡ »ç¿ë½Ã ÀÌ·± ¹®Á¦Á¡ÀÌ ¹ß»ý.
eResult = m_pStateBlow->CanApplySkillStateEffect(&StateBlowInfo.ParentSkillInfo, StateBlowInfo.StateEffect);
if( CDnSkill::CanApply::Fail != eResult )
{
// [2010/12/08 semozz]
// ½ºÅ³ »ç¿ë ½ÃÁ¡ÀÇ CanApplySkillStateEffectÇÔ¼ö¿¡¼­ ¸®¼Â ½Ãų »óÅÂµé ¸®½ºÆ®¿¡ ´ã¾Æ ³õÀº°ÍµéÀ»
// ¿©±â¼­ Á¦°Å ÇÑ´Ù.
RemoveResetStateBlow();
// Note Çѱâ: ½ºÅ³ÀÌ ¹ßµ¿µÉ ½Ã¿¡ Àڽſ¡°Ô ½ºÅ³ ¾×¼Ç ½Ã°£ µ¿¾È Áï½Ã °É¸®´Â »óÅÂÈ¿°ú´Â
// ÇØÁ¦ ½ÃÁ¡À» ½ºÅ³ °´Ã¼°¡ ¾Ë°í ÀÖÀ¸¹Ç·Î ½ºÅ³ °´Ã¼ÂÊÀÇ nopacket »óÅÂÈ¿°ú. ¸®½ºÆ®¿¡ ³Ö¾îÁØ´Ù.
// nopacket »óÅÂÈ¿°ú´Â Ŭ¶óÀÌ¾ðÆ®¿¡¼­µµ ½ºÅ³ÀÌ ½ÇÇàµÇ¸é ¾Ë¾Æ¼­ Ãß°¡ÇÏ°í »©ÁØ´Ù.
// ±×³É Àڽſ¡°Ô °Å´Â ¹öÇÁ °Å´Â Áö¼Ó½Ã°£ÀÌ ÀÖ´Â »óÅÂÈ¿°ú´Â Áö¼Ó½Ã°£ÀÌ Á¤ÇØÁ® ÀÖÀ¸¹Ç·Î ½Ã°£ ´Ù µÇ¸é
// ¾Ë¾Æ¼­ Á¦°ÅµÇ¹Ç·Î ±âÁ¸ ½Ã½ºÅÛÀ» ±×´ë·Î »ç¿ëÇØ¼­ CmdAddStateEffect ½ÃŲ´Ù. ÆÐŶµµ ¾Ë¾Æ¼­ ½÷ÁÜ. ÀÌ °æ¿ì¿£ Ŭ¶ó¿¡¼­ »óÅÂÈ¿°ú ¹ßµ¿½ÃŰÁö ¾Ê°í
// ¼­¹öÀÇ ÆÐŶÀ» ±â´Ù¸°´Ù.
if( StateBlowInfo.StateEffect.ApplyType == CDnSkill::ApplySelf &&
StateBlowInfo.StateEffect.nDurationTime == -1 /*&& // ¹öÇÁ/µð¹öÇÁ/¿À¶ó µîµîµµ µÉ ¼ö Àֱ⠶§¹®¿¡ ÀÌ Á¶°ÇÀº ºüÁý´Ï´Ù.
CDnSkill::Instantly == StateBlowInfo.ParentSkillInfo.eDurationType*/ )
{
// [2010/12/09 semozz]
// »óÅÂÈ¿°ú Ãß°¡ ÆÐŶÀ» º¸³»¾ß ÇÑ´Ù.
int iBlowID = CmdAddStateEffect( &StateBlowInfo.ParentSkillInfo, (STATE_BLOW::emBLOW_INDEX)StateBlowInfo.StateEffect.nID,
StateBlowInfo.StateEffect.nDurationTime, StateBlowInfo.StateEffect.szValue.c_str() );
if( -1 != iBlowID )
{
if( m_hProcessSkill )
{
//_ASSERT( m_hProcessSkill && -1 != iBlowID );
// ºí·Ï »óÅÂÈ¿°ú (30¹ø)Àº Áö¼Ó½Ã°£ÀÌ ¾ø´Â ÄÁ¼ÁÀ¸·Î º¯°æµÇ¾úÀ¸¹Ç·Î ¿¹¿Ü·Î ¿©±â¿¡ Ãß°¡½ÃÄÑÁÖÁö ¾Ê´Â´Ù.
// Ãß°¡ ½ÃŰ¸é ¾×¼ÇÀÌ ³¡³ª´Â ¼ø°£ °°ÀÌ Á¾·áµÊ. 2010.09.20
if( !((-1 == StateBlowInfo.StateEffect.nDurationTime) &&
(STATE_BLOW::BLOW_030 == StateBlowInfo.StateEffect.nID)) )
m_hProcessSkill->AddSignalApplyNoPacketStateEffectHandle( iBlowID );
}
else
if( m_hAuraSkill && CDnSkill::Aura == StateBlowInfo.ParentSkillInfo.eDurationType )
{
m_hAuraSkill->AddSignalApplyNoPacketStateEffectHandle( iBlowID );
}
#ifdef _DEBUG
else
_ASSERT( !"»óÅÂÈ¿°ú ¼³Á¤ÇÑ ½Ã±×³Î ŸÀÌ¹Ö Ãß°¡ ½ÇÆÐ!!" );
#endif
}
}
else
{
// Áö¼Ó½Ã°£ÀÌ ÀÖ´Â self »óÅÂÈ¿°ú
int iBlowID = CmdAddStateEffect( &StateBlowInfo.ParentSkillInfo, (STATE_BLOW::emBLOW_INDEX)StateBlowInfo.StateEffect.nID,
StateBlowInfo.StateEffect.nDurationTime, StateBlowInfo.StateEffect.szValue.c_str() );
}
}
// ½ºÅ³ »ç¿ë ³¡³µÀ¸¸é ¸®¼Â¸®½ºÆ® ÃʱâÈ­ [2010/12/09 semozz]
InitStateBlowIDToRemove();
// ½ºÅ³ »ç¿ëÀ» ¸øÇصµ »ç¿ëÇÑ°É·Î ÇØ¾ßÇÏ´ÂÁö´Â È®ÀÎ ÇØºÁ¾ß ÇÒµí [2010/11/11 semozz]
const_cast<S_NO_PACKET_SELF_STATEBLOW&>(StateBlowInfo).Used();
}
else
{
OutputDebug( "[Error!!] »óÅÂÈ¿°ú Àû¿ë ½Ã±×³Î¿¡¼­ ÀÌ¹Ì »ç¿ëÇÑ »óÅÂÈ¿°ú À妽º(%d) »ç¿ë!!\n", pStruct->StateEffectIndex );
_ASSERT( !"»óÅÂÈ¿°ú Àû¿ë ½Ã±×³Î¿¡¼­ ÀÌ¹Ì »ç¿ëÇÑ »óÅÂÈ¿°ú À妽º »ç¿ë!!" );
}
}
#if defined(PRE_FIX_51048)
void CDnActor::RemoveDebufAction(LOCAL_TIME LocalTime, float fDelta)
{
//Freezing
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_041 ) )
{
DNVector(DnBlowHandle) vlBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_041, vlBlows );
int nBlowCount = (int)vlBlows.size();
for (int i = 0; i < nBlowCount; ++i)
{
DnBlowHandle hBlow = vlBlows[i];
if (hBlow)
hBlow->RemoveDebufAction(LocalTime, fDelta);
}
}
//Frostbite
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_144 ) )
{
DNVector(DnBlowHandle) vlBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_144, vlBlows );
int nBlowCount = (int)vlBlows.size();
for (int i = 0; i < nBlowCount; ++i)
{
DnBlowHandle hBlow = vlBlows[i];
if (hBlow)
hBlow->RemoveDebufAction(LocalTime, fDelta);
}
}
//ElectricShock
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_043 ) )
{
DNVector(DnBlowHandle) vlBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_043, vlBlows );
int nBlowCount = (int)vlBlows.size();
for (int i = 0; i < nBlowCount; ++i)
{
DnBlowHandle hBlow = vlBlows[i];
if (hBlow)
hBlow->RemoveDebufAction(LocalTime, fDelta);
}
}
//Escape
if( IsAppliedThisStateBlow( STATE_BLOW::BLOW_218 ) )
{
DNVector(DnBlowHandle) vlBlows;
GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_218, vlBlows );
int nBlowCount = (int)vlBlows.size();
for (int i = 0; i < nBlowCount; ++i)
{
DnBlowHandle hBlow = vlBlows[i];
if (hBlow)
hBlow->RemoveDebufAction(LocalTime, fDelta);
}
}
}
#endif // PRE_FIX_51048
void CDnActor::SetState(ActorStateEnum State)
{
#if defined(PRE_FIX_59939)
//¸Å ÇÁ·¹ÀÓ SetState°¡ È£Ãâ µÇÁö¸¸ ÀúÁÖ»óÅÂÈ¿°ú(244)¿¡¼­ ÀÚü ÄðŸÀÓ Á¦¾îÇϱ⿡ ±×³É È£Ãâ Çϵµ·Ï ÇÑ´Ù...
//
__super::SetState(State);
bool isAttackState = IsAttack();
if (isAttackState)
OnAttackChange();
#else
bool isPreAttackState = IsAttack();
__super::SetState(State);
bool isNewAttackState = IsAttack();
if (isPreAttackState == false && isNewAttackState == true)
OnAttackChange();
#endif // PRE_FIX_59939
}
void CDnActor::OnAttackChange()
{
if (IsAppliedThisStateBlow(STATE_BLOW::BLOW_244))
{
DNVector(DnBlowHandle) vlBlows;
GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_244, vlBlows );
int nBlowCount = (int)vlBlows.size();
for (int i = 0; i < nBlowCount; ++i)
{
DnBlowHandle hBlow = vlBlows[i];
if (hBlow)
{
CDnCurseBlow* pCurseBlow = dynamic_cast<CDnCurseBlow*>(hBlow.GetPointer());
if (pCurseBlow)
pCurseBlow->OnAttackChange();
}
}
}
}
int CDnActor::ExceptionHitList(DNVector(DnActorHandle) &hVecList, MatrixEx& Cross, DnActorHandle hHiterActor, HitStruct* pStruct)
{
std::map<DWORD, DnActorHandle> hOwnerActorList; //²ÀµÎ°¢½Ã »óÅÂÈ¿°ú¸¦ °¡Áö°í ÀÖ´Â ÁÖÀξ×ÅÍ Èĺ¸? ¸®½ºÆ®
std::map<DWORD, DnActorHandle> eraseActorList; //Á¦°Å µÇ¾î¾ß ÇÒ ¾×ÅÍ ¸®½ºÆ®
std::vector<CDnMonsterActor*> hSummonActorList; //¼ÒȯµÈ ¸ó½ºÅÍ ¾×ÅÍ ¸®½ºÆ®
DNVector(DnActorHandle) hNewVecList; //»õ·Î¿î ¾×ÅÍ ¸®½ºÆ®
int nWeaponLength = 0;
bool bOnDamageCalled = false;
if (hHiterActor)
{
if( pStruct->bIncludeWeaponLength && hHiterActor->GetWeapon() )
nWeaponLength = hHiterActor->GetWeapon()->GetWeaponLength();
}
MatrixEx CrossTemp = Cross;
// ½ºÄÉÀÏµÈ ¸ó½ºÅÍÀÇ °æ¿ì È÷Æ® ½Ã±×³ÎÀÇ Áß½ÉÃàÀÌ Ç×»ó ¾×ÅÍÀÇ ¿øÁ¡ À§Ä¡°¡ ¸Â´Â °ÍÀº ¾Æ´Ï±â ¶§¹®¿¡
// ¿ÀÇÁ¼Â¿¡µµ Á¤È®ÇÏ°Ô ½ºÄÉÀÏ °ªÀ» Àû¿ë½ÃÄÑ Áà¾ß ÇÑ´Ù.(#18971)
EtVector3 vScale = EtVector3(1.0f, 1.0f, 1.0f);
if (hHiterActor)
vScale = *hHiterActor->GetScale();
EtVector3 vOffset = *pStruct->vOffset * vScale.y;
CrossTemp.MoveLocalZAxis( vOffset.z );
CrossTemp.MoveLocalXAxis( vOffset.x );
CrossTemp.MoveLocalYAxis( vOffset.y );
// ƯÁ¤ º»°ú ¸µÅ©µÈ »óŶó¸é..
if( hHiterActor &&
pStruct->szLinkBoneName && strlen(pStruct->szLinkBoneName) > 0 )
{
int nBoneIndex = hHiterActor->GetBoneIndex( pStruct->szLinkBoneName );
if( -1 != nBoneIndex )
{
EtMatrix matBoneWorld = hHiterActor->GetBoneMatrix( pStruct->szLinkBoneName );
EtMatrixMultiply( (EtMatrix*)&CrossTemp, (EtMatrix*)&CrossTemp, &matBoneWorld );
}
}
// ¸ó½ºÅÍ´Â ½ºÄÉÀÏ¿¡µû¶ó º¸Á¤ÇØÁà¾ßÇÑ´Ù.
float fDistanceMax = pStruct->fDistanceMax * vScale.y;
float fDistanceMin = pStruct->fDistanceMin * vScale.y;
float fHeightMax = pStruct->fHeightMax * vScale.y;
///////////////////////////////////////////////
EtVector3 vPos = CrossTemp.m_vPosition;
float fDistance = max( fDistanceMax, fHeightMax - pStruct->fHeightMin ) + nWeaponLength;
float fXZDistanceSQ = fDistanceMax + nWeaponLength;
float fXZDistanceMinSQ = fDistanceMin; // Min Àº Weapon ±æÀÌ ¿µÇâ¾È¹Þ½À´Ï´Ù.
fXZDistanceSQ *= fXZDistanceSQ;
fXZDistanceMinSQ *= fXZDistanceMinSQ;
EtVector3 vDir;
EtVector3 vZVec = Cross.m_vZAxis;
if( pStruct->fCenterAngle != 0.f )
{
EtMatrix matRotate;
EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) );
EtVec3TransformNormal( &vZVec, &vZVec, &matRotate );
}
SAABox Box;
float fDot = 0.0f;
#if defined(PRE_FIX_59680)
int nMyTeamID = -1;
if (hHiterActor)
{
nMyTeamID = hHiterActor->GetTeam();
if (hHiterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
nMyTeamID = hHiterActor->GetOriginalTeam();
}
#endif // PRE_FIX_59680
int nListCount = (int)hVecList.size();
for (int i = 0; i < nListCount; ++i)
{
DnActorHandle hActor = hVecList[i];
if (!hActor)
continue;
switch( hActor->GetHitCheckType() )
{
case HitCheckTypeEnum::BoundingBox:
{
vDir = *hActor->GetPosition() - vPos;
vDir.y = 0.f;
hActor->GetBoundingBox( Box );
if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue;
if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue;
EtVec3Normalize( &vDir, &vDir );
fDot = EtVec3Dot( &vZVec, &vDir );
if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue;
if( Box.Min.y < vPos.y + pStruct->fHeightMin &&
Box.Max.y < vPos.y + pStruct->fHeightMin ) continue;
if( Box.Min.y > vPos.y + fHeightMax &&
Box.Max.y > vPos.y + fHeightMax ) continue;
}
break;
case HitCheckTypeEnum::Collision:
{
SCollisionCapsule Capsule;
SCollisionResponse CollisionResult;
DNVector(SCollisionResponse) vCollisionResult;
//
Capsule.Segment.vOrigin = vPos;
float fHeight = fHeightMax - pStruct->fHeightMin;
Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) );
Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f );
Capsule.fRadius = ( fDistanceMax + nWeaponLength );
//int nParentBoneIndex = -1;
EtVector3 vDestPos;
if( hActor->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false )
continue;
}
}
//²ÀµÎ°¢½Ã »óÅÂÈ¿°ú°¡ ÀÖ´Â ÁÖÀξ×ÅÍ Èĺ¸ ¸®½ºÆ®¸¦ ¸¸µç´Ù..
if (hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_247))
{
hOwnerActorList.insert(std::make_pair(hActor->GetUniqueID(), hActor));
}
//²ÀµÎ°¢½Ã·Î ¼ÒȯµÈ ¸ó½ºÅÍ ¸®½ºÆ®¸¦ ¸¸µç´Ù..
else if (hActor->IsMonsterActor())
{
CDnMonsterActor* pMonsterActor = static_cast<CDnMonsterActor*>(hActor.GetPointer());
if (pMonsterActor &&
pMonsterActor->IsSummonedMonster() &&
pMonsterActor->IsPuppetSummonMonster())
{
#if defined(PRE_FIX_59680)
//·¼¸¯¿ÀºêÈú ½ºÅ³ÀÇ °æ¿ì ·¼¸¯Àº °°Àº ÆÀÀ¸·Î ¼³Á¤À̵Ê.
//·¼¸¯ÀÇ Hit½Ã±×³Î 󸮽à ¼­¸Õ ÆÛÆêÀÌ ¸®½ºÆ® Ãß°¡°¡ µÇ°í, ¾Æ·¡¿¡¼­ ÁÖÀÎ ¾×ÅͰ¡ Á¦¿Ü µÇ¾î¼­ ÈúÀÌ Á¤»ó ó¸® µÇÁö ¾Ê´Â ¹®Á¦°¡ ¹ß»ýÇÔ.
//°°Àº ÆÀÀÇ ¼­¸ÕÆÛÆêÀº ÀÌ ¸®½ºÆ®¿¡ Á¦¿Ü µÇ¾î¾ßÇÑ´Ù.
int nTargetTeam = hActor->GetTeam();
if (hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
nTargetTeam = hActor->GetOriginalTeam();
//¹ß»çü¿¡¼­ Hiter¾×ÅͰ¡ ¾øÀ» ¼ö ÀÖ´Ù. PropÀÎ °æ¿ì(Hiter¾×ÅͰ¡ ¾ø´Â °æ¿ì´Â Ãß°¡)
if (hHiterActor)
{
//¼­¸Õ ÆÛÆêÀÌ ´Ù¸¥ ÆÀÀÎ °æ¿ì ¼­¸Õ¾×ÅÍ ¸®½ºÆ®¿¡ Ãß°¡ Çϰí
//°°Àº ÆÀÀÎ °æ¿ì Áö¿ï ¸®½ºÆ®¿¡ ¼­¸ÓÆÛÆê ¾×Å͸¦ Ãß°¡Çؼ­ ÃÖÁ¾ ¸®½ºÆ®¿¡ Áö¿ö Áöµµ·Ï ÇÑ´Ù.
if (nMyTeamID != nTargetTeam)
hSummonActorList.push_back(pMonsterActor);
else
eraseActorList.insert(std::make_pair(hActor->GetUniqueID(), hActor));
}
else
hSummonActorList.push_back(pMonsterActor);
#else
hSummonActorList.push_back(pMonsterActor);
#endif // PRE_FIX_59680
}
}
}
//¼Òȯ ¸ó½ºÅÍ ¾×ÅͰ¡ ÀÖ´Â °æ¿ì
//¼Òȯ ¸ó½ºÅÍ ¾×ÅÍÀÇ ÁÖÀÎ ¾×ÅͰ¡ Á¸Àç ÇÏ´Â Áö È®ÀÎ ÇØ¼­, ÁÖÀÎ ¾×ÅͰ¡ Á¸Àç Çϸé
//Áö¿ï¸®½ºÆ®¿¡ ÁÖÀÎ ¾×Å͸¦ Ãß°¡ ÇØ ³õ´Â´Ù.
int nSummonActorList = (int)hSummonActorList.size();
for (int iIndex = 0; iIndex < nSummonActorList; ++iIndex)
{
CDnMonsterActor* pSummonMonsterActor = hSummonActorList[iIndex];
//¼Òȯ¾×ÅÍÀÇ ÁÖÀÎ ¾×Å͸¦ È®ÀÎ ÇÑ´Ù.
DnActorHandle hOwnerActor = pSummonMonsterActor->GetSummonerPlayerActor();
DWORD dwOwnerUniqueID = hOwnerActor ? hOwnerActor->GetUniqueID() : -1;
if (dwOwnerUniqueID == -1)
continue;
//ÁÖÀÎÈĺ¸ ¾×ÅÍ ¸®½ºÆ®¿¡¼­ ¾×Å͸¦ ã´Â´Ù.
std::map<DWORD, DnActorHandle>::iterator findIter = hOwnerActorList.find(dwOwnerUniqueID);
if (findIter != hOwnerActorList.end())
{
//»èÁ¦ ¾×ÅÍ ¸®½ºÆ®¿¡ Ãß°¡ ÇÑ´Ù.
eraseActorList.insert(std::make_pair(dwOwnerUniqueID, hOwnerActor));
}
}
nListCount = (int)hVecList.size();
for (int i = 0; i < nListCount; ++i)
{
DnActorHandle hActor = hVecList[i];
if (!hActor)
continue;
//¿ø·¡ ¾×ÅÍ ¸®½ºÆ®¸¦ µ¹¸é¼­, Áö¿ö¾ß ÇÒ ¾×ÅÍ ¸®½ºÆ®¿¡ ãÁö ¸ø ÇÏ¸é »õ·Î¿î ¸®½ºÆ®¿¡ Ãß°¡ ÇÑ´Ù.
DWORD dwOwnerUniqueID = hActor->GetUniqueID();
std::map<DWORD, DnActorHandle>::iterator findIter = eraseActorList.find(dwOwnerUniqueID);
if (findIter == eraseActorList.end())
hNewVecList.push_back(hActor);
}
std::swap(hVecList, hNewVecList);
return (int)hVecList.size();
}
//½ºÄµµÈ ¾×ÅÍ ¸®½ºÆ®Áß Hit¿µ¿ª¿¡ ÀÖ´Â ³à¼®µé¸¸ ¸®½ºÆ®¸¦ ¸¸µç´Ù.
void CDnActor::CheckHitAreaActorList(DNVector(DnActorHandle)& hVecList, MatrixEx& Cross, DnActorHandle hHiterActor, HitStruct* pStruct, int nCheckType, float fScanLength, EtVector3& vPrePos)
{
DNVector(DnActorHandle) hNewVecList; //»õ·Î¿î ¾×ÅÍ ¸®½ºÆ®
int nWeaponLength = 0;
bool bOnDamageCalled = false;
if (hHiterActor)
{
if( pStruct->bIncludeWeaponLength && hHiterActor->GetWeapon() )
nWeaponLength = hHiterActor->GetWeapon()->GetWeaponLength();
}
MatrixEx CrossTemp = Cross;
// ½ºÄÉÀÏµÈ ¸ó½ºÅÍÀÇ °æ¿ì È÷Æ® ½Ã±×³ÎÀÇ Áß½ÉÃàÀÌ Ç×»ó ¾×ÅÍÀÇ ¿øÁ¡ À§Ä¡°¡ ¸Â´Â °ÍÀº ¾Æ´Ï±â ¶§¹®¿¡
// ¿ÀÇÁ¼Â¿¡µµ Á¤È®ÇÏ°Ô ½ºÄÉÀÏ °ªÀ» Àû¿ë½ÃÄÑ Áà¾ß ÇÑ´Ù.(#18971)
EtVector3 vScale = EtVector3(1.0f, 1.0f, 1.0f);
if (hHiterActor)
vScale = *hHiterActor->GetScale();
EtVector3 vOffset = *pStruct->vOffset * vScale.y;
CrossTemp.MoveLocalZAxis( vOffset.z );
CrossTemp.MoveLocalXAxis( vOffset.x );
CrossTemp.MoveLocalYAxis( vOffset.y );
// ƯÁ¤ º»°ú ¸µÅ©µÈ »óŶó¸é..
if( pStruct->szLinkBoneName && strlen(pStruct->szLinkBoneName) > 0 )
{
int nBoneIndex = hHiterActor->GetBoneIndex( pStruct->szLinkBoneName );
if( -1 != nBoneIndex )
{
EtMatrix matBoneWorld = hHiterActor->GetBoneMatrix( pStruct->szLinkBoneName );
EtMatrixMultiply( (EtMatrix*)&CrossTemp, (EtMatrix*)&CrossTemp, &matBoneWorld );
}
}
// ¸ó½ºÅÍ´Â ½ºÄÉÀÏ¿¡µû¶ó º¸Á¤ÇØÁà¾ßÇÑ´Ù.
float fDistanceMax = pStruct->fDistanceMax * vScale.y;
float fDistanceMin = pStruct->fDistanceMin * vScale.y;
float fHeightMax = pStruct->fHeightMax * vScale.y;
///////////////////////////////////////////////
EtVector3 vPos = CrossTemp.m_vPosition;
float fDistance = max( fDistanceMax, fHeightMax - pStruct->fHeightMin ) + nWeaponLength;
float fXZDistanceSQ = fDistanceMax + nWeaponLength;
float fXZDistanceMinSQ = fDistanceMin; // Min Àº Weapon ±æÀÌ ¿µÇâ¾È¹Þ½À´Ï´Ù.
fXZDistanceSQ *= fXZDistanceSQ;
fXZDistanceMinSQ *= fXZDistanceMinSQ;
EtVector3 vDir;
EtVector3 vZVec = Cross.m_vZAxis;
if( pStruct->fCenterAngle != 0.f )
{
EtMatrix matRotate;
EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) );
EtVec3TransformNormal( &vZVec, &vZVec, &matRotate );
}
SAABox Box;
float fDot = 0.0f;
int nListCount = (int)hVecList.size();
for (int i = 0; i < nListCount; ++i)
{
DnActorHandle hActor = hVecList[i];
if (!hActor)
continue;
if( !hActor->GetObjectHandle() )
continue;
switch( hActor->GetHitCheckType() )
{
case HitCheckTypeEnum::BoundingBox:
{
switch(nCheckType)
{
case 0: //CDnActorÀÇ OnSignal¿¡ Àִ üũ ¹æ½Ä...
{
vDir = *hActor->GetPosition() - vPos;
vDir.y = 0.f;
hActor->GetBoundingBox( Box );
if( SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue;
if( SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue;
EtVec3Normalize( &vDir, &vDir );
fDot = EtVec3Dot( &vZVec, &vDir );
if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue;
if( Box.Min.y < vPos.y + pStruct->fHeightMin &&
Box.Max.y < vPos.y + pStruct->fHeightMin ) continue;
if( Box.Min.y > vPos.y + fHeightMax &&
Box.Max.y > vPos.y + fHeightMax ) continue;
}
break;
case 1: //ProjectileÀÇ Ã¹¹øÂ° üũ ¹æ½Ä.
{
float fPropContactDistance = FLT_MAX;
float fNowFrameActorContactDistanceSQ = FLT_MAX;
vDir = *hActor->GetPosition() - vPos;
vDir.y = 0.f;
hActor->GetBoundingBox( Box );
if( CDnActor::SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue;
if( CDnActor::SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue;
EtVec3Normalize( &vDir, &vDir );
fDot = EtVec3Dot( &vZVec, &vDir );
if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue;
if( Box.Min.y < vPos.y + pStruct->fHeightMin &&
Box.Max.y < vPos.y + pStruct->fHeightMin ) continue;
if( Box.Min.y > vPos.y + pStruct->fHeightMax &&
Box.Max.y > vPos.y + pStruct->fHeightMax ) continue;
fNowFrameActorContactDistanceSQ = EtVec3LengthSq( &EtVector3( vPos - vPrePos ) );
if( fNowFrameActorContactDistanceSQ > fPropContactDistance ) continue;
}
break;
case 2: //ProjectileÀÇ µÎ¹øÂ° üũ ¹æ½Ä
{
bool bResult = false;
float fPropContactDistance = FLT_MAX;
float fNowFrameActorContactDistanceSQ = FLT_MAX;
SCollisionResponse Response;
DNVector(SCollisionResponse) vResponse;
float fThickness = max( fabs( pStruct->fHeightMin ), fabs( pStruct->fHeightMax ) );
SSegment Segment;
Segment.vOrigin = vPrePos;
Segment.vDirection = Cross.m_vZAxis * fScanLength;
SCollisionCapsule Capsule;
Capsule.Segment = Segment;
Capsule.fRadius = fThickness;
if( fThickness == 0.f ) bResult = hActor->GetObjectHandle()->FindSegmentCollision( Segment, Response );
else bResult = hActor->GetObjectHandle()->FindCapsuleCollision( Capsule, Response );
fNowFrameActorContactDistanceSQ = EtVec3LengthSq( &EtVector3( *hActor->GetPosition() - vPrePos ) );
if( fNowFrameActorContactDistanceSQ > fPropContactDistance ) continue;
if (bResult == false)
continue;
}
break;
}
}
break;
case HitCheckTypeEnum::Collision:
{
switch(nCheckType)
{
case 0://CDnActorÀÇ OnSignal üũ ¹æ½Ä..
{
SCollisionCapsule Capsule;
SCollisionResponse CollisionResult;
DNVector(SCollisionResponse) vCollisionResult;
//
Capsule.Segment.vOrigin = vPos;
float fHeight = fHeightMax - pStruct->fHeightMin;
Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) );
Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f );
Capsule.fRadius = ( fDistanceMax + nWeaponLength );
//int nParentBoneIndex = -1;
EtVector3 vDestPos;
if( hActor->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false )
continue;
}
break;
case 1://ProjectileÀÇ Ã¹¹øÂ° üũ ¹æ½Ä..
{
SCollisionCapsule Capsule;
SCollisionResponse CollisionResult;
DNVector(SCollisionResponse) vCollisionResult;
//
Capsule.Segment.vOrigin = vPos;
float fHeight = pStruct->fHeightMax - pStruct->fHeightMin;
Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) );
Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f );
Capsule.fRadius = pStruct->fDistanceMax;
//int nParentBoneIndex = -1;
EtVector3 vDestPos;
if( hActor->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false )
continue;
}
break;
case 2://ProjectileÀÇ µÎ¹øÂ° üũ ¹æ½Ä..
{
float fPropContactDistance = FLT_MAX;
float fNowFrameActorContactDistanceSQ = FLT_MAX;
bool bResult = false;
float fThickness = max( fabs( pStruct->fHeightMin ), fabs( pStruct->fHeightMax ) );
SSegment Segment;
Segment.vOrigin = vPrePos;
Segment.vDirection = Cross.m_vZAxis * fScanLength;
SCollisionCapsule Capsule;
Capsule.Segment = Segment;
Capsule.fRadius = fThickness;
SCollisionResponse Response;
DNVector(SCollisionResponse) vResponse;
int nParentBoneIndex = -1;
EtVector3 vDestPos;
if( fThickness == 0.f )
bResult = hActor->GetObjectHandle()->FindSegmentCollision( Segment, Response, &vResponse );
else
bResult = hActor->GetObjectHandle()->FindCapsuleCollision( Capsule, Response, &vResponse );
if (bResult)
{
fNowFrameActorContactDistanceSQ = EtVec3LengthSq( &EtVector3( Segment.vDirection * Response.fContactTime ) );
if( fNowFrameActorContactDistanceSQ > fPropContactDistance ) continue;
}
else
continue;
}
break;
}
}
}
hNewVecList.push_back(hActor);
}
std::swap(hVecList, hNewVecList);
}
int CDnActor::ExceptionHitList2(DNVector(DnActorHandle) &hVecList, MatrixEx& Cross, DnActorHandle hHiterActor, HitStruct* pStruct,
DNVector(DnActorHandle)& hAddStateEffectActorList,
int nCheckType, float fScanLength, EtVector3& vPrePos)
{
//È÷Æ® ¿µ¿ª¿¡ ÀÖ´Â ¾×Å͵鸸 ¸®½ºÆ®¿¡ ´ã´Â´Ù...
CDnActor::CheckHitAreaActorList(hVecList, Cross, hHiterActor, pStruct, nCheckType, fScanLength, vPrePos);
int nMyTeamID = -1;
if (hHiterActor)
{
nMyTeamID = hHiterActor->GetTeam();
if (hHiterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
nMyTeamID = hHiterActor->GetOriginalTeam();
}
struct _PuppetNOwnerInfo
{
DWORD dwOwnerID;
CDnMonsterActor* pPuppetMonster;
DnActorHandle hPuppetActor;
DnActorHandle hOwnerActor;
};
std::map<DWORD, _PuppetNOwnerInfo> PuppetnOnwerInfoList;
DNVector(DnActorHandle) hNewVecList; //»õ·Î¿î ¾×ÅÍ ¸®½ºÆ®
EtVector3 vPos = *hHiterActor->GetPosition();
int nListCount = (int)hVecList.size();
for (int i = 0; i < nListCount; ++i)
{
DnActorHandle hActor = hVecList[i];
if (!hActor)
continue;
bool bSeperated = false;
//²ÀµÎ°¢½Ã »óÅÂÈ¿°ú°¡ ÀÖ´Â ÁÖÀξ×ÅÍ Èĺ¸ ¸®½ºÆ®¸¦ ¸¸µç´Ù..
if (hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_247))
{
bSeperated = true;
DWORD dwOwnerUniqueID = hActor->GetUniqueID();
std::map<DWORD, _PuppetNOwnerInfo>::iterator findIter = PuppetnOnwerInfoList.find(dwOwnerUniqueID);
if (findIter == PuppetnOnwerInfoList.end())
{
_PuppetNOwnerInfo _info;
_info.dwOwnerID = dwOwnerUniqueID;
_info.hOwnerActor = hActor;
PuppetnOnwerInfoList.insert(std::make_pair(dwOwnerUniqueID, _info));
}
else
{
_PuppetNOwnerInfo& _info = findIter->second;
_info.hOwnerActor = hActor;
}
}
//²ÀµÎ°¢½Ã·Î ¼ÒȯµÈ ¸ó½ºÅÍ ¸®½ºÆ®¸¦ ¸¸µç´Ù..
else if (hActor->IsMonsterActor())
{
CDnMonsterActor* pMonsterActor = static_cast<CDnMonsterActor*>(hActor.GetPointer());
if (pMonsterActor &&
pMonsterActor->IsSummonedMonster() &&
pMonsterActor->IsPuppetSummonMonster())
{
bSeperated = true;
DnActorHandle hOwnerActor = pMonsterActor->GetSummonerPlayerActor();
DWORD dwOwnerUniqueID = hOwnerActor ? hOwnerActor->GetUniqueID() : -1;
std::map<DWORD, _PuppetNOwnerInfo>::iterator findIter = PuppetnOnwerInfoList.find(dwOwnerUniqueID);
if (findIter == PuppetnOnwerInfoList.end())
{
_PuppetNOwnerInfo _info;
_info.dwOwnerID = dwOwnerUniqueID;
_info.hPuppetActor = hActor;
_info.pPuppetMonster = pMonsterActor;
PuppetnOnwerInfoList.insert(std::make_pair(dwOwnerUniqueID, _info));
}
else
{
_PuppetNOwnerInfo& _info = findIter->second;
_info.hPuppetActor = hActor;
_info.pPuppetMonster = pMonsterActor;
}
}
}
//ÁÖÀÎ ¾×ÅÍ/ ¼Òȯ ¾×ÅÍ ¸®½ºÆ®¿¡ Æ÷ÇÔµÇÁö ¾Ê´Â ³à¼®µéÀº »õ·Î¿î ¸®½ºÆ®¿¡ ¹Ì¸® ´ã¾Æ ³õ´Â´Ù.
if (bSeperated == false)
hNewVecList.push_back(hActor);
}
std::map<DWORD, _PuppetNOwnerInfo>::iterator iter = PuppetnOnwerInfoList.begin();
std::map<DWORD, _PuppetNOwnerInfo>::iterator endIter = PuppetnOnwerInfoList.end();
for (; iter != endIter; ++iter)
{
_PuppetNOwnerInfo& _info = iter->second;
if (_info.hOwnerActor && _info.hPuppetActor)
{
/*
//Á¦ÀÏ °¡±î¿î ¾×Å͸¦ Ãß°¡ ÇÑ´Ù.
//ÁÖÀÎ ¾×ÅͰ¡ Á¦¿Ü µÇ´Â °æ¿ì Á¦¿ÜµÈ ¾×ÅÍ ¸®½ºÆ®¿¡ Ãß°¡ ÇØ ³õ´Â´Ù.(»óÅÂÈ¿°ú Ãß°¡¸¦ À§ÇØ)
EtVector3 vOwnerDiff = (*_info.hOwnerActor->GetPosition()) - vPos;
EtVector3 vPuppetDiff = (*_info.hPuppetActor->GetPosition()) - vPos;
float fOwnerLength = EtVec3LengthSq(&vOwnerDiff);
float fPuppetLength = EtVec3LengthSq(&vPuppetDiff);
*/
int nTargetTeam = _info.hOwnerActor->GetTeam();
if (_info.hOwnerActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
nTargetTeam = _info.hOwnerActor->GetOriginalTeam();
/*
//°°Àº ÆÀÀÎ °æ¿ì °Å¸®¿¡ »ó°ü¾øÀÌ ÁÖÀÎ ¾×Å͸¦ Ãß°¡
//ÁÖÀÎ ¾×ÅÍ °Å¸®°¡ ´õ ¸Ö´Ù¸é ¼Òȯ ¾×Å͸¦ ¸®½ºÆ®¿¡ Ãß°¡ Çϰí, Á¦¿ÜµÈ ¾×ÅÍ ¸®½ºÆ®¿¡ ÁÖÀÎ ¾×Å͸¦ Ãß°¡
if (nMyTeamID != nTargetTeam && fOwnerLength > fPuppetLength)
*/
//°Å¸® »ó°ü ¾øÀÌ °°Àº È÷Æ® ¹üÀ§¿¡ ÀÖÀ¸¸é ¼Òȯ ¾×Å͸¦ È÷Æ® ¸®½ºÆ®¿¡ Ãß°¡ ÇÑ´Ù.
if (hHiterActor &&
nMyTeamID != nTargetTeam)
{
hNewVecList.push_back(_info.hPuppetActor);
hAddStateEffectActorList.push_back(_info.hOwnerActor);
}
else
{
hNewVecList.push_back(_info.hOwnerActor);
}
}
//¼Òȯ ¾×ÅÍ/ÁÖÀÎ ¾×ÅÍ ½ÖÀÌ ¾Æ´Ñ °æ¿ì(µÎ ¾×ÅÍÁß Çϳª¸¸ Àִ°æ¿ì) ¸®½ºÆ®¿¡ Ãß°¡
else
{
DnActorHandle hActor = _info.hOwnerActor ? _info.hOwnerActor : _info.hPuppetActor;
if (hActor)
hNewVecList.push_back(hActor);
}
}
std::swap(hVecList, hNewVecList);
return (int)hVecList.size();
}
void CDnActor::ScanActorByStateIndex(DNVector(DnActorHandle) &Veclist, STATE_BLOW::emBLOW_INDEX blowIndex)
{
DNVector(DnActorHandle) scanActorList;
ScanActor(GetRoom(), *GetPosition(), FLT_MAX, scanActorList);
int nListCount = (int)scanActorList.size();
for (int i = 0; i < nListCount; ++i)
{
DnActorHandle hActor = scanActorList[i];
if (hActor && hActor->IsDie() == false)
{
DNVector(DnBlowHandle) blowList;
if (hActor->IsAppliedThisStateBlow(blowIndex))
hActor->GetStateBlow()->GetStateBlowFromBlowIndex(blowIndex, blowList);
int nBlowCount = (int)blowList.size();
for (int j = 0; j < nBlowCount; ++j)
{
DnBlowHandle hBlow = blowList[j];
if (hBlow && hBlow->IsEnd() == false)
{
//ÇØ´ç ¾×ÅÍÀÇ ³«ÀÎ »óÅÂÈ¿°úÀÇ ½ºÅ³ ½ÃÀüÀÚ°¡ ÀÚ½ÅÀÎ °æ¿ì ¸®½ºÆ®¿¡ ´ã´Â´Ù.
CDnSkill::SkillInfo *pSkillInfo = const_cast<CDnSkill::SkillInfo*>(hBlow->GetParentSkillInfo());
DnActorHandle hSkillActor = GetMySmartPtr();
if (IsMonsterActor())
{
CDnMonsterActor* pMonsterActor = static_cast<CDnMonsterActor*>(hSkillActor.GetPointer());
if (pMonsterActor)
hSkillActor = pMonsterActor->GetSummonerPlayerActor();
}
if (pSkillInfo && pSkillInfo->hSkillUser == hSkillActor)
Veclist.push_back(hActor);
}
}
}
}
}
// Signal Rotate.
void CDnActor::SetRotate( DWORD dwTime, float fStart, float fEnd, EtVector3 & vPos, bool bLeft )
{
m_bRotate = true;
m_dwRotateStartTime = CDnActionBase::m_LocalTime;
m_dwRotateTime = dwTime;
m_fStartSpeed = fStart; m_fEndSpeed = fEnd;
m_vRotAxis = vPos; m_bRotLeft = bLeft;
}
// Rotate.
void CDnActor::ProcessRotate( LOCAL_TIME LocalTime, float fDelta )
{
if( !m_bRotate )
return;
if( (LocalTime - m_dwRotateStartTime) > m_dwRotateTime )
{
m_bRotate = false;
return;
}
if( m_dwRotateStartTime == 0 ) m_dwRotateStartTime = LocalTime;
// ¼Óµµ( ȸÀü°¢·® )
if( m_fStartSpeed == m_fEndSpeed )
{
m_fSpeedRot = m_fStartSpeed;
}
else
{
/*float frame = pObject->GetCurFrame();
float w = ( frame - m_pSignal->GetStartFrame() ) / ( m_pSignal->GetEndFrame() - m_pSignal->GetStartFrame() );
m_fSpeedRot = m_fStartSpeed + ( ( m_fEndSpeed - m_fStartSpeed ) * w ); */
m_fSpeedRot = m_fStartSpeed;
}
// ¹æÇâ.
if( m_bRotLeft )
m_fSpeedRot = -m_fSpeedRot;
m_fSpeedRot *= fDelta;
//// ȸÀüÃàÁÂÇ¥À̵¿.
m_Cross.MoveLocalXAxis( m_vRotAxis.x );
m_Cross.MoveLocalYAxis( m_vRotAxis.y );
m_Cross.MoveLocalZAxis( m_vRotAxis.z );
// ȸÀü.
m_Cross.RotateYaw( (-m_fSpeedRot) );
}
#if defined(PRE_FIX_61382)
//²ÀµÎ°¢½Ã ¸ó½ºÅÍÀÏ °æ¿ì ÁÖÀÎ ¾×ÅÍ ¹Ýȯ.
DnActorHandle CDnActor::GetOwnerActorHandle(DnActorHandle hActor)
{
DnActorHandle hOwnerActor = hActor;
if (hActor && hActor->IsMonsterActor())
{
CDnMonsterActor* pMonsterActor = static_cast<CDnMonsterActor*>(hActor.GetPointer());
if (pMonsterActor && pMonsterActor->IsPuppetSummonMonster())
hOwnerActor = pMonsterActor->GetSummonerPlayerActor();
}
return hOwnerActor;
}
#endif // PRE_FIX_61382
#if defined(PRE_ADD_65808)
void CDnActor::AddSummonMonsterGlyphInfo(int monsterID, int glyphID)
{
std::map<int, std::list<int>>::iterator findIter = m_SummonMonsterGlyphInfo.find(monsterID);
if (findIter != m_SummonMonsterGlyphInfo.end())
{
findIter->second.push_back(glyphID);
}
else
{
std::list<int> glyphIDList;
glyphIDList.push_back(glyphID);
m_SummonMonsterGlyphInfo.insert(std::make_pair(monsterID, glyphIDList));
}
}
void CDnActor::AddSummonMonsterGlyphStateEffectID(int monsterID, int glyphID, DWORD dwMonsterUniqueID, int stateEffectID)
{
std::map<int, std::map<int, std::list<_StateEffectInfo>>>::iterator findIter = m_SummonMonsterGlyphStateEffectIDs.find(monsterID);
//ÇØ´ç ¸ó½ºÅÍ Á¤º¸°¡ ¾ø´Ù¸é
if (findIter == m_SummonMonsterGlyphStateEffectIDs.end())
{
//»õ·Î¿î glyphID, stateEffectIDList¸¦ ¸¸µé¾î µî·ÏÇÑ´Ù.
std::map<int, std::list<_StateEffectInfo>> newList;
std::list<_StateEffectInfo> stateEffectList;
_StateEffectInfo info;
info.nStateEffectID = stateEffectID;
info.dwUniqueID = dwMonsterUniqueID;
stateEffectList.push_back(info);
newList.insert(std::make_pair(glyphID, stateEffectList));
m_SummonMonsterGlyphStateEffectIDs.insert(std::make_pair(monsterID, newList));
}
else
{
std::map<int, std::list<_StateEffectInfo>>& oldList = findIter->second;
std::map<int, std::list<_StateEffectInfo>>::iterator iter = oldList.find(glyphID);
if (iter != oldList.end())
{
//ÀÌ¹Ì glyphID°¡ µî·Ï µÇ¾î ÀÖÀ¸¸é ±âÁ¸ ¸®½ºÆ®¿¡ stateEffectID¸¦ µî·ÏÇÑ´Ù.
_StateEffectInfo info;
info.nStateEffectID = stateEffectID;
info.dwUniqueID = dwMonsterUniqueID;
iter->second.push_back(info);
}
else
{
//¸ó½ºÅÍ´Â µî·Ï µÇ¾î Àִµ¥, glyphID°¡ µî·Ï µÇ¾î ÀÖÁö ¾ÊÀ¸¸é..
//»óÅÂÈ¿°ú ¸®½ºÆ® ¸¸µé°í,
std::list<_StateEffectInfo> stateEffectList;
_StateEffectInfo info;
info.nStateEffectID = stateEffectID;
info.dwUniqueID = dwMonsterUniqueID;
stateEffectList.push_back(info);
//glyphID¿¡ »óÅÂÈ¿°ú ¸®½ºÆ®¸¦ µî·Ï ÇÑ´Ù.
oldList.insert(std::make_pair(glyphID, stateEffectList));
}
}
}
void CDnActor::RemoveSummonMonsterGlyphInfo(int monsterID, int glyphID)
{
std::map<int, std::list<int>>::iterator findIter = m_SummonMonsterGlyphInfo.find(monsterID);
if (findIter != m_SummonMonsterGlyphInfo.end())
{
std::list<int>& oldList = findIter->second;
std::list<int>::iterator iter = oldList.begin();
std::list<int>::iterator endIter = oldList.end();
int nGlyphID = 0;
for (; iter != endIter; ++iter)
{
nGlyphID = (*iter);
if (nGlyphID == glyphID)
{
oldList.erase(iter);
break;
}
}
}
//¼Òȯ¸ó½ºÅÍÁß¿¡ monsterID¿¡ ÇØ´çÇÏ´Â ¸ó½ºÅ͵éÀ» ã´Â´Ù..
std::list<DnMonsterActorHandle> monsterActorList;
FindSummonMonster(monsterID, monsterActorList);
std::list<DnMonsterActorHandle>::iterator iter = monsterActorList.begin();
std::list<DnMonsterActorHandle>::iterator endIter = monsterActorList.end();
for (; iter != endIter; ++iter)
{
DnMonsterActorHandle hMonsterActor = (*iter);
//¸ó½ºÅÍ ¾×ÅÍ ¸®½ºÆ®¸¦ ¼øÈ¸ Çϴµ¿¾È Á¤º¸°¡ Áö¿ö Áö¸é ¾ÈµÈ´Ù..
RemoveSummonMonsterStateEffectByGlyph(hMonsterActor, monsterID, glyphID);
}
//½ÇÁ¦ Á¤º¸´Â ¿©±â¼­ Á¦°Å µÇµµ·Ï ÇÑ´Ù.
RemoveSummonMonsterGlyphStateEffects(monsterID);
}
void CDnActor::RemoveSummonMonsterStateEffectByGlyph(DnMonsterActorHandle hMonsterActor, int monsterID, int glyphID)
{
std::map<int, std::map<int, std::list<_StateEffectInfo>>>::iterator findIter = m_SummonMonsterGlyphStateEffectIDs.find(monsterID);
if (findIter != m_SummonMonsterGlyphStateEffectIDs.end())
{
std::map<int, std::list<_StateEffectInfo>>& oldList = findIter->second;
std::map<int, std::list<_StateEffectInfo>>::iterator glyphIter = oldList.find(glyphID);
if (glyphIter != oldList.end())
{
std::list<_StateEffectInfo>& stateEffectIDList = glyphIter->second;
if (stateEffectIDList.empty() == false)
{
std::list<_StateEffectInfo>::iterator iter = stateEffectIDList.begin();
std::list<_StateEffectInfo>::iterator endIter = stateEffectIDList.end();
for (; iter != endIter; ++iter)
{
_StateEffectInfo& info = (*iter);
if (hMonsterActor && hMonsterActor->GetUniqueID() == info.dwUniqueID)
hMonsterActor->CmdRemoveStateEffectFromID(info.nStateEffectID);
}
}
}
}
}
//½ÇÁ¦ ¸ó½ºÅͰ¡ Á×¾úÀ»¶§ PlayerActor::OnDieSummonMonsterÇÔ¼ö¿¡¼­ È£Ãâ µÊ.
//¸ó½ºÅͰ¡ Á¦°Å µÉ ¿¹Á¤À̹ǷΠ»óÅÂÈ¿°ú¸¦ ã¾Æ ÀÏÀÏÀÌ Áö¿ï ÇÊ¿ä´Â ¾øÀ»µí..
//¼³Á¤µÈ Á¤º¸¸¸ Á¦°Å..
void CDnActor::RemoveSummonMonsterGlyphStateEffects(int monsterID)
{
std::map<int, std::map<int, std::list<_StateEffectInfo>>>::iterator findIter = m_SummonMonsterGlyphStateEffectIDs.find(monsterID);
if (findIter != m_SummonMonsterGlyphStateEffectIDs.end())
{
m_SummonMonsterGlyphStateEffectIDs.erase(findIter);
}
}
bool CDnActor::GetSummonMonsterGlyphInfo(int monsterID, std::list<int>& glyphIDs)
{
std::map<int, std::list<int>>::iterator findIter = m_SummonMonsterGlyphInfo.find(monsterID);
if (findIter != m_SummonMonsterGlyphInfo.end())
{
std::list<int>& oldList = findIter->second;
std::list<int>::iterator iter = oldList.begin();
std::list<int>::iterator endIter = oldList.end();
int nGlyphID = 0;
for (; iter != endIter; ++iter)
{
nGlyphID = (*iter);
glyphIDs.push_back(nGlyphID);
}
return true;
}
return false;
}
void CDnActor::FindSummonMonster(int monsterID, std::list<DnMonsterActorHandle>& monsterActorList)
{
std::map<int, std::list<DnMonsterActorHandle> >::iterator iter = m_mapSummonMonsterByGroup.begin();
std::map<int, std::list<DnMonsterActorHandle> >::iterator endIter = m_mapSummonMonsterByGroup.end();
for (; iter != endIter; ++iter)
{
std::list<DnMonsterActorHandle>::iterator monsterIter = iter->second.begin();
std::list<DnMonsterActorHandle>::iterator monsterEndIter = iter->second.end();
for (; monsterIter != monsterEndIter; ++monsterIter)
{
DnMonsterActorHandle hMonster = *monsterIter;
if (!hMonster)
continue;
if (hMonster->GetMonsterClassID() == monsterID)
{
monsterActorList.push_back(hMonster);
}
}
}
{
for( std::list<DnMonsterActorHandle>::iterator itor=m_listSummonMonster.begin() ; itor!=m_listSummonMonster.end(); ++itor)
{
DnMonsterActorHandle hMonster = *itor;
if (!hMonster || hMonster->GetMonsterClassID() != monsterID)
continue;
monsterActorList.push_back(hMonster);
}
}
}
#endif // PRE_ADD_65808
#if defined(PRE_FIX_68898)
void CDnActor::SetSkipEndAction(bool isSkipEndAction)
{
if (IsProcessSkill() && m_hProcessSkill)
{
CDnPartialPlayProcessor* pPartialPlayProcess = static_cast<CDnPartialPlayProcessor*>(m_hProcessSkill->GetProcessor( IDnSkillProcessor::PARTIAL_PLAY_ANI ));
if (pPartialPlayProcess)
pPartialPlayProcess->SetSkipEndAction(isSkipEndAction);
}
}
#endif // PRE_FIX_68898
void CDnActor::ResetDamageRemainTime()
{
m_mapLastDamageTime.clear();
m_nLastDamageHitterActionIndex = 0;
}
LOCAL_TIME CDnActor::GetDamageRemainTime( DWORD dwActorUniqueID )
{
map<DWORD, LOCAL_TIME>::iterator iter = m_mapLastDamageTime.find( dwActorUniqueID );
if( m_mapLastDamageTime.end() != iter )
return iter->second;
else
return 0;
}
void CDnActor::SetDamageRemainTime( DWORD dwActorUniqueID, LOCAL_TIME LastDamageTime, int nCurrentActionIndex )
{
m_mapLastDamageTime[ dwActorUniqueID ] = LastDamageTime;
m_nLastDamageHitterActionIndex = nCurrentActionIndex;
}
void CDnActor::SetLastDamageHitUniqueID( DWORD dwActorUniqueID, int iLastHitUniqueID )
{
m_mapLastHitUniqueID[ dwActorUniqueID ] = iLastHitUniqueID;
}
int CDnActor::GetLastDamageHitUniqueID( DWORD dwActorUniqueID )
{
if( m_mapLastHitUniqueID.end() != m_mapLastHitUniqueID.find( dwActorUniqueID ) )
return m_mapLastHitUniqueID[ dwActorUniqueID ];
else
return -1;
};