4581 lines
123 KiB
C++
4581 lines
123 KiB
C++
#include "stdafx.h"
|
||
#include "SGameWork.h"
|
||
|
||
#include "SGameMessage.h"
|
||
#include "GameDefine.h"
|
||
|
||
#include "SGame.h"
|
||
|
||
#include "SMotionDB.h"
|
||
#include "SStringDB.h"
|
||
#include "SMonsterDB.h"
|
||
#include "SCreatureDB.h"
|
||
#include "SNpcDB.h"
|
||
#include "SGameUtil.h"
|
||
#include "SItemDB.h"
|
||
|
||
#include "SGameAvatarEx.h"
|
||
#include "SSkillStageType.h"
|
||
|
||
#include "SGameOtherEffectMng.h"
|
||
|
||
#include "LuaVM.h"
|
||
#include <toolkit/XStringUtil.h>
|
||
|
||
#include "SSoundResourceDB.h"
|
||
|
||
#include "SDebug_Util.h"
|
||
|
||
#include "SGameWorld.h"
|
||
#include "SGameSystem.h"
|
||
#include "CommonUtil.h"
|
||
|
||
#include "SGameScript.h" // Fraun performance tweak
|
||
|
||
extern SGameSystem * g_pCurrentGameSystem;
|
||
|
||
namespace
|
||
{
|
||
const char* szNX3Name[3][2] =
|
||
{
|
||
{ "gam.nx3", "gaf.nx3", },
|
||
{ "dem.nx3", "def.nx3", },
|
||
{ "asm.nx3", "asf.nx3", },
|
||
};
|
||
|
||
const char* GetNX3Name( int nRace, int nSex )
|
||
{
|
||
short race = 0;
|
||
if( nRace == GCLAN_GAIA ) race = 0;
|
||
else if( nRace == GCLAN_DEVA ) race = 1;
|
||
else if( nRace == GCLAN_ASURA ) race = 2;
|
||
else
|
||
{
|
||
assert( false && "유효하지 않는 종족" );
|
||
return "";
|
||
}
|
||
|
||
short sex = 0;
|
||
if( nSex == SEX_MALE ) sex = 0;
|
||
else if( nSex == SEX_FEMALE ) sex = 1;
|
||
else
|
||
{
|
||
assert( false && "유효하지 않는 성별" );
|
||
return "";
|
||
}
|
||
|
||
return szNX3Name[race][sex];
|
||
}
|
||
};
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
SGameWork::SGameWork( SGameAvatarEx *pOwner, int nCount, DWORD dwKeepTime )
|
||
: m_nCount(nCount), m_dwStartTime(0), m_dwKeepTime(dwKeepTime), m_dwTime(0), m_pOwner(pOwner), m_bEnd(FALSE), m_nStep(STEP_00), m_nWorkType( WORK_NONE )
|
||
{
|
||
|
||
}
|
||
|
||
SGameWork::~SGameWork()
|
||
{
|
||
}
|
||
|
||
void SGameWork::Process( DWORD dwTime )
|
||
{
|
||
}
|
||
|
||
void SGameWork::_setEvent( KEventKeyRes<Key_EVENT_NEW>* srcEvent, KEventKeyRes<Key_EVENT_NEW>* & dstEvent )
|
||
{
|
||
dstEvent = NULL;
|
||
if( srcEvent )
|
||
{
|
||
dstEvent = new KEventKeyRes<Key_EVENT_NEW>;
|
||
dstEvent->SetKeyCount( srcEvent->GetKeyCount(), srcEvent->GetLength() );
|
||
|
||
for( int i(0); srcEvent->GetKeyCount()>i; i++ )
|
||
dstEvent->SetKey( i, &srcEvent->GetKey(i) );
|
||
}
|
||
}
|
||
|
||
void SGameWork::SetDamageDisplayName( SMSG_DAMAGE* pDamage, SGameAvatarEx* pTarget )
|
||
{
|
||
// Fraun performance tweak
|
||
if( m_pOwner )
|
||
{
|
||
switch (m_pOwner->GetObjType())
|
||
{
|
||
case TS_ENTER::GAME_PLAYER:
|
||
{
|
||
pDamage->strCasterName = m_pOwner->GetName();
|
||
break;
|
||
}
|
||
case TS_ENTER::GAME_MOB:
|
||
{
|
||
pDamage->strCasterName = GetStringDB().GetString(GetMonsterDB().GetTextID(m_pOwner->GetContentID()));
|
||
break;
|
||
}
|
||
case TS_ENTER::GAME_SUMMON:
|
||
{
|
||
pDamage->strCasterName = GetStringDB().GetString(GetCreatureDB().GetTextID(m_pOwner->GetContentID()));
|
||
break;
|
||
}
|
||
case TS_ENTER::GAME_NPC:
|
||
{
|
||
pDamage->strCasterName = GetStringDB().GetString(GetNpcDB().GetTextID(m_pOwner->GetContentID()));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( pTarget )
|
||
{
|
||
switch (m_pOwner->GetObjType())
|
||
{
|
||
case TS_ENTER::GAME_PLAYER:
|
||
{
|
||
pDamage->strTargetName = pTarget->GetName();
|
||
break;
|
||
}
|
||
case TS_ENTER::GAME_MOB:
|
||
{
|
||
pDamage->strTargetName = GetStringDB().GetString(GetMonsterDB().GetTextID(pTarget->GetContentID()));
|
||
break;
|
||
}
|
||
case TS_ENTER::GAME_SUMMON:
|
||
{
|
||
pDamage->strTargetName = GetStringDB().GetString(GetCreatureDB().GetTextID(pTarget->GetContentID()));
|
||
break;
|
||
}
|
||
case TS_ENTER::GAME_NPC:
|
||
{
|
||
pDamage->strTargetName = GetStringDB().GetString(GetNpcDB().GetTextID(pTarget->GetContentID()));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void SGameWork::SetWorkType( WORK_TYPE nWorkType )
|
||
{
|
||
m_nWorkType = nWorkType;
|
||
}
|
||
|
||
// 2010.06.14 - prodongi
|
||
void SGameWork::SetStep(int nStep)
|
||
{
|
||
m_nStep = nStep;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//캐릭터 이모션 관련
|
||
SWorkEmotion::SWorkEmotion( class SGameAvatarEx * pOwner, struct SGameMessage * pMsg )
|
||
: SGameWork( pOwner )
|
||
{
|
||
if( pMsg )
|
||
{
|
||
//TODO : 서버에서 처리 해주면 추가 가능.
|
||
}
|
||
|
||
m_nEmotionID = -1;
|
||
SetStep(STEP_01);
|
||
}
|
||
|
||
SWorkEmotion::~SWorkEmotion()
|
||
{
|
||
if( m_pOwner ) m_pOwner->HideWeapon( TRUE );
|
||
}
|
||
|
||
bool SWorkEmotion::SetEmotion( int nEmotionID )
|
||
{
|
||
if( m_pOwner->GetCurrAnimationID() == nEmotionID )
|
||
{
|
||
SetEnd( true );
|
||
return false;
|
||
}
|
||
|
||
m_nEmotionID = nEmotionID;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkEmotion::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
if( m_pOwner->GetInnObjType() != m_pOwner->GetObjType() )
|
||
{
|
||
SetEnd( true );
|
||
return;
|
||
}
|
||
|
||
if( m_nEmotionID == -1 )
|
||
{ //초기화 안 됐음
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
if( GetStep() == STEP_01 )
|
||
{
|
||
//Emotion이 가능 한가 검사
|
||
if( m_pOwner->IsAniLock() || m_pOwner->GetAttackAniLock() )
|
||
{
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
if( !m_pOwner->CheckAllState() )
|
||
{
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
if( m_nEmotionID == ANI_PRAY && IsRamadanPrayRoom() == false ) // 기도실이 아니면 기도는 할 수 없다
|
||
{
|
||
SetEnd(TRUE);
|
||
return ;
|
||
}
|
||
|
||
//FALSE가 무기 숨김
|
||
//TRUE가 무기 보여줌
|
||
if( ANI_CHEER != m_nEmotionID ) m_pOwner->HideWeapon( FALSE );
|
||
|
||
SetStep(STEP_02);
|
||
}
|
||
else if( GetStep() == STEP_02 )
|
||
{
|
||
m_pOwner->NPlayAnimation( m_nEmotionID );
|
||
SetStep(STEP_03);
|
||
}
|
||
else if( GetStep() == STEP_03 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() && m_pOwner->GetCurrAnimationID() == m_nEmotionID )
|
||
{
|
||
m_pOwner->HideWeapon( TRUE );
|
||
|
||
m_pOwner->Default();
|
||
SetEnd(TRUE);
|
||
}
|
||
|
||
if( m_pOwner->GetCurrAnimationID() != m_nEmotionID )
|
||
{
|
||
m_pOwner->HideWeapon( TRUE );
|
||
|
||
SetEnd(TRUE);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//SWorkAttackEx
|
||
SWorkAttackEx::SWorkAttackEx( class SGameAvatarEx * pOwner, const AR_HANDLE target, float fAttackPlayRate )
|
||
: SGameWork( pOwner )
|
||
{
|
||
m_Target = target; //타겟
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_Target );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
// _oprint( "SWorkAttackEx : fRate[%f]\n", m_fAttackRate );
|
||
|
||
ZeroMemory( m_pDamageSet, sizeof( m_pDamageSet ) );
|
||
m_nHitCount = 0;
|
||
m_nSwingCnt = 0;
|
||
m_nMaxHitCount = 0;
|
||
|
||
m_fAttackPlayRate = fAttackPlayRate;
|
||
|
||
pOwner->SetVisibleWeaponTrail( true );
|
||
|
||
SetWorkType( WORK_ATTACKEX );
|
||
}
|
||
|
||
SWorkAttackEx::~SWorkAttackEx()
|
||
{
|
||
if( !m_vFX_List.empty() )
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
for( unsigned int i(0); m_vFX_List.size()>i; i++ )
|
||
m_pOwner->DelEffect(m_vFX_List[i]);
|
||
}
|
||
|
||
m_vFX_List.erase( m_vFX_List.begin(), m_vFX_List.end() );
|
||
}
|
||
|
||
if( m_pOwner ) m_pOwner->SetAttackAniLock( false );
|
||
|
||
if( m_pOwner )
|
||
{
|
||
//처리가 안된 데미지 처리한다
|
||
while( m_nHitCount > 0 )
|
||
{
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_Target );
|
||
if( pTarget )
|
||
{
|
||
SMSG_DAMAGE *pDamage = m_pDamageSet[m_nMaxHitCount-m_nHitCount];
|
||
_processDamage( pDamage, m_nHitCount, SMotionEventHanderDB::EV_HIT, -1 );
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
for( short i = 0; i < 4; i++ )
|
||
{
|
||
SAFE_DELETE( m_pDamageSet[i] );
|
||
}
|
||
|
||
SAFE_DELETE( m_pEventHandle06 );
|
||
SAFE_DELETE( m_pEventHandle05 );
|
||
SAFE_DELETE( m_pEventHandle04 );
|
||
SAFE_DELETE( m_pEventHandle03 );
|
||
SAFE_DELETE( m_pEventHandle02 );
|
||
SAFE_DELETE( m_pEventHandle01 );
|
||
SAFE_DELETE( m_pEventHandle00_sound );
|
||
SAFE_DELETE( m_pEventHandle00_effect );
|
||
SAFE_DELETE( m_pEventHandle00_motion_effect );
|
||
}
|
||
|
||
void SWorkAttackEx::SetEventHandle( const DWORD dwStartTime, const unsigned short attack_speed, KEventKeyRes<Key_EVENT_NEW>* pEvent00_eff, KEventKeyRes<Key_EVENT_NEW>* pEvent00_sound, KEventKeyRes<Key_EVENT_NEW>* pEvent00_motion_effect,
|
||
KEventKeyRes<Key_EVENT_NEW>* pEvent01,
|
||
KEventKeyRes<Key_EVENT_NEW>* pEvent02,
|
||
KEventKeyRes<Key_EVENT_NEW>* pEvent03,
|
||
KEventKeyRes<Key_EVENT_NEW>* pEvent04,
|
||
KEventKeyRes<Key_EVENT_NEW>* pEvent05,
|
||
KEventKeyRes<Key_EVENT_NEW>* pEvent06 )
|
||
{
|
||
m_dwStartTime = dwStartTime; //공격 시작 시간
|
||
m_dwMaxTime = attack_speed; //공격 전체 시간
|
||
|
||
_setEvent( pEvent00_eff , m_pEventHandle00_effect );
|
||
_setEvent( pEvent00_sound, m_pEventHandle00_sound );
|
||
_setEvent( pEvent00_motion_effect, m_pEventHandle00_motion_effect );
|
||
_setEvent( pEvent01, m_pEventHandle01 );
|
||
_setEvent( pEvent02, m_pEventHandle02 );
|
||
_setEvent( pEvent03, m_pEventHandle03 );
|
||
_setEvent( pEvent04, m_pEventHandle04 );
|
||
_setEvent( pEvent05, m_pEventHandle05 );
|
||
_setEvent( pEvent06, m_pEventHandle06 );
|
||
|
||
int nLength = 0;
|
||
if( pEvent00_eff ) nLength = pEvent00_eff->GetLength();
|
||
else if( pEvent00_sound ) nLength = pEvent00_sound->GetLength();
|
||
else if( pEvent00_motion_effect ) nLength = pEvent00_motion_effect->GetLength();
|
||
else if( pEvent01 ) nLength = pEvent01->GetLength();
|
||
else if( pEvent02 ) nLength = pEvent02->GetLength();
|
||
else if( pEvent03 ) nLength = pEvent03->GetLength();
|
||
else if( pEvent04 ) nLength = pEvent04->GetLength();
|
||
else if( pEvent05 ) nLength = pEvent05->GetLength();
|
||
else if( pEvent06 ) nLength = pEvent06->GetLength();
|
||
|
||
float fAttack = m_pOwner->GetAttackSpeed( attack_speed );
|
||
float fRate = GetAniPlayRate( fAttack, nLength );
|
||
// _oprint( "SGameAttackEx : total[%d], fAttack[%f], fRate[%f]\n", attack_speed, fAttack, fRate );
|
||
m_fAttackRate = fRate; //진행 배속
|
||
|
||
//#ifndef NDEBUG
|
||
// if( m_pOwner && m_pOwner->IsLocalPlayer() )
|
||
// _oprint( "Work Attack Speed : %d, %f\n", attack_speed, 4.8f / fRate );
|
||
//#endif
|
||
|
||
//Half 시간 설정
|
||
if( m_pOwner->GetObjType() == TS_ENTER::GAME_MOB ||
|
||
m_pOwner->GetObjType() == TS_ENTER::GAME_SUMMON )
|
||
{
|
||
//Mouvement de dégâts possible lorsque la progression est supérieure à 50 %
|
||
m_dwHalfTime = (nLength/fRate)/2.f;
|
||
}
|
||
else if( m_pOwner->GetObjType() == TS_ENTER::GAME_PLAYER )
|
||
{
|
||
//Le mouvement des dégâts est possible lorsque la progression est supérieure à 70 %
|
||
m_dwHalfTime = (nLength / fRate) - ((nLength / fRate) * 0.3f);
|
||
}
|
||
|
||
//assert( m_dwHalfTime && "공격 시간이 이상함!!!" );
|
||
|
||
m_dwHalfTime += dwStartTime;
|
||
|
||
//이번 공격이 끝날 시점
|
||
m_dwMaxTime += dwStartTime; //현재 시간을 더해서 끝날 시간을 생성
|
||
}
|
||
|
||
void SWorkAttackEx::SetDamegeMsg( struct SMSG_ATTACK * pAttackMsg )
|
||
{
|
||
for( short i(0); i < 4; i++ )
|
||
{
|
||
SAFE_DELETE( m_pDamageSet[i] );
|
||
}
|
||
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_Target );
|
||
for( m_nMaxHitCount = 0; m_nMaxHitCount < pAttackMsg->count; m_nMaxHitCount++ )
|
||
{
|
||
m_pDamageSet[m_nMaxHitCount] = new SMSG_DAMAGE;
|
||
m_pDamageSet[m_nMaxHitCount]->attacker_handle = pAttackMsg->attacker_handle;
|
||
m_pDamageSet[m_nMaxHitCount]->target_handle = pAttackMsg->target_handle;
|
||
|
||
m_pDamageSet[m_nMaxHitCount]->attack_action = pAttackMsg->attack_action;
|
||
m_pDamageSet[m_nMaxHitCount]->attack_flag = pAttackMsg->attack_flag;
|
||
|
||
m_pDamageSet[m_nMaxHitCount]->flag = pAttackMsg->m_vAttackInfoList[m_nMaxHitCount].flag;
|
||
m_pDamageSet[m_nMaxHitCount]->nDamage = pAttackMsg->m_vAttackInfoList[m_nMaxHitCount].damage;
|
||
|
||
SetDamageDisplayName( m_pDamageSet[m_nMaxHitCount], pTarget );
|
||
|
||
for( int count(0); CreatureElemental::ElementalType::COUNT>count; count++ )
|
||
m_pDamageSet[m_nMaxHitCount]->elemental_damage[count] = pAttackMsg->m_vAttackInfoList[m_nMaxHitCount].elemental_damage[count];
|
||
}
|
||
|
||
m_nSwingCnt = m_nHitCount = m_nMaxHitCount;
|
||
}
|
||
|
||
void SWorkAttackEx::SetDamegeInfo( const struct SStateInfo * pStateInfo )
|
||
{
|
||
for( short i(0); i < 4; i++ )
|
||
{
|
||
SAFE_DELETE( m_pDamageSet[i] );
|
||
}
|
||
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_Target );
|
||
for( m_nMaxHitCount = 0; m_nMaxHitCount < pStateInfo->count; m_nMaxHitCount++ )
|
||
{
|
||
m_pDamageSet[m_nMaxHitCount] = new SMSG_DAMAGE;
|
||
m_pDamageSet[m_nMaxHitCount]->attacker_handle = pStateInfo->hSelf;
|
||
m_pDamageSet[m_nMaxHitCount]->target_handle = pStateInfo->hTarget;
|
||
|
||
m_pDamageSet[m_nMaxHitCount]->attack_action = pStateInfo->attack_action;
|
||
m_pDamageSet[m_nMaxHitCount]->attack_flag = pStateInfo->attack_flag;
|
||
|
||
m_pDamageSet[m_nMaxHitCount]->flag = pStateInfo->vAttackInfoList[m_nMaxHitCount].flag;
|
||
m_pDamageSet[m_nMaxHitCount]->nDamage = pStateInfo->vAttackInfoList[m_nMaxHitCount].damage;
|
||
|
||
SetDamageDisplayName( m_pDamageSet[m_nMaxHitCount], pTarget );
|
||
|
||
for( int count(0); CreatureElemental::ElementalType::COUNT>count; count++ )
|
||
m_pDamageSet[m_nMaxHitCount]->elemental_damage[count] = pStateInfo->vAttackInfoList[m_nMaxHitCount].elemental_damage[count];
|
||
}
|
||
|
||
m_nSwingCnt = m_nHitCount = m_nMaxHitCount;
|
||
}
|
||
|
||
bool SWorkAttackEx::ProcessingDamage()
|
||
{
|
||
if( m_nHitCount > 0 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkAttackEx::_ondamage( struct SMSG_DAMAGE * pDamage, int & nHitCnt, int nKeyHandleID, int nKeyTime )
|
||
{
|
||
// Fraun performance tweak
|
||
if( pDamage && nHitCnt > 0)
|
||
{
|
||
AR_HANDLE ownerHandle = m_pOwner->GetArID();
|
||
AR_HANDLE targetHandle = m_pTarget->GetArID();
|
||
m_pOwner->OnDamage(ownerHandle, targetHandle, pDamage);
|
||
if (!(pDamage->flag & TS_ATTACK_EVENT::FLAG_MISS))
|
||
{
|
||
int nMaterial = 0;
|
||
int nWeaponClass = 0;
|
||
bool bCrit = pDamage->flag & TS_ATTACK_EVENT::FLAG_CRITICAL;
|
||
bool bBlock = pDamage->flag & TS_ATTACK_EVENT::FLAG_BLOCK;
|
||
|
||
SGame* pGame = g_pCurrentGameSystem->GetGame();
|
||
|
||
if (pGame)
|
||
{
|
||
SGameObject* pPlayer = pGame->GetGameObject(targetHandle);
|
||
if (pPlayer)
|
||
{
|
||
nMaterial = pPlayer->GetMaterial();
|
||
nWeaponClass = pPlayer->GetItemClass();
|
||
}
|
||
}
|
||
Noscript_PlayFX(ownerHandle, ownerHandle, targetHandle, nMaterial, nWeaponClass, bCrit, bBlock, nKeyHandleID, nKeyTime);
|
||
//void Noscript_PlayFX(AR_HANDLE owner_handle, AR_HANDLE attack_handle, AR_HANDLE target_handle, int nMaterial, int nWeaponClass, bool bIsCritical, bool bIsBlock, int nKeyHandleID, int nKeyTime)
|
||
m_pTarget->Damage();
|
||
}
|
||
nHitCnt--;
|
||
}
|
||
}
|
||
|
||
void SWorkAttackEx::_processDamage( struct SMSG_DAMAGE * pDamage, int & nHitCnt, int nKeyHandleID, int nKeyTime )
|
||
{
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_Target );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
if( pDamage ) _ondamage( pDamage, nHitCnt, nKeyHandleID, nKeyTime );
|
||
}
|
||
|
||
void SWorkAttackEx::_processEvent( KEventKeyRes<Key_EVENT_NEW>* event, DWORD eventTime )
|
||
{
|
||
if( event )
|
||
{
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
event->GetData( eventTime, pKey1, pKey2 );
|
||
|
||
if( pKey1 && !pKey1->bUse )
|
||
{
|
||
pKey1->bUse = true;
|
||
|
||
//std::string strScript;
|
||
|
||
//힛팅임.
|
||
if( pKey1->nHandleID == SMotionEventHanderDB::EV_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_LEFT_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_RIGHT_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_TWO_HAND_HIT)
|
||
{
|
||
if( m_nHitCount )
|
||
_processDamage( m_pDamageSet[m_nMaxHitCount-m_nHitCount], m_nHitCount, pKey1->nHandleID, pKey1->time );
|
||
}
|
||
else
|
||
{
|
||
if( m_nSwingCnt && (pKey1->nHandleID == SMotionEventHanderDB::EV_SHOOT || pKey1->nHandleID == SMotionEventHanderDB::EV_SWING) )
|
||
{
|
||
m_nSwingCnt--;
|
||
//XStringUtil::Format( strScript, "%s( %u, %u )", "call_fx_ch_weapone_attack", m_pOwner->GetArID(), m_pTarget->GetArID() );
|
||
}
|
||
}
|
||
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkAttackEx::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() )
|
||
return;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_Target );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
if( dwTime >= m_dwHalfTime )
|
||
{ //공격 시간이 50% 지났다.
|
||
m_pOwner->SetAttackAniLock( false );
|
||
}
|
||
|
||
if( dwTime >= m_dwMaxTime )
|
||
{ //시간이 모두 지났다.
|
||
// _oprint( "SWorkAttackEx 종료 02\n" );
|
||
m_pOwner->SetAttackAniLock( false );
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fAttackRate);
|
||
//_oprint( " 공격 : %d\n", eventTime );
|
||
|
||
if( m_pEventHandle00_effect )
|
||
{
|
||
//시작 되자 마자 나오는 Effect
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
m_pEventHandle00_effect->GetData( 0, pKey1, pKey2 );
|
||
if( pKey1 && !pKey1->bUse )
|
||
{
|
||
pKey1->bUse = true;
|
||
m_pOwner->FindMotionAddOnFx( pKey1 );
|
||
switch(pKey1->nSpeedType)
|
||
{
|
||
case 0:
|
||
{
|
||
m_pOwner->AddEffect( &FX_DATA_EX( pKey1->strEffect.c_str(), pKey1->followflag, m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), pKey1->nEffPos, false, pKey1->nSpeedType, m_fAttackPlayRate ) );
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
if(!pKey1->strEffect.empty())
|
||
{
|
||
m_pOwner->AddEffect( &FX_DATA_EX( pKey1->strEffect.c_str(), pKey1->followflag, m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), pKey1->nEffPos, false, pKey1->nSpeedType, m_fAttackPlayRate ) );
|
||
}
|
||
|
||
//검 잔상
|
||
m_pOwner->ActivateFxSwordSlashForSkill();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( m_pEventHandle00_sound )
|
||
{
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
m_pEventHandle00_sound->GetData( eventTime, pKey1, pKey2 );
|
||
if( pKey1 && !pKey1->bUse )
|
||
{
|
||
pKey1->bUse = true;
|
||
if( pKey1->nSound_play_probability != 100 )
|
||
{
|
||
int nRatio = rand()%100;
|
||
if( nRatio < pKey1->nSound_play_probability )
|
||
m_pOwner->StartSound( m_pOwner, pKey1->strSound.c_str(), *m_pOwner->GetPosition(), true, pKey1->nSoundVolume, false, pKey1->SoundOption );
|
||
}
|
||
else
|
||
{
|
||
m_pOwner->StartSound( m_pOwner, pKey1->strSound.c_str(), *m_pOwner->GetPosition(), true, pKey1->nSoundVolume, false, pKey1->SoundOption );
|
||
}
|
||
}
|
||
}
|
||
|
||
if( m_pEventHandle00_motion_effect )
|
||
{
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
|
||
m_pEventHandle00_motion_effect->GetData( eventTime, pKey1, pKey2 );
|
||
|
||
if( pKey1 && pKey1->bUse == false )
|
||
{
|
||
pKey1->bUse = true; //사용.
|
||
|
||
FX_DATA fxdata;
|
||
fxdata.nFX_ID = pKey1->nFXsetID;
|
||
fxdata.nEffPos = pKey1->nEffPos;
|
||
fxdata.owner = m_pOwner->GetArID();
|
||
fxdata.attack = m_pOwner->GetArID();
|
||
fxdata.target = m_pOwner->GetArID();
|
||
fxdata.fPlayRate = pKey1->fPlayRate;
|
||
fxdata.nPlayID = 0;//한번
|
||
fxdata.nMode = 0;//기본
|
||
|
||
m_pOwner->AddEffect( &fxdata );
|
||
}
|
||
}
|
||
|
||
_processEvent( m_pEventHandle01, eventTime );
|
||
_processEvent( m_pEventHandle02, eventTime );
|
||
_processEvent( m_pEventHandle03, eventTime );
|
||
_processEvent( m_pEventHandle04, eventTime );
|
||
_processEvent( m_pEventHandle05, eventTime );
|
||
_processEvent( m_pEventHandle06, eventTime );
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//SWorkWarp
|
||
SWorkWarp::SWorkWarp( class SGameAvatarEx * pOwner, struct SCMSG_WARP * pMsg ) : SGameWork( pOwner )
|
||
{
|
||
// _oprint( "SWorkWarp::SWorkWarp\n" );
|
||
|
||
m_pWarpMsg = new SCMSG_WARP;
|
||
m_pWarpMsg->x = pMsg->x;
|
||
m_pWarpMsg->y = pMsg->y;
|
||
m_pWarpMsg->z = pMsg->z;
|
||
m_pWarpMsg->layer = pMsg->layer;
|
||
}
|
||
|
||
SWorkWarp::~SWorkWarp()
|
||
{
|
||
if( m_pOwner ) m_pOwner->InputThawing();
|
||
|
||
SAFE_DELETE( m_pWarpMsg );
|
||
}
|
||
|
||
|
||
void SWorkWarp::Process( DWORD dwTime )
|
||
{
|
||
// _oprint( "SWorkWarp::Process\n" );
|
||
m_pOwner->SetArObjectPos( m_pWarpMsg->x, m_pWarpMsg->y, m_pWarpMsg->z, m_pWarpMsg->layer );
|
||
float fHeight = 0.f;
|
||
WORD wTile=0;
|
||
m_pOwner->GetHeight(m_pWarpMsg->x,m_pWarpMsg->y,fHeight,wTile);
|
||
m_pOwner->SetPosition( K3DVector(m_pWarpMsg->x,m_pWarpMsg->y, fHeight) );
|
||
|
||
SGameAvatarEx* pTransportCreature = (SGameAvatarEx*)m_pOwner->GetGameTransportCreatureObject( m_pOwner->GetCreatureMountHandle() );
|
||
if( pTransportCreature )
|
||
{
|
||
m_pOwner->SetMountMode();
|
||
pTransportCreature->SetMountMode();
|
||
|
||
pTransportCreature->SetArObjectPos( m_pWarpMsg->x, m_pWarpMsg->y, m_pWarpMsg->z, m_pWarpMsg->layer );
|
||
pTransportCreature->SetPosition( K3DVector(m_pWarpMsg->x,m_pWarpMsg->y, fHeight) );
|
||
|
||
int nDefaultAniType;
|
||
|
||
switch( pTransportCreature->GetCreatureMountType() )
|
||
{
|
||
case SGameAvatarEx::RIDE_LOW_TYPE:
|
||
nDefaultAniType = ANI_M_DEFAULT01_LOW;
|
||
break;
|
||
case SGameAvatarEx::RIDE_HIGH_TYPE:
|
||
nDefaultAniType = ANI_M_DEFAULT01_HIGH;
|
||
break;
|
||
case SGameAvatarEx::RIDE_QILIN_TYPE:
|
||
nDefaultAniType = ANI_M_DEFAULT01_QILIN;
|
||
break;
|
||
case SGameAvatarEx::RIDE_WHITE_TYPE:
|
||
nDefaultAniType = ANI_M_DEFAULT01_WHITE;
|
||
break;
|
||
case SGameAvatarEx::RIDE_UNICORN_TYPE:
|
||
nDefaultAniType = ANI_M_DEFAULT01_UNICORN;
|
||
break;
|
||
/// 2011.02.08 - prodongi
|
||
case SGameAvatarEx::RIDE_BEAKHO_TYPE:
|
||
nDefaultAniType = ANI_M_DEFAULT01_BEAKHO;
|
||
break;
|
||
default:
|
||
nDefaultAniType = ANI_M_DEFAULT01_HIGH;
|
||
break;
|
||
}
|
||
|
||
m_pOwner->NPlayAnimation( nDefaultAniType, SEQTYPE_LOOP );
|
||
pTransportCreature->NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
||
}
|
||
else
|
||
{
|
||
//마운트 모드가 아닐때 기본 상태로
|
||
// if( !m_pOwner->IsMountMode() )
|
||
|
||
SGameAvatarEx* pCreature = (SGameAvatarEx*)m_pOwner->GetGameObject( m_pOwner->GetCreatureMountHandle() );
|
||
if( pCreature )
|
||
{
|
||
pCreature->SetAniLock( false );
|
||
pCreature->Default();
|
||
}
|
||
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->Default();
|
||
}
|
||
|
||
m_pOwner->SetAttackAniLock( false );
|
||
m_pOwner->WarpComplete( m_pWarpMsg );
|
||
m_pOwner->InputThawing();
|
||
|
||
SetEnd( TRUE );
|
||
}
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//SWorkAttack
|
||
SWorkAttack::SWorkAttack( SGameAvatarEx * pOwner, K3DVector & targetpos, AR_HANDLE targetID, int nDamage, int nRest_hp, int nAttackMsec ) : SGameWork(pOwner)
|
||
{
|
||
// _oprint( "호호호 : SWorkAttack::SWorkAttack %0x8d \n", targetID );
|
||
|
||
m_TargetPos = targetpos;
|
||
m_TargetID = targetID;
|
||
m_nDamage = nDamage;
|
||
m_nRest_hp = nRest_hp;
|
||
m_nAttackMsec = nAttackMsec;
|
||
}
|
||
|
||
SWorkAttack::~SWorkAttack()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkAttack::Process( DWORD dwTime )
|
||
{
|
||
// _oprint( "SWorkAttack Damage : %d, RestHP : %d\n", m_nDamage, m_nRest_hp );
|
||
m_pOwner->SetViewVector( m_TargetPos );
|
||
// m_pOwner->SetDamage( m_TargetID, m_nDamage, m_nRest_hp );
|
||
// m_pOwner->Attack( m_TargetID, m_TargetPos, m_nAttackMsec );
|
||
|
||
SetEnd(TRUE);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//SWorkGoodPosSearch
|
||
SWorkGoodPosSearch::SWorkGoodPosSearch( class SGameAvatarEx * pOwner, AR_HANDLE hMaster ): SGameWork(pOwner)
|
||
{
|
||
// _oprint( "SWorkGoodPosSearch::SWorkGoodPosSearch\n" );
|
||
|
||
m_hMaster = hMaster; //주인님
|
||
SetStep(STEP_01);
|
||
}
|
||
|
||
SWorkGoodPosSearch::~SWorkGoodPosSearch()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkGoodPosSearch::Process( DWORD dwTime )
|
||
{
|
||
//성공 할때까지, 자동으로 해준다.
|
||
//공격하는 Object에서 떨어진다.
|
||
//적절한 위치라 함은, 어딜까???
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
SWorkPickUp::SWorkPickUp( class SGameAvatarEx * pOwner, class SGameAvatarEx* pItem ) : SGameWork(pOwner)
|
||
{
|
||
m_dwStartTime = 0;
|
||
|
||
m_pOwner->SetViewVector( *pItem->GetPosition() );
|
||
|
||
SetStep( STEP_00 );
|
||
}
|
||
|
||
SWorkPickUp::~SWorkPickUp()
|
||
{
|
||
}
|
||
|
||
void SWorkPickUp::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
//마운트 상태에서는 줍기 모션 생략
|
||
if( m_pOwner->IsMountMode() )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
if( m_dwStartTime == 0 )
|
||
m_dwStartTime = dwTime;
|
||
|
||
if( !m_pOwner->IsMoving() )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
m_dwStartTime = dwTime;
|
||
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->PickUpEx();
|
||
m_pOwner->SetAniLock( true );
|
||
SetStep( STEP_01 );
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() &&
|
||
m_pOwner->GetCurrAnimationID() == ANI_PICKUP01 )
|
||
{
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->StandUp();
|
||
SetEnd( TRUE );
|
||
}
|
||
}
|
||
|
||
//줍는 도중 이동 및 공격 모션으로 바뀌었을 경우 검사한다
|
||
if( m_pOwner->IsPlaying() && m_pOwner->GetCurrAnimationID() != ANI_PICKUP01 )
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock( false );
|
||
SetEnd( TRUE );
|
||
}
|
||
}
|
||
|
||
//10초가 경과했는데도 끝나지 않았다면
|
||
if( dwTime - m_dwStartTime > 10000 )
|
||
{
|
||
//줍는 모션중이라면
|
||
if( m_pOwner->GetCurrAnimationID() == ANI_PICKUP01 )
|
||
{
|
||
m_pOwner->StandUp();
|
||
}
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock( false );
|
||
SetEnd( TRUE );
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
SWorkAniSit::SWorkAniSit( class SGameAvatarEx * pOwner, DWORD dwTime ) : SGameWork(pOwner)
|
||
{
|
||
m_dwStartTime = dwTime;
|
||
SetStep( STEP_00 );
|
||
}
|
||
|
||
SWorkAniSit::~SWorkAniSit()
|
||
{
|
||
|
||
}
|
||
|
||
void *SWorkAniSit::PerformMsg( struct SGameMessage * pMsg )
|
||
{
|
||
return (void*)0;
|
||
}
|
||
|
||
void SWorkAniSit::Process( DWORD dwTime )
|
||
{
|
||
//if( GetStep() != STEP_00 )
|
||
//{
|
||
// if( dwTime - m_dwStartTime > 3000 )
|
||
// { //3000 초 이후에는 강제 종료
|
||
// SetEnd( TRUE );
|
||
// }
|
||
//}
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
m_dwStartTime = dwTime;
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->SitProcess( ANI_SITDOWN );
|
||
m_pOwner->SetAniLock( true );
|
||
|
||
SetStep( STEP_01 );
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() && m_pOwner->GetCurrAnimationID() == ANI_SITDOWN )
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->SitProcess( ANI_SIT, SEQTYPE_LOOP );
|
||
SetEnd( TRUE );
|
||
}
|
||
else
|
||
{
|
||
if( dwTime - m_dwStartTime > 3000 )
|
||
SetEnd( TRUE );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
SWorkAniStandUp::SWorkAniStandUp( class SGameAvatarEx * pOwner, DWORD dwTime ) : SGameWork(pOwner)
|
||
{
|
||
m_dwStartTime = dwTime;
|
||
SetStep( STEP_00 );
|
||
}
|
||
|
||
SWorkAniStandUp::~SWorkAniStandUp()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkAniStandUp::Process( DWORD dwTime )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
m_pOwner->SitProcess( ANI_SITUP );
|
||
SetStep( STEP_01 );
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() && m_pOwner->GetCurrAnimationID() == ANI_SITUP )
|
||
{
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->StandUp();
|
||
SetEnd( TRUE );
|
||
m_pOwner->SetIng(false);
|
||
}
|
||
}
|
||
|
||
//2초 후에는 무조건 종료
|
||
if( (dwTime - m_dwStartTime) > 2000 )
|
||
{
|
||
//일어서는 도중 애니메이션이 바뀌었는지 검사한다( 일어서는 도중 이동 및 공격 할수있기 때문 )
|
||
if( m_pOwner->GetCurrAnimationID() == ANI_SITUP )
|
||
{
|
||
m_pOwner->StandUp();
|
||
}
|
||
m_pOwner->SetAniLock( false );
|
||
SetEnd( TRUE );
|
||
m_pOwner->SetIng(false);
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
SWorkAimingBow::SWorkAimingBow( class SGameAvatarEx * pOwner, AR_HANDLE hTarger, char bowtype ) : SGameWork(pOwner)
|
||
{
|
||
m_hTarget = hTarger;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
m_nTypeBow = 0;
|
||
|
||
// Arrow casting and shooting effect IDs
|
||
// 3049 Normal Arrow_Cast Asura (Female Only)
|
||
// 3050 Normal Arrow_Cast Asura (Male Only)
|
||
// 3051 Normal Arrow_Cast Deva (Female Only)
|
||
// 3052 Normal Arrow_Cast Deva (Male Only)
|
||
|
||
|
||
m_nEffectID[0] = -1;
|
||
m_nEffectID[1] = -1;
|
||
|
||
if( bowtype & TS_ATTACK_EVENT::ATTACK_FLAG_CROSS_BOW )
|
||
{
|
||
m_strFX_01 = "rcfx_cross_arrowattack_start_lv01_";
|
||
m_strFX_02 = "rcfx_cross_arrowattack_loop_lv01_";
|
||
}
|
||
else
|
||
{
|
||
m_strFX_01 = "rcfx_arrowattack_start_lv01_";
|
||
m_strFX_02 = "rcfx_arrowattack_loop_lv01_";
|
||
}
|
||
|
||
const char* szName = GetNX3Name( pOwner->GetRace(), pOwner->GetSex() );
|
||
m_strFX_01 += szName;
|
||
m_strFX_02 += szName;
|
||
|
||
SetStep( STEP_00 );
|
||
|
||
SetWorkType( WORK_AIMINGBOW );
|
||
|
||
pOwner->SetVisibleWeaponTrail( true );
|
||
}
|
||
|
||
SWorkAimingBow::~SWorkAimingBow()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
if( m_nEffectID[0] != -1 ) m_pOwner->DelEffect( m_nEffectID[0] );
|
||
if( m_nEffectID[1] != -1 ) m_pOwner->DelEffect( m_nEffectID[1] );
|
||
}
|
||
}
|
||
|
||
void SWorkAimingBow::ForceEnd()
|
||
{
|
||
m_bEnd = TRUE;
|
||
if( m_nEffectID[0] != -1 ) m_pOwner->DelEffect( m_nEffectID[0] );
|
||
if( m_nEffectID[1] != -1 ) m_pOwner->DelEffect( m_nEffectID[1] );
|
||
}
|
||
|
||
void SWorkAimingBow::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( m_pTarget == NULL )
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->Default();
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
m_pOwner->SetViewVector( *m_pTarget->GetPosition() );
|
||
|
||
////////////////////////////////////////////////////////////////////////////
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
m_pOwner->SetIng(true);
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->NPlayAnimation( ANI_BOW_ATTACK01_A ); //장전
|
||
m_nEffectID[0] = m_pOwner->AddEffect( &FX_DATA_EX( m_strFX_01.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true ) );
|
||
m_pOwner->SetAniLock( true );
|
||
SetStep( STEP_01 );
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() )
|
||
{
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->NPlayAnimation( ANI_BOW_ATTACK01_B, SEQTYPE_LOOP ); //겨누기
|
||
m_nEffectID[1] = m_pOwner->AddEffect( &FX_DATA_EX( m_strFX_02.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true, SEQTYPE_LOOP ) );
|
||
m_pOwner->SetAniLock( true );
|
||
SetStep( STEP_04 );
|
||
}
|
||
}
|
||
|
||
//장전 및 겨누기 이외 모션이 재생될 경우 끝낸다
|
||
if( m_pOwner->GetCurrAnimationID() != ANI_BOW_ATTACK01_A &&
|
||
m_pOwner->GetCurrAnimationID() != ANI_BOW_ATTACK01_B )
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
SetEnd(TRUE);
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
SWorkShootingBow::SWorkShootingBow( class SGameAvatarEx * pOwner, AR_HANDLE hTarger, char bowtype ) : SGameWork(pOwner)
|
||
{
|
||
m_hTarget = hTarger;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
m_pAttackMsg = NULL;
|
||
m_nTypeBow = 0;
|
||
|
||
m_nEffectID = -1;
|
||
|
||
m_strFX_03 = "rcfx_arrowattack_end_lv01_";
|
||
m_strFX_03 += GetNX3Name( pOwner->GetRace(), pOwner->GetSex() );
|
||
|
||
SetStep( STEP_00 );
|
||
|
||
SetWorkType( WORK_SHOOTINGBOW );
|
||
}
|
||
SWorkShootingBow::~SWorkShootingBow()
|
||
{
|
||
SAFE_DELETE( m_pAttackMsg );
|
||
if( m_nEffectID != -1 )
|
||
{
|
||
if( m_pOwner )
|
||
m_pOwner->DelEffect( m_nEffectID );
|
||
}
|
||
}
|
||
void SWorkShootingBow::SetDamegeInfo( const struct SStateInfo * pStateInfo )
|
||
{
|
||
SAFE_DELETE( m_pAttackMsg );
|
||
SMSG_ATTACK * pAttackMsg = new SMSG_ATTACK;
|
||
|
||
pAttackMsg->attacker_handle = pStateInfo->hSelf;
|
||
pAttackMsg->target_handle = pStateInfo->hTarget;
|
||
|
||
pAttackMsg->attack_action = pStateInfo->attack_action;
|
||
pAttackMsg->attack_flag = pStateInfo->attack_flag;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
|
||
pAttackMsg->attack_speed = pStateInfo->dwSpeed;
|
||
pAttackMsg->count = pStateInfo->count;
|
||
|
||
for( int i = 0; i < pStateInfo->count; i++ )
|
||
{
|
||
pAttackMsg->m_vAttackInfoList.push_back( pStateInfo->vAttackInfoList[i] );
|
||
}
|
||
|
||
pAttackMsg->nTypeBow = m_nTypeBow;
|
||
|
||
m_pAttackMsg = pAttackMsg;
|
||
}
|
||
|
||
bool SWorkShootingBow::ProcessingDamage()
|
||
{
|
||
if( GetStep() != STEP_02 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkShootingBow::Process( DWORD dwTime )
|
||
{
|
||
// Fraun performance tweak
|
||
if( IsEnd() ) return;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject(m_hTarget);
|
||
if( m_pTarget == NULL )
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->Default();
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
|
||
int nCurrtStep = GetStep();
|
||
switch (nCurrtStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
m_pOwner->SetViewVector(*m_pTarget->GetPosition());
|
||
// Shoot after the character’s direction has been set
|
||
|
||
if (m_pAttackMsg && !m_pOwner->IsRotation())
|
||
{
|
||
m_pOwner->SetIng(true);
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->NPlayAnimation(ANI_BOW_ATTACK01_C); // Shooting
|
||
m_nEffectID = m_pOwner->AddEffect(&FX_DATA_EX(m_strFX_03.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true));
|
||
m_pOwner->SetAniLock(true);
|
||
|
||
m_pOwner->AddAction(m_pAttackMsg);
|
||
SetStep(STEP_02);
|
||
}
|
||
else
|
||
{
|
||
SetStep(STEP_01);
|
||
}
|
||
break;
|
||
}
|
||
case STEP_01:
|
||
{
|
||
if (m_pAttackMsg && !m_pOwner->IsRotation())
|
||
{
|
||
m_pOwner->SetIng(true);
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->NPlayAnimation(ANI_BOW_ATTACK01_C);
|
||
m_nEffectID = m_pOwner->AddEffect(&FX_DATA_EX(m_strFX_03.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true));
|
||
m_pOwner->SetAniLock(true);
|
||
m_pOwner->AddAction(m_pAttackMsg);
|
||
SetStep(STEP_02);
|
||
}
|
||
}
|
||
case STEP_02:
|
||
{
|
||
if (!m_pOwner->IsPlaying())
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->Default(); // Return to the default pose
|
||
SetEnd(TRUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
// End if any motion other than the shooting motion is played
|
||
if(GetStep() == STEP_02 && m_pOwner->GetCurrAnimationID() != ANI_BOW_ATTACK01_C )
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
SetEnd(TRUE);
|
||
}
|
||
}
|
||
|
||
//==============================================================================================
|
||
//New Skill 시스템
|
||
SNewSkill::SNewSkill( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SGameWork( pOwner ), m_pSkillFX(pSkillFX)
|
||
{
|
||
// SetEnd( true );
|
||
m_fPlayRate = 1.f; //1배
|
||
m_fPlayRateAfterFire = 1.0f;
|
||
|
||
m_hTarget = 0;
|
||
m_pTarget = NULL;
|
||
|
||
m_pEventSet = NULL;
|
||
|
||
m_pDamage = NULL;
|
||
m_pSkillEvent = NULL;
|
||
|
||
m_nCurHitIndex = 0;
|
||
m_nHitCnt = 0;
|
||
|
||
m_dwStartTime = 0;
|
||
|
||
m_nFireMotionID = pSkillFX->nFire_Motion_Id;
|
||
|
||
m_nFxID = -1;
|
||
|
||
//1이면 타겟형
|
||
//0이면 셀프형
|
||
if( m_pSkillFX->szHas_Target > 0 )
|
||
m_bIsSelfSkill = false;
|
||
else
|
||
m_bIsSelfSkill = true;
|
||
|
||
m_dwCatingTime = 0;
|
||
|
||
m_pActionSkillEvent = NULL;
|
||
|
||
m_bIsMeleeSkill = false;
|
||
}
|
||
|
||
SNewSkill::~SNewSkill()
|
||
{
|
||
if(m_nFxID != -1)
|
||
{
|
||
if( m_pOwner )
|
||
m_pOwner->EndLoopFx(m_nFxID);
|
||
}
|
||
|
||
if( !m_vFX_List.empty() )
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
for( unsigned int i(0); m_vFX_List.size()>i; i++ )
|
||
m_pOwner->DelEffect(m_vFX_List[i]);
|
||
}
|
||
|
||
m_vFX_List.erase( m_vFX_List.begin(), m_vFX_List.end() );
|
||
}
|
||
|
||
if( m_pOwner )
|
||
{
|
||
//힛팅 처리 안된 것들 처리
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( m_pTarget )
|
||
{
|
||
while(m_nHitCnt > 0)
|
||
_processDamage();
|
||
}
|
||
}
|
||
|
||
//Event handle 처리
|
||
if( m_pEventSet )
|
||
{
|
||
m_pEventSet->event_clear();
|
||
SAFE_DELETE( m_pEventSet );
|
||
}
|
||
|
||
SAFE_DELETE( m_pSkillEvent );
|
||
SAFE_DELETE( m_pDamage );
|
||
SAFE_DELETE( m_pSkillFX );
|
||
|
||
if( m_pActionSkillEvent )
|
||
{
|
||
if( m_pOwner ) m_pOwner->AddAction( m_pActionSkillEvent );
|
||
|
||
SAFE_DELETE( m_pActionSkillEvent );
|
||
}
|
||
}
|
||
|
||
void SNewSkill::ForceEnd()
|
||
{
|
||
if(m_nFxID != -1)
|
||
{
|
||
m_pOwner->EndLoopFx(m_nFxID);
|
||
}
|
||
m_bEnd = TRUE;
|
||
}
|
||
|
||
void SNewSkill::SetDamegeInfo( const struct SStateInfo * pStateInfo )
|
||
{
|
||
SAFE_DELETE( m_pSkillEvent );
|
||
SAFE_DELETE( m_pDamage );
|
||
|
||
//데미지 일반 데미지 때릴때 사용
|
||
m_pDamage = new SMSG_DAMAGE;
|
||
|
||
m_pDamage->attacker_handle = pStateInfo->hSelf;
|
||
m_pDamage->target_handle = pStateInfo->hTarget;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_pDamage->target_handle );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
SetDamageDisplayName( m_pDamage, m_pTarget );
|
||
|
||
//스킬 이벤트 -> Action 에 날릴때 사용
|
||
m_pSkillEvent = new SMSG_SKILL_EVENT;
|
||
m_pSkillEvent->skill_id = pStateInfo->nSkillID;
|
||
m_pSkillEvent->skill_level = pStateInfo->nSkillLv;
|
||
m_pSkillEvent->caster = m_pOwner->GetArID();
|
||
m_pSkillEvent->target = pStateInfo->hTarget;
|
||
m_pSkillEvent->fire.count = pStateInfo->nRepeat;
|
||
m_pSkillEvent->fire.bMultiple = pStateInfo->bMultiple;
|
||
m_pSkillEvent->fire.range = pStateInfo->range;
|
||
m_pSkillEvent->fire.target_count = pStateInfo->target_count;
|
||
m_pSkillEvent->fire.fire_count = pStateInfo->fire_count;
|
||
|
||
m_pDamage->nSkillID = pStateInfo->nSkillID;
|
||
m_pDamage->nSkillLevel = pStateInfo->nSkillLv;
|
||
|
||
m_nCount = (int)pStateInfo->vSkillResult.size();
|
||
|
||
m_nCurHitIndex = 0;
|
||
m_nHitCnt = m_nCount;
|
||
|
||
//스킬 결과 데미지
|
||
for( unsigned int i(0); pStateInfo->vSkillResult.size()>i; i++ )
|
||
m_pSkillEvent->vSkillResult.push_back( pStateInfo->vSkillResult[i] );
|
||
|
||
_oprint( "Server skill result %d\n", pStateInfo->vSkillResult.size() );
|
||
}
|
||
|
||
void SNewSkill::SetActionSkillEvent( const struct SStateInfo * pStateInfo )
|
||
{
|
||
//스킬 이벤트 -> Action 에 날릴때 사용
|
||
m_pActionSkillEvent = new SMSG_SKILL_EVENT;
|
||
m_pActionSkillEvent->status_type = TS_SC_SKILL::FIRE;
|
||
m_pActionSkillEvent->skill_id = pStateInfo->nSkillID;
|
||
m_pActionSkillEvent->skill_level = pStateInfo->nSkillLv;
|
||
m_pActionSkillEvent->caster = m_pOwner->GetArID();
|
||
m_pActionSkillEvent->target = pStateInfo->hTarget;
|
||
//m_pActionSkillEvent->target_name = pStateInfo->target_name; // Fraun performance tweak
|
||
m_pActionSkillEvent->fire.count = pStateInfo->nRepeat;
|
||
m_pActionSkillEvent->fire.bMultiple = pStateInfo->bMultiple;
|
||
m_pActionSkillEvent->fire.range = pStateInfo->range;
|
||
m_pActionSkillEvent->fire.target_count = pStateInfo->target_count;
|
||
m_pActionSkillEvent->fire.fire_count = pStateInfo->fire_count;
|
||
|
||
//스킬 결과 데미지
|
||
for( unsigned int i(0); pStateInfo->vSkillResult.size()>i; i++ )
|
||
m_pActionSkillEvent->vSkillResult.push_back( pStateInfo->vSkillResult[i] );
|
||
}
|
||
|
||
void SNewSkill::SetTarget( AR_HANDLE handle, class SGameAvatarEx* pTarget )
|
||
{
|
||
m_hTarget = handle;
|
||
m_pTarget = pTarget;
|
||
}
|
||
|
||
void SNewSkill::SetSkillMode( SKILL_MODE bMode )
|
||
{
|
||
m_nMode = bMode;
|
||
if( m_nMode == SKILLMODE_CAST )
|
||
{
|
||
_processView();
|
||
}
|
||
}
|
||
|
||
void SNewSkill::SetPlayRate( float fPlayRate )
|
||
{
|
||
m_fPlayRate = fPlayRate;
|
||
}
|
||
|
||
void SNewSkill::SetStartTime( DWORD dwStartTime )
|
||
{
|
||
m_dwStartTime = dwStartTime;
|
||
}
|
||
|
||
void SNewSkill::SetFireMotionID( int nFireMotionID )
|
||
{
|
||
m_nFireMotionID = nFireMotionID;
|
||
}
|
||
|
||
void SNewSkill::SetCastingTime( DWORD time )
|
||
{
|
||
m_dwCatingTime = time;
|
||
}
|
||
|
||
bool SNewSkill::ProcessingDamage()
|
||
{
|
||
if( m_nHitCnt > 0 || GetSkillMode() != SKILLMODE_FIRE )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SNewSkill::_processDamage()
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pDamage->skillresult = m_pSkillEvent->vSkillResult[m_nCount - m_nHitCnt];
|
||
if( m_pTarget )
|
||
{
|
||
int nBlock = 0;
|
||
int nCritical = 0;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_CRITICAL) nCritical = 1;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_BLOCK) nBlock = 1;
|
||
|
||
m_pOwner->OnDamage( m_pOwner->GetArID(), m_pTarget->GetArID(), m_pDamage );
|
||
|
||
std::string strScript;
|
||
|
||
int resultType = m_pDamage->skillresult.GetType();
|
||
if( (resultType == SkillResult::DAMAGE || resultType == SkillResult::MAGIC_DAMAGE ||
|
||
resultType == SkillResult::CHAIN_DAMAGE || resultType == SkillResult::CHAIN_MAGIC_DAMAGE)
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
m_pTarget->Damage();
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), m_pTarget->GetArID(), nCritical, nBlock );
|
||
}
|
||
else if( m_pDamage->skillresult.GetType() == SkillResult::DAMAGE_WITH_KNOCK_BACK
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
if( m_pTarget->GetHP() > 0 )
|
||
{
|
||
m_pTarget->SetAniLock( false );
|
||
m_pTarget->NPlayAnimation( ANI_DAMAGE01, SEQTYPE_LOOP );
|
||
}
|
||
|
||
K3DVector vKnockBackPosition = K3DVector( m_pDamage->skillresult.damage_kb.x, m_pDamage->skillresult.damage_kb.y, 0.f );
|
||
m_pTarget->SetKnockBack( vKnockBackPosition , m_pDamage->skillresult.damage_kb.speed );
|
||
|
||
m_pTarget->Damage();
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), m_pTarget->GetArID(), nCritical, nBlock );
|
||
}
|
||
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
}
|
||
--m_nHitCnt;
|
||
}
|
||
}
|
||
|
||
void SNewSkill::_processDamageMulti()
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pDamage->skillresult = m_pSkillEvent->vSkillResult[m_nCount - m_nHitCnt];
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_pDamage->skillresult.GetTargetHandle() );
|
||
if( pTarget )
|
||
{
|
||
int nBlock = 0;
|
||
int nCritical = 0;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_CRITICAL) nCritical = 1;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_BLOCK) nBlock = 1;
|
||
|
||
m_pOwner->OnDamage( m_pOwner->GetArID(), pTarget->GetArID(), m_pDamage );
|
||
|
||
std::string strScript;
|
||
|
||
if( (m_pDamage->skillresult.GetType() == SkillResult::DAMAGE || m_pDamage->skillresult.GetType() == SkillResult::MAGIC_DAMAGE)
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
pTarget->Damage();
|
||
XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), pTarget->GetArID(), nCritical, nBlock );
|
||
}
|
||
else if( m_pDamage->skillresult.GetType() == SkillResult::DAMAGE_WITH_KNOCK_BACK
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
if( pTarget->GetHP() > 0 )
|
||
{
|
||
pTarget->SetAniLock( false );
|
||
pTarget->NPlayAnimation( ANI_DAMAGE01, SEQTYPE_LOOP );
|
||
}
|
||
|
||
K3DVector vKnockBackPosition = K3DVector( m_pDamage->skillresult.damage_kb.x, m_pDamage->skillresult.damage_kb.y, 0.f );
|
||
pTarget->SetKnockBack( vKnockBackPosition , m_pDamage->skillresult.damage_kb.speed );
|
||
|
||
pTarget->Damage();
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), pTarget->GetArID(), nCritical, nBlock );
|
||
}
|
||
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
}
|
||
--m_nHitCnt;
|
||
}
|
||
}
|
||
|
||
void SNewSkill::Process( DWORD dwTime )
|
||
{
|
||
m_dwTime = dwTime;
|
||
|
||
if( IsEnd() ) return;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
_processDefCast( dwTime );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
_processDefFire( dwTime );
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
void SNewSkill::_processEventSet( DWORD eventTime )
|
||
{
|
||
if( !m_pEventSet ) return;
|
||
|
||
if( m_pEventSet->pCurEvent00_effect )
|
||
{
|
||
//시작 되자 마자 나오는 Effect
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
m_pEventSet->pCurEvent00_effect->GetData( 0, pKey1, pKey2 );
|
||
if( pKey1 && !pKey1->bUse )
|
||
{
|
||
pKey1->bUse = true;
|
||
m_pOwner->FindMotionAddOnFx( pKey1 );
|
||
switch(pKey1->nSpeedType)
|
||
{
|
||
case 0:
|
||
{
|
||
float fPlayRate = m_pOwner->GetCurPlayRate();
|
||
m_pOwner->AddEffect( &FX_DATA_EX( pKey1->strEffect.c_str(), pKey1->followflag, m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), pKey1->nEffPos, false, pKey1->nSpeedType, fPlayRate ) );
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
if(!pKey1->strEffect.empty())
|
||
{
|
||
float fPlayRate = m_pOwner->GetCurPlayRate();
|
||
m_pOwner->AddEffect( &FX_DATA_EX( pKey1->strEffect.c_str(), pKey1->followflag, m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), pKey1->nEffPos, false, pKey1->nSpeedType, fPlayRate ) );
|
||
}
|
||
|
||
//검 잔상
|
||
m_pOwner->ActivateFxSwordSlashForSkill();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( m_pEventSet->pCurEvent00_sound )
|
||
{
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
m_pEventSet->pCurEvent00_sound->GetData( eventTime, pKey1, pKey2 );
|
||
if( pKey1 && !pKey1->bUse )
|
||
{
|
||
pKey1->bUse = true;
|
||
if( pKey1->nSound_play_probability != 100 )
|
||
{
|
||
int nRatio = rand()%100;
|
||
if( nRatio < pKey1->nSound_play_probability )
|
||
m_pOwner->StartSound( m_pOwner, pKey1->strSound.c_str(), *m_pOwner->GetPosition(), true, pKey1->nSoundVolume, false, pKey1->SoundOption );
|
||
}
|
||
else
|
||
{
|
||
m_pOwner->StartSound( m_pOwner, pKey1->strSound.c_str(), *m_pOwner->GetPosition(), true, pKey1->nSoundVolume, false, pKey1->SoundOption );
|
||
}
|
||
}
|
||
}
|
||
|
||
if( m_pEventSet->pCurEvent00_motion_effect )
|
||
{
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
|
||
m_pEventSet->pCurEvent00_motion_effect->GetData( eventTime, pKey1, pKey2 );
|
||
|
||
if( pKey1 && pKey1->bUse == false )
|
||
{
|
||
pKey1->bUse = true; //사용.
|
||
|
||
FX_DATA fxdata;
|
||
fxdata.nFX_ID = pKey1->nFXsetID;
|
||
fxdata.nEffPos = pKey1->nEffPos;
|
||
fxdata.owner = m_pOwner->GetArID();
|
||
fxdata.attack = m_pOwner->GetArID();
|
||
fxdata.target = m_pOwner->GetArID();
|
||
fxdata.fPlayRate = pKey1->fPlayRate;
|
||
fxdata.nPlayID = 0;//한번
|
||
fxdata.nMode = 0;//기본
|
||
|
||
m_pOwner->AddEffect( &fxdata );
|
||
}
|
||
}
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
return;
|
||
|
||
// _processEvent( , eventTime );
|
||
// _processEvent( , eventTime );
|
||
_processEvent( m_pEventSet->pCurEvent01 , eventTime );
|
||
_processEvent( m_pEventSet->pCurEvent02 , eventTime );
|
||
_processEvent( m_pEventSet->pCurEvent03 , eventTime );
|
||
_processEvent( m_pEventSet->pCurEvent04 , eventTime );
|
||
_processEvent( m_pEventSet->pCurEvent05 , eventTime );
|
||
_processEvent( m_pEventSet->pCurEvent06 , eventTime );
|
||
}
|
||
|
||
void SNewSkill::_processEvent( KEventKeyRes<Key_EVENT_NEW>* event, DWORD eventTime )
|
||
{
|
||
if( event )
|
||
{
|
||
Key_EVENT_NEW * pKey1 = NULL;
|
||
Key_EVENT_NEW * pKey2 = NULL;
|
||
event->GetData( eventTime, pKey1, pKey2 );
|
||
|
||
if( pKey1 && !pKey1->bUse )
|
||
{
|
||
pKey1->bUse = true;
|
||
|
||
std::string strScript;
|
||
|
||
//힛팅임.
|
||
if( pKey1->nHandleID == SMotionEventHanderDB::EV_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_LEFT_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_RIGHT_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_TWO_HAND_HIT )
|
||
{
|
||
assert( GetSkillMode() != SKILLMODE_CAST && "캐스팅 모션에 힛팅 연출 모션이 설정 되어 있음." );
|
||
OnEventHit();
|
||
}
|
||
else if( pKey1->nHandleID == SMotionEventHanderDB::EV_SHOOT || pKey1->nHandleID == SMotionEventHanderDB::EV_SWING )
|
||
{
|
||
// 이것도 따로 처리해야 해야 할듯
|
||
OnEventSwing();
|
||
XStringUtil::Format( strScript, "%s( %u, %u )", "call_fx_ch_weapone_attack", m_pOwner->GetArID(), m_pTarget->GetArID() );
|
||
}
|
||
else
|
||
{
|
||
if( pKey1->nHandleID != 0 )
|
||
{
|
||
_MOTION_EVENT_HANDER * pHandler = GetMotionEventHanderDB().GetScript( pKey1->nHandleID );
|
||
if( pHandler )
|
||
{
|
||
OnEventEtc();
|
||
XStringUtil::Format( strScript, "%s( %u )", pHandler->szScript, m_pOwner->GetArID(), m_pTarget->GetArID() );
|
||
}
|
||
}
|
||
}
|
||
|
||
if( pKey1->nHandleID == SMotionEventHanderDB::EV_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_LEFT_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_RIGHT_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_TWO_HAND_HIT ||
|
||
pKey1->nHandleID == SMotionEventHanderDB::EV_SHOOT )
|
||
{
|
||
//이펙트 출력
|
||
if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
if( m_pActionSkillEvent )
|
||
{
|
||
if( m_pOwner->GetObjType() != TS_ENTER::GAME_MOB ) assert( false );
|
||
|
||
m_pOwner->AddAction( m_pActionSkillEvent );
|
||
SAFE_DELETE( m_pActionSkillEvent );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
}
|
||
}
|
||
}
|
||
|
||
void SNewSkill::_getEventSet()
|
||
{
|
||
//Ani 변경 되어서, 시작 시간 다시 설정
|
||
m_dwStartTime = m_dwTime;
|
||
|
||
//Event handle 처리
|
||
if( m_pEventSet )
|
||
{
|
||
m_pEventSet->event_clear();
|
||
SAFE_DELETE( m_pEventSet );
|
||
}
|
||
m_pEventSet = new EVENT_SET;
|
||
EVENT_SET event_set;
|
||
m_pOwner->GetCurSeqEvent( event_set );
|
||
_setEvent( event_set.pCurEvent00_effect, m_pEventSet->pCurEvent00_effect );
|
||
_setEvent( event_set.pCurEvent00_sound , m_pEventSet->pCurEvent00_sound );
|
||
_setEvent( event_set.pCurEvent00_motion_effect, m_pEventSet->pCurEvent00_motion_effect );
|
||
_setEvent( event_set.pCurEvent01, m_pEventSet->pCurEvent01 );
|
||
_setEvent( event_set.pCurEvent02, m_pEventSet->pCurEvent02 );
|
||
_setEvent( event_set.pCurEvent03, m_pEventSet->pCurEvent03 );
|
||
_setEvent( event_set.pCurEvent04, m_pEventSet->pCurEvent04 );
|
||
_setEvent( event_set.pCurEvent05, m_pEventSet->pCurEvent05 );
|
||
_setEvent( event_set.pCurEvent06, m_pEventSet->pCurEvent06 );
|
||
}
|
||
|
||
void SNewSkill::_processDefCast( DWORD dwTime )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{ //손 올리기
|
||
if( m_pSkillFX->nCasting_Start_Motion_Id != 0 )
|
||
{
|
||
m_pOwner->NPlayAnimation( m_pSkillFX->nCasting_Start_Motion_Id, SEQTYPE_NORMAL, m_fPlayRate*4.8f );
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nCasting_Fx_Set_Id, EFFECT_POS_BOTTOM, SEQTYPE_LOOP );
|
||
_getEventSet();
|
||
}
|
||
|
||
// m_pOwner->OnSkillDamage( m_pOwner->GetArID(), m_pOwner->GetArID(), )
|
||
|
||
SetStep(STEP_01);
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{ //손 올리고 대기
|
||
if( m_pSkillFX->nCasting_Start_Motion_Id != 0 )
|
||
{
|
||
if( m_pOwner->GetCurrAnimationID() == m_pSkillFX->nCasting_Start_Motion_Id && !m_pOwner->IsPlaying() )
|
||
{
|
||
//밀리스킬과 마법스킬을 구분해서 마법스킬만 skill_b를 루프
|
||
if (m_bIsMeleeSkill)
|
||
m_pOwner->NPlayAnimation( m_pSkillFX->nCasting_Middle_Motion_Id, SEQTYPE_NORMAL, m_fPlayRate*4.8 );
|
||
else
|
||
m_pOwner->NPlayAnimation( m_pSkillFX->nCasting_Middle_Motion_Id, SEQTYPE_LOOP, 4.8f );
|
||
// _addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nCasting_Fx_Set_Id, EFFECT_POS_BOTTOM, SEQTYPE_LOOP );
|
||
_getEventSet();
|
||
|
||
SetStep(STEP_02);
|
||
}
|
||
}
|
||
else if( m_pSkillFX->nCasting_Start_Motion_Id == 0 )
|
||
{
|
||
if( m_pSkillFX->nCasting_Middle_Motion_Id != 0 )
|
||
{
|
||
//밀리스킬과 마법스킬을 구분해서 마법스킬만 skill_b를 루프
|
||
if (m_bIsMeleeSkill)
|
||
m_pOwner->NPlayAnimation( m_pSkillFX->nCasting_Middle_Motion_Id, SEQTYPE_NORMAL, m_fPlayRate*4.8 );
|
||
else
|
||
m_pOwner->NPlayAnimation( m_pSkillFX->nCasting_Middle_Motion_Id, SEQTYPE_LOOP, 4.8f );
|
||
|
||
if( m_nFxID == -1 )
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nCasting_Fx_Set_Id, EFFECT_POS_BOTTOM, SEQTYPE_LOOP );
|
||
|
||
_getEventSet();
|
||
}
|
||
SetStep(STEP_02);
|
||
}
|
||
}
|
||
else if( GetStep() == STEP_02 )
|
||
{
|
||
if( m_bIsMeleeSkill && !m_pOwner->IsPlaying() )
|
||
{
|
||
if (m_nFireMotionID != 0)
|
||
{
|
||
m_pOwner->NPlayAnimation( m_nFireMotionID , SEQTYPE_NORMAL, m_fPlayRateAfterFire * 4.8f );
|
||
if( m_pSkillFX->nFire_Fx_Set_Id != 0 )
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nFire_Fx_Set_Id , EFFECT_POS_BOTTOM, SEQTYPE_NORMAL );
|
||
_oprint("강제로 fire애니 재생\n");
|
||
}
|
||
}
|
||
// SetEnd(TRUE);
|
||
}
|
||
}
|
||
|
||
void SNewSkill::_processDefFire( DWORD dwTime )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
_oprint("Fire animation started: %d\n", m_nFireMotionID);
|
||
if( m_nFireMotionID != 0 )
|
||
{
|
||
if ( m_bIsMeleeSkill && m_pOwner->IsPlaying() && (m_pOwner->GetCurrAnimationID() == m_nFireMotionID))
|
||
{ // 밀리스킬이고 재생중이고 재생중인게 파이어모션이면
|
||
} // 아무것도 하지않음
|
||
else if (m_nFireMotionID == ANI_ATTACK01)
|
||
{ // 스킬이지만 평타모션으로 나가고 있을 경우도 아무것도 하지 않음
|
||
}
|
||
else // 아니면 파이어모션 출력
|
||
{
|
||
m_pOwner->NPlayAnimation( m_nFireMotionID , SEQTYPE_NORMAL, m_fPlayRateAfterFire * 4.8f );
|
||
//시전시 동반 되는 이펙트
|
||
if( m_pSkillFX->nFire_Fx_Set_Id != 0 )
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nFire_Fx_Set_Id , EFFECT_POS_BOTTOM, SEQTYPE_NORMAL );
|
||
}
|
||
|
||
_getEventSet();
|
||
}
|
||
SetStep(STEP_01);
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( m_nFireMotionID != 0 )
|
||
{
|
||
if( m_pOwner->GetCurrAnimationID() == m_nFireMotionID && !m_pOwner->IsPlaying() )
|
||
{ //시전 연출 끝났음.
|
||
SetStep(STEP_02);
|
||
}
|
||
}
|
||
else if( m_nFireMotionID == 0 )
|
||
{ //시전 모션 없음.
|
||
SetStep(STEP_02);
|
||
}
|
||
}
|
||
else if( GetStep() == STEP_02 )
|
||
{
|
||
m_pOwner->EndUseSkill( m_pSkillFX->nID );
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(TRUE);
|
||
}
|
||
|
||
//이미 스킬이 완료 되었고
|
||
if( m_pOwner->IsUseSkill_complete() == true )
|
||
{ //기존 애니메이션이 다르면, 종료
|
||
if( m_nFireMotionID != 0 && m_pOwner->GetCurrAnimationID() != m_nFireMotionID )
|
||
{
|
||
_oprint( "Fire ended because the animation was different. [cur:%d] [fire:%d]\n", m_pOwner->GetCurrAnimationID(), m_nFireMotionID );
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// AziaMafia FixSkill
|
||
void SNewSkill::_processView()
|
||
{
|
||
if (IsEnd()) return;
|
||
|
||
if (m_pTarget && !m_bIsSelfSkill)
|
||
{
|
||
if (m_pTarget->GetArID() != m_pOwner->GetArID())
|
||
{
|
||
if (GetSkillMode() == SKILLMODE_FIRE && m_pOwner->GetCurrAnimationID() != m_nFireMotionID)
|
||
return;
|
||
|
||
m_pOwner->SetViewVector(*m_pTarget->GetPosition());
|
||
}
|
||
else
|
||
m_bIsSelfSkill = true;
|
||
}
|
||
}
|
||
|
||
void SNewSkill::_addEffect( const AR_HANDLE & owner, const AR_HANDLE & attack, const AR_HANDLE & target, const int & nFX_ID, const int & nFX_pos, int nAnitype, float fPlayRate )
|
||
{
|
||
FX_DATA fx_data;
|
||
fx_data.owner = owner;
|
||
fx_data.attack = attack;
|
||
fx_data.target = target;
|
||
fx_data.nFX_ID = nFX_ID; //시전(타격)연출 보조FX ID
|
||
fx_data.nEffPos = nFX_pos; //시전(타격)연출 보조FX 위치
|
||
fx_data.fPlayRate = fPlayRate;
|
||
if(nAnitype == SEQTYPE_LOOP ) fx_data.bIsLoop = true;
|
||
m_nFxID = m_pOwner->AddEffect( &fx_data );
|
||
}
|
||
|
||
void SNewSkill::_addEffect( const AR_HANDLE & target, const int & nFX_ID, const int & nFX_pos )
|
||
{
|
||
FX_DATA fx_data;
|
||
fx_data.owner = target;
|
||
fx_data.attack = target;
|
||
fx_data.target = target;
|
||
fx_data.nFX_ID = nFX_ID; //시전(타격)연출 보조FX ID
|
||
fx_data.nEffPos = nFX_pos; //시전(타격)연출 보조FX 위치
|
||
m_nFxID = m_pTarget->AddEffect( &fx_data );
|
||
}
|
||
|
||
void SNewSkill::_addFX( int nStage_Type )
|
||
{
|
||
if( nStage_Type == SS_TYPE_121 )
|
||
{
|
||
if( m_pSkillFX->fStage_Data[7] == 0 ) return;
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pTarget->GetArID(), m_pSkillFX->fStage_Data[7], m_pSkillFX->fStage_Data[8], SEQTYPE_NORMAL, m_pSkillFX->fStage_Data[1]*4.8f );
|
||
}
|
||
else if( nStage_Type == SS_TYPE_122 )
|
||
{
|
||
if( m_pSkillFX->fStage_Data[2] == 0 ) return;
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pTarget->GetArID(), m_pSkillFX->fStage_Data[2], m_pSkillFX->fStage_Data[3], SEQTYPE_NORMAL, m_pSkillFX->fStage_Data[1]*4.8f );
|
||
|
||
if( m_pSkillFX->fStage_Data[4] == 0 ) return;
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pTarget->GetArID(), m_pSkillFX->fStage_Data[4], m_pSkillFX->fStage_Data[5], SEQTYPE_NORMAL, m_pSkillFX->fStage_Data[1]*4.8f );
|
||
}
|
||
else if( nStage_Type == SS_TYPE_123 )
|
||
{
|
||
if( m_pSkillFX->fStage_Data[7] == 0 ) return;
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->fStage_Data[7], m_pSkillFX->fStage_Data[8], SEQTYPE_NORMAL, m_pSkillFX->fStage_Data[1]*4.8f );
|
||
}
|
||
else if( nStage_Type == SS_TYPE_171)
|
||
{
|
||
if( m_pSkillFX->fStage_Data[7] == 0 ) return;
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pTarget->GetArID(), m_pSkillFX->fStage_Data[7], m_pSkillFX->fStage_Data[8], SEQTYPE_NORMAL, m_pSkillFX->fStage_Data[1]*4.8f );
|
||
}
|
||
}
|
||
|
||
float SNewSkill::CalcCurrentAniTimeTime( SGameAvatarEx* pAvatar )
|
||
{
|
||
if( pAvatar == NULL ) return 0.0f;
|
||
|
||
int nBoneCnt = 0;
|
||
DWORD dwMinTime = 0, dwMaxTime = 0;
|
||
DWORD dwCurAniTime = 0;
|
||
pAvatar->GetCurrentAnimationInfo( nBoneCnt, dwMinTime, dwMaxTime, dwCurAniTime );
|
||
|
||
float fMaxTime = (float)dwMaxTime / 160.0f;
|
||
float fMinTime = (float)dwMinTime / 160.0f;
|
||
|
||
fMaxTime = ((fMaxTime * 4.8f) / 100.0f ) * 1000.0f;
|
||
fMinTime = ((fMinTime * 4.8f) / 100.0f ) * 1000.0f;
|
||
|
||
return fMaxTime - fMinTime;
|
||
}
|
||
|
||
//==============================================================================================
|
||
//추후에 소환 연출 개개별로 만들 필요 있음.
|
||
SWorkSummonCall::SWorkSummonCall( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
//마법 모션임.
|
||
pSkillFX->nCasting_Start_Motion_Id; //시작
|
||
pSkillFX->nCasting_Middle_Motion_Id; //대기
|
||
|
||
pSkillFX->nFire_Motion_Id; //시전
|
||
|
||
SetStep(STEP_00);
|
||
// 2010.08.31 - prodongi
|
||
m_nFXID = -1;
|
||
}
|
||
|
||
SWorkSummonCall::~SWorkSummonCall()
|
||
{
|
||
// 2010.08.31 - prodongi
|
||
//if( m_nFXID != 0 )
|
||
if( m_nFXID != 0 && -1 != m_nFXID)
|
||
{
|
||
if( m_pOwner )
|
||
m_pOwner->EndOtherEffect( m_nFXID );
|
||
}
|
||
}
|
||
|
||
void SWorkSummonCall::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
if( GetStep() == STEP_00 && GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
int fxid = 5081;
|
||
m_nFXID = m_pOwner->AddOtherEffect( SGameOtherEffectMng::FX_CAST_SUMMONING_CREATURE, &OtherFxData( m_pOwner->GetArID(), 0,fxid, m_dwCatingTime, &m_vPos ) );
|
||
}
|
||
else if( GetStep() == STEP_00 && GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
// 2010.08.31 소환 주문서 사용 경우에 캐스팅 시간이 0이므로 SKILLMODE_CAST에 들어가지 않아서 이펙트가 출력 안될때가 만다
|
||
// 그래서 SKILLMODE_FIRE에서 출력하도록 해줌 - prodongi
|
||
if (-1 == m_nFXID && 0 == m_dwCatingTime)
|
||
{
|
||
AR_HANDLE handle = m_pOwner->GetArID();
|
||
FX_DATA fx_data;
|
||
fx_data.attack = handle;
|
||
fx_data.owner = handle;
|
||
fx_data.target = handle;
|
||
fx_data.fPlayRate = 1.f;
|
||
fx_data.nEffPos = EFFECT_POS_BOTTOM;
|
||
fx_data.nPlayID = 0;
|
||
fx_data.nFX_ID = 5081;
|
||
|
||
m_pOwner->AddEffect(&fx_data);
|
||
m_nFXID = 0;
|
||
}
|
||
|
||
m_pOwner->OnUISync( m_pOwner->GetArID(), m_pOwner->GetArID() );
|
||
}
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
m_pOwner->SetViewVector( m_vPos );
|
||
}
|
||
//==============================================================================================
|
||
//추후에 역소환 연출 개개별로 만들 필요 있음.
|
||
SWorkSummonReCall::SWorkSummonReCall( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
//마법 모션임.
|
||
pSkillFX->nCasting_Start_Motion_Id; //시작
|
||
pSkillFX->nCasting_Middle_Motion_Id; //대기
|
||
|
||
pSkillFX->nFire_Motion_Id; //시전
|
||
|
||
}
|
||
|
||
SWorkSummonReCall::~SWorkSummonReCall()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkSummonReCall::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
if( GetStep() == STEP_00 && GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
m_pOwner->OnUISync( m_pOwner->GetArID(), m_pOwner->GetArID() );
|
||
}
|
||
|
||
SNewSkill::Process( dwTime );
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkWeaponSwingHit::SWorkWeaponSwingHit( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
//물리 스킬
|
||
// pSkillFX->nCasting_Start_Motion_Id; //시작
|
||
// pSkillFX->nCasting_Middle_Motion_Id; //대기
|
||
|
||
// pSkillFX->nFire_Motion_Id; //시전
|
||
|
||
if( m_pSkillFX->fStage_Data[0] == 0 )
|
||
m_bMultiAttack = false;
|
||
else
|
||
m_bMultiAttack = true;
|
||
|
||
|
||
SetStep(STEP_00);
|
||
}
|
||
|
||
SWorkWeaponSwingHit::~SWorkWeaponSwingHit()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
//처리가 안됐다면
|
||
if( m_bMultiAttack )
|
||
{
|
||
while( m_nHitCnt > 0 ) //_processDamageMulti() 여기서 --m_nHitCnt 무조건 수행하므로 무한 루프 가능성은 없음
|
||
{
|
||
_processDamageMulti();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkWeaponSwingHit::OnEventHit()
|
||
{
|
||
/// 2010.10.07 epic6에서 적용 안된 것 추가
|
||
/*
|
||
//대상 1
|
||
if( !m_bMultiAttack )
|
||
{
|
||
_processDamage();
|
||
}
|
||
else //광역
|
||
{
|
||
while( m_nHitCnt > 0 ) //_processDamageMulti() 여기서 --m_nHitCnt 무조건 수행하므로 무한 루프 가능성은 없음
|
||
{
|
||
_processDamageMulti();
|
||
}
|
||
}
|
||
*/
|
||
|
||
if( m_bMultiAttack )
|
||
_processDamage();
|
||
else
|
||
{
|
||
while( m_nHitCnt > 0 ) //_processDamageMulti() 여기서 --m_nHitCnt 무조건 수행하므로 무한 루프 가능성은 없음
|
||
{
|
||
_processDamageMulti();
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkWeaponSwingHit::OnEventSwing()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkWeaponSwingHit::OnEventEtc()
|
||
{
|
||
|
||
}
|
||
|
||
/// 2010.10.07 epic6에서 적용 안되서 추가함 - prodongi
|
||
/*
|
||
void SWorkWeaponSwingHit::_processDamage()
|
||
{
|
||
if( m_pTarget )
|
||
{
|
||
if( m_pSkillFX->nHit_Fx_Set_Id != 0 )
|
||
_addEffect( m_pTarget->GetArID(), m_pTarget->GetArID(), m_pTarget->GetArID(), m_pSkillFX->nHit_Fx_Set_Id, m_pSkillFX->nHit_Fx_Set_Position_Id );
|
||
}
|
||
SNewSkill::_processDamage();
|
||
}
|
||
*/
|
||
|
||
void SWorkWeaponSwingHit::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkShieldSwingHit::SWorkShieldSwingHit( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
//물리 스킬
|
||
pSkillFX->nCasting_Start_Motion_Id; //시작
|
||
pSkillFX->nCasting_Middle_Motion_Id; //대기
|
||
|
||
pSkillFX->nFire_Motion_Id; //시전
|
||
|
||
if( m_pSkillFX->fStage_Data[0] == 0 )
|
||
m_bMultiAttack = false;
|
||
else
|
||
m_bMultiAttack = true;
|
||
}
|
||
|
||
SWorkShieldSwingHit::~SWorkShieldSwingHit()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
//처리가 안됐다면
|
||
if( m_bMultiAttack )
|
||
{
|
||
while( m_nHitCnt > 0 ) //_processDamageMulti() 여기서 --m_nHitCnt 무조건 수행하므로 무한 루프 가능성은 없음
|
||
{
|
||
_processDamageMulti();
|
||
}
|
||
}
|
||
else
|
||
_processDamage();
|
||
}
|
||
}
|
||
|
||
void SWorkShieldSwingHit::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
void SWorkShieldSwingHit::OnEventHit()
|
||
{
|
||
//대상 1
|
||
if( !m_bMultiAttack )
|
||
{
|
||
_processDamage();
|
||
}
|
||
else //광역
|
||
{
|
||
while( m_nHitCnt > 0 ) //_processDamage() 여기서 --m_nHitCnt 무조건 수행하므로 무한 루프 가능성은 없음
|
||
{
|
||
_processDamageMulti();
|
||
}
|
||
}
|
||
}
|
||
void SWorkShieldSwingHit::OnEventSwing()
|
||
{
|
||
|
||
}
|
||
void SWorkShieldSwingHit::OnEventEtc()
|
||
{
|
||
|
||
}
|
||
|
||
//==============================================================================================
|
||
//스킬 연출 유형 121
|
||
SWorkWeaponSwing_3Motion::SWorkWeaponSwing_3Motion( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
int nFX1 = pSkillFX->fStage_Data[0];//모션배분 (0:순차 1:랜덤)
|
||
int nFX2 = pSkillFX->fStage_Data[1];//모션속도변화 (1=100%, 클수록 빨라짐)
|
||
int nFX3 = pSkillFX->fStage_Data[2];//시전(타격)모션1 ID
|
||
int nFX4 = pSkillFX->fStage_Data[3];//시전(타격)모션2 ID
|
||
int nFX5 = pSkillFX->fStage_Data[4];//시전(타격)모션3 ID
|
||
int nFX6 = pSkillFX->fStage_Data[5];//시전(타격)연출 보조FX ID
|
||
int nFX7 = pSkillFX->fStage_Data[6];//시전(타격)연출 보조FX 위치
|
||
|
||
m_fPlayRate = pSkillFX->fStage_Data[1]; //재생 배속
|
||
|
||
// m_nLocalFireMotionID[0] = pSkillFX->fStage_Data[2];
|
||
// m_nLocalFireMotionID[1] = pSkillFX->fStage_Data[3];
|
||
// m_nLocalFireMotionID[2] = pSkillFX->fStage_Data[4];
|
||
|
||
m_nCurHitCount = 0;
|
||
|
||
m_cMaxHitCount = (int)pSkillFX->fStage_Data[9];
|
||
if( m_cMaxHitCount <= 0 )
|
||
m_cMaxHitCount = 3;
|
||
|
||
m_pLocalFireMotionID = new int[m_cMaxHitCount];
|
||
for( unsigned char cMaxHitCount = 0; cMaxHitCount < m_cMaxHitCount; ++cMaxHitCount )
|
||
m_pLocalFireMotionID[cMaxHitCount] = pSkillFX->fStage_Data[2+cMaxHitCount]; //시전(타격)모션
|
||
}
|
||
|
||
SWorkWeaponSwing_3Motion::~SWorkWeaponSwing_3Motion()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( m_pTarget )
|
||
{
|
||
while(m_nHitCnt > 0)
|
||
_processDamage();
|
||
}
|
||
}
|
||
|
||
SAFE_DELETE_ARRAY( m_pLocalFireMotionID );
|
||
}
|
||
|
||
void SWorkWeaponSwing_3Motion::OnEventHit()
|
||
{
|
||
_processDamage();
|
||
}
|
||
|
||
void SWorkWeaponSwing_3Motion::OnEventSwing()
|
||
{
|
||
// _oprint( "스윙 이벤트\n" );
|
||
}
|
||
|
||
void SWorkWeaponSwing_3Motion::OnEventEtc()
|
||
{
|
||
// _oprint( "그외 이벤트\n" );
|
||
}
|
||
|
||
bool SWorkWeaponSwing_3Motion::ProcessingDamage()
|
||
{
|
||
//마지막 연타가 m_nCurHitCount == 2
|
||
//히트 카운트가 m_nHitCnt == 0
|
||
//SkillMode는 GetSkillMode() == SKILLMODE_FIRE
|
||
if( m_nCurHitCount != 2 || m_nHitCnt > 0 || GetSkillMode() != SKILLMODE_FIRE )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkWeaponSwing_3Motion::_processDamage()
|
||
{
|
||
//타겟 만큼 순차적으로 데미지 처리
|
||
for( unsigned char target_count = 0; target_count < m_pSkillEvent->fire.target_count; ++target_count )
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pDamage->skillresult = m_pSkillEvent->vSkillResult[m_nCount - m_nHitCnt];
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_pDamage->skillresult.GetTargetHandle() );
|
||
if( pTarget )
|
||
{
|
||
int nBlock = 0;
|
||
int nCritical = 0;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_CRITICAL) nCritical = 1;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_BLOCK) nBlock = 1;
|
||
|
||
m_pOwner->OnDamage( m_pOwner->GetArID(), pTarget->GetArID(), m_pDamage );
|
||
|
||
if( (m_pDamage->skillresult.GetType() == SkillResult::DAMAGE || m_pDamage->skillresult.GetType() == SkillResult::MAGIC_DAMAGE)
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
pTarget->Damage();
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//std::string strScript;
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), pTarget->GetArID(), nCritical, nBlock );
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
|
||
if( m_pSkillFX->nSub_Fire_Fx_Set_Id != 0 )
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nSub_Fire_Fx_Set_Id, m_pSkillFX->nSub_Fire_Fx_Position );
|
||
if( m_pSkillFX->nHit_Fx_Set_Id != 0 )
|
||
_addEffect( pTarget->GetArID(), pTarget->GetArID(), pTarget->GetArID(), m_pSkillFX->nHit_Fx_Set_Id, m_pSkillFX->nHit_Fx_Set_Position_Id );
|
||
}
|
||
}
|
||
--m_nHitCnt;
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkWeaponSwing_3Motion::SetCurHitCount( int nCurHitCount )
|
||
{
|
||
m_nCurHitCount = nCurHitCount;
|
||
}
|
||
|
||
void SWorkWeaponSwing_3Motion::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_dwTime = dwTime;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
_processView();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
_addFX( m_pSkillFX->nStage_Type_Id );
|
||
}
|
||
_processDefCast( dwTime );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
if( m_nCurHitCount < m_cMaxHitCount && m_pLocalFireMotionID[m_nCurHitCount] != 0 )
|
||
{
|
||
m_pOwner->NPlayAnimation( m_pLocalFireMotionID[m_nCurHitCount], SEQTYPE_NORMAL, m_fPlayRate * 4.8f );
|
||
_getEventSet();
|
||
|
||
if( m_nCurHitCount == 0 )
|
||
_addFX( m_pSkillFX->nStage_Type_Id );
|
||
|
||
SetStep( STEP_01 );
|
||
}
|
||
else
|
||
{
|
||
m_pOwner->EndUseSkill( m_pSkillFX->nID );
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
int nAniType = m_pOwner->GetCurrAnimationID();
|
||
if( !m_pOwner->IsPlaying() || !CurrentlyAnimationIsFire() )
|
||
{
|
||
m_pOwner->EndUseSkill( m_pSkillFX->nID );
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
bool SWorkWeaponSwing_3Motion::CurrentlyAnimationIsFire()
|
||
{
|
||
int nCurrentAniID = m_pOwner->GetCurrAnimationID();
|
||
for( unsigned char cMaxHitCount = 0; cMaxHitCount < m_cMaxHitCount; ++cMaxHitCount )
|
||
{
|
||
if( nCurrentAniID == m_pLocalFireMotionID[cMaxHitCount] )
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
//==============================================================================================
|
||
//스킬 연출 유형 122
|
||
SWorkWeaponSwing_ContinuousHits::SWorkWeaponSwing_ContinuousHits( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
m_nFireMotionID = pSkillFX->fStage_Data[0]; //시전모션 ID
|
||
m_nEndFireMotionID = pSkillFX->fStage_Data[6];
|
||
m_fPlayRate = pSkillFX->fStage_Data[1]; //모션속도변화 (1=100%, 클수록 빨라짐)
|
||
|
||
//pSkillFX->nStage_Data_03;
|
||
//pSkillFX->nStage_Data_04;
|
||
//pSkillFX->nStage_Data_05;//시전(타격)연출 보조FX(2) ID
|
||
//pSkillFX->nStage_Data_06;//시전(타격)연출 보조FX(2) 위치
|
||
}
|
||
|
||
SWorkWeaponSwing_ContinuousHits::~SWorkWeaponSwing_ContinuousHits()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( m_pTarget )
|
||
{
|
||
while(m_nHitCnt > 0)
|
||
_processDamage();
|
||
}
|
||
}
|
||
}
|
||
|
||
//Snewskill에서 처리 하지 말고 여기서 처리한다 ( 추가될수 있으이 )
|
||
bool SWorkWeaponSwing_ContinuousHits::ProcessingDamage()
|
||
{
|
||
if( m_nHitCnt > 0 || GetSkillMode() != SKILLMODE_FIRE )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkWeaponSwing_ContinuousHits::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_dwTime = dwTime;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
_processView();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
_processDefCast( dwTime );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
if( m_nFireMotionID != 0 )
|
||
{
|
||
m_pOwner->NPlayAnimation( m_nFireMotionID, SEQTYPE_NORMAL, m_fPlayRate * 4.8f );
|
||
_addFX( m_pSkillFX->nStage_Type_Id );
|
||
|
||
_getEventSet();
|
||
SetStep( STEP_01 );
|
||
}
|
||
else
|
||
SetStep( STEP_02 );
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() )
|
||
{
|
||
SetStep( STEP_02 );
|
||
}
|
||
else if( m_pOwner->GetCurrAnimationID() != m_nFireMotionID )
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->NPlayAnimation( m_nFireMotionID, SEQTYPE_NORMAL, m_fPlayRate * 4.8f );
|
||
m_pOwner->SetAniLock( true );
|
||
|
||
_getEventSet();
|
||
}
|
||
else
|
||
{
|
||
SetStep( STEP_02 );
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
else if( GetStep() == STEP_02 )
|
||
{
|
||
m_pOwner->EndUseSkill( m_pSkillFX->nID );
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate );
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
|
||
void SWorkWeaponSwing_ContinuousHits::OnEventHit()
|
||
{
|
||
_processDamage();
|
||
}
|
||
void SWorkWeaponSwing_ContinuousHits::OnEventSwing()
|
||
{
|
||
|
||
}
|
||
void SWorkWeaponSwing_ContinuousHits::OnEventEtc()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkWeaponSwing_ContinuousHits::_processDamage()
|
||
{
|
||
//타겟 만큼 순차적으로 데미지 처리
|
||
for( unsigned char target_count = 0; target_count < m_pSkillEvent->fire.target_count; ++target_count )
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pDamage->skillresult = m_pSkillEvent->vSkillResult[m_nCount - m_nHitCnt];
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_pDamage->skillresult.GetTargetHandle() );
|
||
if( pTarget )
|
||
{
|
||
int nBlock = 0;
|
||
int nCritical = 0;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_CRITICAL) nCritical = 1;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_BLOCK) nBlock = 1;
|
||
|
||
m_pOwner->OnDamage( m_pOwner->GetArID(), pTarget->GetArID(), m_pDamage );
|
||
|
||
if( (m_pDamage->skillresult.GetType() == SkillResult::DAMAGE || m_pDamage->skillresult.GetType() == SkillResult::MAGIC_DAMAGE)
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
pTarget->Damage();
|
||
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//std::string strScript;
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), pTarget->GetArID(), nCritical, nBlock );
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
|
||
if( m_pSkillFX->nSub_Fire_Fx_Set_Id != 0 )
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nSub_Fire_Fx_Set_Id, m_pSkillFX->nSub_Fire_Fx_Position );
|
||
if( m_pSkillFX->nHit_Fx_Set_Id != 0 )
|
||
_addEffect( pTarget->GetArID(), pTarget->GetArID(), pTarget->GetArID(), m_pSkillFX->nHit_Fx_Set_Id, m_pSkillFX->nHit_Fx_Set_Position_Id );
|
||
}
|
||
}
|
||
--m_nHitCnt;
|
||
}
|
||
}
|
||
}
|
||
|
||
//==============================================================================================
|
||
//스킬 연출 유형 123
|
||
SWorkWeaponSwing_Zeal::SWorkWeaponSwing_Zeal( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
// m_nLocalFireMotionID[0] = pSkillFX->fStage_Data[2];//시전(타격)모션1 ID
|
||
// m_nLocalFireMotionID[1] = pSkillFX->fStage_Data[3];//시전(타격)모션2 ID
|
||
// m_nLocalFireMotionID[2] = pSkillFX->fStage_Data[4];//시전(타격)모션3 ID
|
||
|
||
m_fPlayRate = pSkillFX->fStage_Data[1];//재생 배속
|
||
m_nCurMotionID = -1;
|
||
|
||
m_cMaxHitCount = (int)pSkillFX->fStage_Data[9];
|
||
|
||
if( m_cMaxHitCount <= 0 )
|
||
{
|
||
m_cMaxHitCount = 3;
|
||
}
|
||
|
||
m_pLocalFireMotionID = new int[m_cMaxHitCount];
|
||
for( unsigned char cMaxHitCount = 0; cMaxHitCount < m_cMaxHitCount; ++cMaxHitCount )
|
||
m_pLocalFireMotionID[cMaxHitCount] = pSkillFX->fStage_Data[2+cMaxHitCount]; //시전(타격)모션
|
||
}
|
||
|
||
SWorkWeaponSwing_Zeal::~SWorkWeaponSwing_Zeal()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( m_pTarget )
|
||
{
|
||
while(m_nHitCnt > 0)
|
||
_processDamage();
|
||
}
|
||
}
|
||
|
||
SAFE_DELETE_ARRAY( m_pLocalFireMotionID );
|
||
}
|
||
|
||
void SWorkWeaponSwing_Zeal::OnEventHit()
|
||
{
|
||
_processDamage();
|
||
}
|
||
|
||
bool SWorkWeaponSwing_Zeal::ProcessingDamage()
|
||
{
|
||
if( m_nHitCnt > 0 || GetSkillMode() != SKILLMODE_FIRE )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkWeaponSwing_Zeal::_processDamage()
|
||
{
|
||
for( unsigned char target_count = 0; target_count < m_pSkillEvent->fire.target_count; ++target_count )
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pDamage->skillresult = m_pSkillEvent->vSkillResult[m_nCount - m_nHitCnt];
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_pDamage->skillresult.GetTargetHandle() );
|
||
if( pTarget )
|
||
{
|
||
int nBlock = 0;
|
||
int nCritical = 0;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_CRITICAL) nCritical = 1;
|
||
if(m_pDamage->skillresult.damage.flag & TS_ATTACK_EVENT::FLAG_BLOCK) nBlock = 1;
|
||
|
||
m_pOwner->OnDamage( m_pOwner->GetArID(), pTarget->GetArID(), m_pDamage );
|
||
|
||
if( (m_pDamage->skillresult.GetType() == SkillResult::DAMAGE || m_pDamage->skillresult.GetType() == SkillResult::MAGIC_DAMAGE)
|
||
&& !(m_pDamage->skillresult.damage.flag & SkillResult::MISS) )
|
||
{
|
||
pTarget->Damage();
|
||
|
||
// Fraun performance tweak (TODO: return it back; testing purposes!)
|
||
//std::string strScript;
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), pTarget->GetArID(), nCritical, nBlock );
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
|
||
if( m_pSkillFX->nSub_Fire_Fx_Set_Id != 0 )
|
||
_addEffect( m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nSub_Fire_Fx_Set_Id, m_pSkillFX->nSub_Fire_Fx_Position );
|
||
if( m_pSkillFX->nHit_Fx_Set_Id != 0 )
|
||
_addEffect( pTarget->GetArID(), pTarget->GetArID(), pTarget->GetArID(), m_pSkillFX->nHit_Fx_Set_Id, m_pSkillFX->nHit_Fx_Set_Position_Id );
|
||
}
|
||
}
|
||
--m_nHitCnt;
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkWeaponSwing_Zeal::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_dwTime = dwTime;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
_processView();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
_processDefCast( dwTime );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
//1이면 랜덤 0이면 순차
|
||
if( m_pSkillFX->fStage_Data[0] > 0.0f)
|
||
m_nCurMotionID = rand() % m_cMaxHitCount;
|
||
else
|
||
{
|
||
++m_nCurMotionID;
|
||
|
||
if( m_nCurMotionID >= m_cMaxHitCount )
|
||
m_nCurMotionID = 0;
|
||
}
|
||
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->NPlayAnimation( m_pLocalFireMotionID[m_nCurMotionID], SEQTYPE_NORMAL, m_fPlayRate * 4.8f );
|
||
m_pOwner->SetAniLock( true );
|
||
|
||
_addFX( m_pSkillFX->nStage_Type_Id );
|
||
|
||
_getEventSet();
|
||
SetStep( STEP_01 );
|
||
}
|
||
else if( GetStep() == STEP_01 )
|
||
{
|
||
if( !m_pOwner->IsPlaying() )
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
//1이면 랜덤 0이면 순차
|
||
if( m_pSkillFX->fStage_Data[0] > 0.0f )
|
||
m_nCurMotionID = rand() % m_cMaxHitCount;
|
||
else
|
||
{
|
||
++m_nCurMotionID;
|
||
|
||
if( m_nCurMotionID >= m_cMaxHitCount )
|
||
m_nCurMotionID = 0;
|
||
}
|
||
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->NPlayAnimation( m_pLocalFireMotionID[m_nCurMotionID], SEQTYPE_NORMAL, m_fPlayRate * 4.8f );
|
||
m_pOwner->SetAniLock( true );
|
||
|
||
_getEventSet();
|
||
}
|
||
else
|
||
{
|
||
SetStep( STEP_02 );
|
||
return;
|
||
}
|
||
}
|
||
else if( !CurrentlyAnimationIsFire() ) //연타 관련 모션을 재생중이지 않다면 끝낸다
|
||
{
|
||
if( m_nHitCnt > 0 )
|
||
{
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->NPlayAnimation( m_pLocalFireMotionID[m_nCurMotionID], SEQTYPE_NORMAL, m_fPlayRate * 4.8f );
|
||
m_pOwner->SetAniLock( true );
|
||
|
||
_getEventSet();
|
||
}
|
||
else
|
||
{
|
||
SetStep( STEP_02 );
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
else if( GetStep() == STEP_02 )
|
||
{
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->EndUseSkill( m_pSkillFX->nID );
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate );
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
bool SWorkWeaponSwing_Zeal::CurrentlyAnimationIsFire()
|
||
{
|
||
int nCurrentAniID = m_pOwner->GetCurrAnimationID();
|
||
for( unsigned char cMaxHitCount = 0; cMaxHitCount < m_cMaxHitCount; ++cMaxHitCount )
|
||
{
|
||
if( nCurrentAniID == m_pLocalFireMotionID[cMaxHitCount] )
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkWeaponSwing_Leech::SWorkWeaponSwing_Leech( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//흡수체생성딜레이(초)
|
||
pSkillFX->fStage_Data[1];//흡수체FX ID
|
||
pSkillFX->fStage_Data[2];//흡수체FX 비행스타일 (0~2)
|
||
pSkillFX->fStage_Data[3];//추가발동(회복) FX ID
|
||
pSkillFX->fStage_Data[4];//추가발동(회복) FX 위치
|
||
}
|
||
|
||
SWorkWeaponSwing_Leech::~SWorkWeaponSwing_Leech()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkWeaponSwing_Leech::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
void SWorkWeaponSwing_Leech::OnEventHit()
|
||
{
|
||
_processDamage();
|
||
}
|
||
void SWorkWeaponSwing_Leech::OnEventSwing()
|
||
{
|
||
|
||
}
|
||
void SWorkWeaponSwing_Leech::OnEventEtc()
|
||
{
|
||
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkBowShoot::SWorkBowShoot( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//연타연출타입 (0,1)
|
||
pSkillFX->fStage_Data[1];//범위연출타입 (0,1)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체FX 비행속도 (-1,1~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
|
||
m_nEffectID[0] = -1;
|
||
m_nEffectID[1] = -1;
|
||
m_nEffectID[2] = -1;
|
||
|
||
struct _MOTION_FX_SET* m_pFxSet = NULL;
|
||
|
||
if( pSkillFX->nStage_Type_Id == SS_TYPE_201 )
|
||
{
|
||
m_pFxSet = GetMotionFxSetDB().GetFXSet( pSkillFX->fStage_Data[5] );
|
||
}
|
||
else if( pSkillFX->nStage_Type_Id == SS_TYPE_212 )
|
||
{
|
||
m_pFxSet = GetMotionFxSetDB().GetFXSet( pSkillFX->fStage_Data[6] );
|
||
}
|
||
|
||
// From ZONE source; dual crossbows
|
||
bool bIsCrossBow = false;
|
||
<<<<<<< HEAD
|
||
if (ItemBase::CLASS_CROSSBOW == pOwner->GetItemClass()) //Double Crossbow
|
||
=======
|
||
if (ItemBase::CLASS_CROSSBOW == pOwner->GetItemClass())
|
||
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
||
bIsCrossBow = true;
|
||
|
||
// AziaMafia Double Crossbow
|
||
//if (ItemBase::CLASS_CROSSBOW == pOwner->GetItemClass())
|
||
// (ItemBase::CLASS_CROSSBOW || ItemBase::CLASS_DOUBLE_CROSSBOW == pOwner->GetItemClass())
|
||
// bIsCrossBow = true;
|
||
|
||
if( m_pFxSet )
|
||
{
|
||
|
||
m_strFX_01 = GetResourceDB().GetEffectResourceName( m_pFxSet->graphic_effect_start_file_ID );
|
||
m_strFX_02 = GetResourceDB().GetEffectResourceName( m_pFxSet->graphic_effect_middle_file_ID );
|
||
m_strFX_03 = GetResourceDB().GetEffectResourceName( m_pFxSet->graphic_effect_end_file_ID );
|
||
|
||
if( bIsCrossBow )
|
||
{
|
||
<<<<<<< HEAD
|
||
//Double Crossbow
|
||
m_strFX_01 += "cba_";
|
||
m_strFX_02 += "cba_";
|
||
m_strFX_03 += "cba_";
|
||
=======
|
||
// AziaMafia Double Crossbow
|
||
//m_strFX_01 += "cba_";
|
||
//m_strFX_02 += "cba_";
|
||
//m_strFX_03 += "cba_";
|
||
|
||
m_strFX_01 += "cbt_";
|
||
m_strFX_02 += "cbt_";
|
||
m_strFX_03 += "cbt_";
|
||
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
||
|
||
}
|
||
else
|
||
{
|
||
m_strFX_01 += "bwa_";
|
||
m_strFX_02 += "bwa_";
|
||
m_strFX_03 += "bwa_";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( bIsCrossBow )
|
||
{
|
||
m_strFX_01 = "rcfx_cross_arrowattack_start_lv01_";
|
||
m_strFX_02 = "rcfx_cross_arrowattack_loop_lv01_";
|
||
m_strFX_03 = "rcfx_cross_arrowattack_end_lv01_";
|
||
}
|
||
else
|
||
{
|
||
m_strFX_01 = "rcfx_arrowattack_start_lv01_";
|
||
m_strFX_02 = "rcfx_arrowattack_loop_lv01_";
|
||
m_strFX_03 = "rcfx_arrowattack_end_lv01_";
|
||
|
||
/*m_strFX_01 = "rcfx_pillaroffirearrow_start_lv01_bwa_"; //Alucard Need test this if this from higher epic
|
||
m_strFX_02 = "rcfx_pillaroffirearrow_loop_lv01_bwa_";
|
||
m_strFX_03 = "rcfx_pillaroffirearrow_end_lv01_bwa_";*/
|
||
}
|
||
}
|
||
|
||
const char* szName = GetNX3Name( pOwner->GetRace(), pOwner->GetSex() );
|
||
m_strFX_01 += szName;
|
||
m_strFX_02 += szName;
|
||
m_strFX_03 += szName;
|
||
}
|
||
|
||
|
||
SWorkBowShoot::~SWorkBowShoot()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
if( m_nEffectID[0] != -1 ) m_pOwner->DelEffect( m_nEffectID[0] );
|
||
if( m_nEffectID[1] != -1 ) m_pOwner->DelEffect( m_nEffectID[1] );
|
||
// if( m_nEffectID[2] != -1 ) m_pOwner->DelEffect( m_nEffectID[2] );
|
||
}
|
||
}
|
||
|
||
bool SWorkBowShoot::ProcessingDamage()
|
||
{
|
||
if( GetSkillMode() != SKILLMODE_FIRE || GetStep() != STEP_01 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkBowShoot::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_dwTime = dwTime;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
_processView();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
_processDefCast( dwTime );
|
||
//우선 애니메이션 체크로 화살 이펙트를 출력하자
|
||
if( m_pOwner->GetCurrAnimationID() == ANI_BOW_ATTACK01_A && m_nEffectID[0] == -1)
|
||
m_nEffectID[0] = m_pOwner->AddEffect( &FX_DATA_EX( m_strFX_01.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true, SEQTYPE_NORMAL, m_fPlayRate*4.8f ) );
|
||
else if( m_pOwner->GetCurrAnimationID() == ANI_BOW_ATTACK01_B && m_nEffectID[1] == -1)
|
||
m_nEffectID[1] = m_pOwner->AddEffect( &FX_DATA_EX( m_strFX_02.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true, SEQTYPE_LOOP, m_fPlayRate*4.8f ) );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
//m_pOwner->AddAction( m_pSkillEvent );
|
||
if( m_nEffectID[2] == -1 )
|
||
m_nEffectID[2] = m_pOwner->AddEffect( &FX_DATA_EX( m_strFX_03.c_str(), 2, m_pOwner->GetArID(), m_pOwner->GetArID(), m_hTarget, EFFECT_POS_DAMAGE, true, SEQTYPE_NORMAL, m_fPlayRate*4.8f ) );
|
||
}
|
||
_processDefFire( dwTime );
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkBowShoot_Shove::SWorkBowShoot_Shove( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//연타연출타입 (0,1)
|
||
pSkillFX->fStage_Data[1];//범위연출타입 (0,1)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체FX 비행속도 (-1,1~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
pSkillFX->fStage_Data[5];//밀려나는속도 (1~9)
|
||
SetEnd( true );
|
||
}
|
||
|
||
SWorkBowShoot_Shove::~SWorkBowShoot_Shove()
|
||
{
|
||
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkBowShoot_Leech::SWorkBowShoot_Leech( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//연타연출타입 (0,1)
|
||
pSkillFX->fStage_Data[1];//범위연출타입 (0,1)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체FX 비행속도 (-1,1~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
pSkillFX->fStage_Data[5];//흡수체생성딜레이(초)
|
||
pSkillFX->fStage_Data[6];//흡수체FX 파일명
|
||
pSkillFX->fStage_Data[7];//흡수체FX 비행스타일 (0~2)
|
||
pSkillFX->fStage_Data[8];//추가발동(회복) FX ID
|
||
pSkillFX->fStage_Data[9];//추가발동(회복) FX 위치
|
||
SetEnd( true );
|
||
}
|
||
|
||
SWorkBowShoot_Leech::~SWorkBowShoot_Leech()
|
||
{
|
||
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkSelf::SWorkSelf( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
|
||
}
|
||
|
||
SWorkSelf::~SWorkSelf()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkSelf::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkMotion::SWorkMotion( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
|
||
}
|
||
|
||
SWorkMotion::~SWorkMotion()
|
||
{
|
||
|
||
}
|
||
|
||
bool SWorkMotion::ProcessingDamage()
|
||
{
|
||
if( GetSkillMode() != SKILLMODE_FIRE || GetStep() != STEP_01 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkMotion::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_dwTime = dwTime;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
_processView();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
_processDefCast( dwTime );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
if( m_pSkillEvent )
|
||
m_pOwner->AddAction( m_pSkillEvent );
|
||
}
|
||
_processDefFire( dwTime );
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkMotion_Leech::SWorkMotion_Leech( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//흡수체생성딜레이(초)
|
||
pSkillFX->fStage_Data[1];//흡수체FX ID
|
||
pSkillFX->fStage_Data[2];//흡수체FX 비행스타일 (0~2)
|
||
pSkillFX->fStage_Data[3];//추가발동(회복) FX ID
|
||
pSkillFX->fStage_Data[4];//추가발동(회복) FX 위치
|
||
}
|
||
|
||
SWorkMotion_Leech::~SWorkMotion_Leech()
|
||
{
|
||
|
||
}
|
||
|
||
bool SWorkMotion_Leech::ProcessingDamage()
|
||
{
|
||
if( GetSkillMode() != SKILLMODE_FIRE || GetStep() != STEP_01 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkMotion_Leech::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_dwTime = dwTime;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
_processView();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
_processDefCast( dwTime );
|
||
}
|
||
else if( GetSkillMode() == SKILLMODE_FIRE )
|
||
{
|
||
_processDefFire( dwTime );
|
||
if( GetStep() == STEP_00 )
|
||
{
|
||
m_pOwner->AddAction( m_pSkillEvent );
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkMotion_SummonMotion_Leech::SWorkMotion_SummonMotion_Leech( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//흡수체생성딜레이(초)
|
||
pSkillFX->fStage_Data[1];//흡수체FX ID
|
||
pSkillFX->fStage_Data[2];//흡수체FX 비행스타일 (0~2)
|
||
pSkillFX->fStage_Data[3];//추가발동(회복) FX ID
|
||
pSkillFX->fStage_Data[4];//추가발동(회복) FX 위치
|
||
}
|
||
|
||
SWorkMotion_SummonMotion_Leech::~SWorkMotion_SummonMotion_Leech()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkMotion_SummonMotion_Leech::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkMotion_FXMotion::SWorkMotion_FXMotion( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//발동형 발사체FX ID
|
||
pSkillFX->fStage_Data[1];//발동형 발사체FX 위치
|
||
pSkillFX->fStage_Data[2];//발동형 발사체 FX 방향 랜덤처리 (0:한방향 1:랜덤방향)
|
||
pSkillFX->fStage_Data[3];//연사간격(초)
|
||
pSkillFX->fStage_Data[4];//힛트타이밍(초)
|
||
}
|
||
|
||
SWorkMotion_FXMotion::~SWorkMotion_FXMotion()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkMotion_FXMotion::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkMotion_FXMotionMultiple::SWorkMotion_FXMotionMultiple( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//발동형 발사체FX ID
|
||
pSkillFX->fStage_Data[1];//발동형 발사체FX 위치
|
||
pSkillFX->fStage_Data[2];//발동형 발사체 FX 방향 랜덤처리 (0:한방향 1:랜덤방향)
|
||
pSkillFX->fStage_Data[3];//연사간격(초)
|
||
pSkillFX->fStage_Data[4];//힛트타이밍(초)
|
||
}
|
||
|
||
SWorkMotion_FXMotionMultiple::~SWorkMotion_FXMotionMultiple()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkMotion_FXMotionMultiple::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkShoot_FXShoot::SWorkShoot_FXShoot( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[1];//슈팅형 발사체 비행 타입 (0~)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체 비행속도 (1~9)
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체 비행 가속 (0~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
}
|
||
|
||
SWorkShoot_FXShoot::~SWorkShoot_FXShoot()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkShoot_FXShoot::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkShoot_FXShootMultiple::SWorkShoot_FXShootMultiple( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[1];//슈팅형 발사체 비행 타입 (0~)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체 비행속도 (1~9)
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체 비행 가속 (0~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
}
|
||
|
||
SWorkShoot_FXShootMultiple::~SWorkShoot_FXShootMultiple()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkShoot_FXShootMultiple::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkShoot_FXShootPenetrate::SWorkShoot_FXShootPenetrate( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[1];//슈팅형 발사체 비행 타입 (0~)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체 비행속도 (1~9)
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체 비행 가속 (0~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
}
|
||
|
||
SWorkShoot_FXShootPenetrate::~SWorkShoot_FXShootPenetrate()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkShoot_FXShootPenetrate::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
/// 2011.03.23 - prodongi
|
||
//==============================================================================================
|
||
SWorkShoot_FXShootChain::SWorkShoot_FXShootChain( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//슈팅형 발사체FX ID
|
||
pSkillFX->fStage_Data[1];//슈팅형 발사체 비행 타입 (0~)
|
||
pSkillFX->fStage_Data[2];//슈팅형 발사체 비행속도 (1~9)
|
||
pSkillFX->fStage_Data[3];//슈팅형 발사체 비행 가속 (0~9)
|
||
pSkillFX->fStage_Data[4];//연사간격(초)
|
||
}
|
||
|
||
SWorkShoot_FXShootChain::~SWorkShoot_FXShootChain()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkShoot_FXShootChain::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkGround_FXContinue::SWorkGround_FXContinue( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
pSkillFX->fStage_Data[0];//지속발동체FX ID
|
||
}
|
||
|
||
SWorkGround_FXContinue::~SWorkGround_FXContinue()
|
||
{
|
||
|
||
}
|
||
|
||
void SWorkGround_FXContinue::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
SNewSkill::Process( dwTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
//==============================================================================================
|
||
|
||
//==============================================================================================
|
||
|
||
SWorkKnockBack::SWorkKnockBack( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX, const SkillResult* pSkillResult ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
m_pDamage = NULL;
|
||
m_hTarget = pSkillResult->damage_kb.hTarget;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
//타겟이 이동중일경우 정지명령을 내린다
|
||
m_pTarget->SetArObjectStop();
|
||
|
||
m_nFireMotionID = pSkillFX->fStage_Data[6];
|
||
|
||
m_nFxSubHitID = pSkillFX->nHit_Fx_Set_Id;
|
||
m_nFxSubFireID = pSkillFX->nSub_Fire_Fx_Set_Id;
|
||
|
||
m_dwAddHitDelayTime = pSkillFX->nSub_Hit_Fx_OutPut_Delay * 1000;
|
||
m_dwAddFireDelayTime = pSkillFX->nFire_Fx_OutPut_Delay * 1000;
|
||
|
||
m_nFxSubHitPos = pSkillFX->nHit_Fx_Set_Position_Id;
|
||
m_nFxSubFirePos = pSkillFX->nSub_Fire_Fx_Position;
|
||
|
||
m_vKnockBackPosition = K3DVector( pSkillResult->damage_kb.x, pSkillResult->damage_kb.y, 0.0f );
|
||
|
||
m_fKnockBackSpeed = pSkillResult->damage_kb.speed;
|
||
|
||
m_pDamage = new SMSG_DAMAGE;
|
||
m_pDamage->attacker_handle = pOwner->GetArID();
|
||
m_pDamage->target_handle = m_hTarget;
|
||
m_pDamage->nDamage = pSkillResult->damage_kb.damage;
|
||
m_pDamage->flag = pSkillResult->damage_kb.flag;
|
||
m_pDamage->nHittingAdd_FxID = pSkillFX->nSub_Stage_On_Hit_Id;
|
||
m_pDamage->skillresult = *pSkillResult;
|
||
m_pDamage->nSkillID = pSkillFX->nID; /// 2011.05.16 - prodongi
|
||
|
||
SetDamageDisplayName( m_pDamage, m_pTarget );
|
||
|
||
SetStep( STEP_00 );
|
||
}
|
||
|
||
SWorkKnockBack::~SWorkKnockBack()
|
||
{
|
||
SAFE_DELETE( m_pDamage );
|
||
}
|
||
|
||
bool SWorkKnockBack::ProcessingDamage()
|
||
{
|
||
if( GetStep() != STEP_02 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void SWorkKnockBack::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
// Fraun performance tweak
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
int nStep = GetStep();
|
||
switch (nStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
if (m_nFireMotionID != 0)
|
||
{
|
||
m_pOwner->NPlayAnimation(m_nFireMotionID);
|
||
_getEventSet();
|
||
}
|
||
|
||
if (m_pDamage)
|
||
{
|
||
m_pTarget->OnDamage(m_pOwner->GetArID(), m_hTarget, m_pDamage);
|
||
|
||
if (!(m_pDamage->flag & TS_ATTACK_EVENT::FLAG_MISS) && m_pDamage->nDamage > 0)
|
||
{
|
||
_addFX(m_pSkillFX->nStage_Type_Id);
|
||
|
||
if (m_pTarget->GetHP() > 0)
|
||
{
|
||
m_pTarget->SetAniLock(false);
|
||
m_pTarget->NPlayAnimation(ANI_DAMAGE01, SEQTYPE_LOOP);
|
||
}
|
||
|
||
m_pTarget->Damage();
|
||
|
||
|
||
// Removed FX in case of performance
|
||
//std::string strScript;
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), m_pTarget->GetArID(),
|
||
// ( m_pDamage->flag & TS_ATTACK_EVENT::FLAG_CRITICAL ),
|
||
// ( m_pDamage->flag & TS_ATTACK_EVENT::FLAG_BLOCK ) );
|
||
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
}
|
||
}
|
||
|
||
SetStep(STEP_01);
|
||
break;
|
||
}
|
||
case STEP_01:
|
||
{
|
||
m_pTarget->SetKnockBack(m_vKnockBackPosition, m_fKnockBackSpeed);
|
||
SetStep(STEP_02);
|
||
break;
|
||
}
|
||
case STEP_02:
|
||
{
|
||
if (!m_pOwner->IsPlaying() || m_pOwner->GetCurrAnimationID() != m_nFireMotionID)
|
||
{
|
||
m_pOwner->Default();
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if( m_nFxSubHitID > 0 )
|
||
{
|
||
if( ( dwTime - m_dwStartTime ) > m_dwAddHitDelayTime )
|
||
{
|
||
_addEffect( m_pTarget->GetArID(),
|
||
m_nFxSubHitID,
|
||
m_nFxSubHitPos );
|
||
|
||
m_nFxSubHitID = -1;
|
||
}
|
||
}
|
||
if( m_nFxSubFireID > 0 )
|
||
{
|
||
if( ( dwTime - m_dwStartTime ) > m_dwAddFireDelayTime )
|
||
{
|
||
_addEffect( m_pTarget->GetArID(),
|
||
m_nFxSubFireID,
|
||
m_nFxSubFirePos );
|
||
|
||
m_nFxSubFireID = -1;
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
//==============================================================================================
|
||
SWorkRush_Shove::SWorkRush_Shove( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX, const struct SStateInfo * pStateInfo ) : SGameWork( pOwner )
|
||
{
|
||
m_nFireMotionID = pSkillFX->fStage_Data[0]; //돌진모션 ID
|
||
m_fPlayRate = pSkillFX->fStage_Data[1] * 4.8f;//모션속도변화 (1=100%, 클수록 빨라짐)
|
||
|
||
m_pOwner->SetViewVector( pStateInfo->vTargetPos );
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->Rush( m_nFireMotionID, m_fPlayRate );
|
||
|
||
if( pSkillFX->fStage_Data[2] != 0 )
|
||
{
|
||
FX_DATA fx_data;
|
||
fx_data.owner = m_pOwner->GetArID();
|
||
fx_data.attack = m_pOwner->GetArID();
|
||
fx_data.target = m_pOwner->GetArID();
|
||
fx_data.nFX_ID = pSkillFX->fStage_Data[2];
|
||
fx_data.nEffPos = pSkillFX->fStage_Data[3];
|
||
m_pOwner->AddEffect( &fx_data );
|
||
}
|
||
|
||
m_pSkillFX = pSkillFX;
|
||
|
||
SetEnd( TRUE );
|
||
}
|
||
|
||
SWorkRush_Shove::~SWorkRush_Shove()
|
||
{
|
||
SAFE_DELETE( m_pSkillFX );
|
||
}
|
||
|
||
void SWorkRush_Shove::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
}
|
||
|
||
//==============================================================================================
|
||
//돌진공격
|
||
SChargeAttack::SChargeAttack( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX, const SkillResult* pSkillResult ) : SNewSkill( pOwner, pSkillFX )
|
||
{
|
||
m_pDamage = NULL;
|
||
m_hTarget = pSkillResult->damage.hTarget;
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
m_nFireMotionID = pSkillFX->fStage_Data[6];
|
||
|
||
m_nFxSubHitID = pSkillFX->nHit_Fx_Set_Id;
|
||
m_nFxSubFireID = pSkillFX->nSub_Fire_Fx_Set_Id;
|
||
|
||
m_dwAddHitDelayTime = pSkillFX->nSub_Hit_Fx_OutPut_Delay * 1000;
|
||
m_dwAddFireDelayTime = pSkillFX->nFire_Fx_OutPut_Delay * 1000;
|
||
|
||
m_nFxSubHitPos = pSkillFX->nHit_Fx_Set_Position_Id;
|
||
m_nFxSubFirePos = pSkillFX->nSub_Fire_Fx_Position;
|
||
|
||
m_pDamage = new SMSG_DAMAGE;
|
||
m_pDamage->attacker_handle = pOwner->GetArID();
|
||
m_pDamage->target_handle = m_hTarget;
|
||
m_pDamage->nDamage = pSkillResult->damage.damage;
|
||
m_pDamage->flag = pSkillResult->damage.flag;
|
||
m_pDamage->nHittingAdd_FxID = pSkillFX->nSub_Stage_On_Hit_Id;
|
||
m_pDamage->skillresult = *pSkillResult;
|
||
|
||
SetDamageDisplayName( m_pDamage, m_pTarget );
|
||
|
||
SetStep( STEP_00 );
|
||
}
|
||
|
||
SChargeAttack::~SChargeAttack()
|
||
{
|
||
SAFE_DELETE( m_pDamage );
|
||
}
|
||
|
||
void SChargeAttack::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
// Fraun performance tweak
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
SetEnd( TRUE );
|
||
return;
|
||
}
|
||
|
||
int nStep = GetStep();
|
||
switch (nStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
if (m_nFireMotionID != 0)
|
||
{
|
||
m_pOwner->NPlayAnimation(m_nFireMotionID);
|
||
_getEventSet();
|
||
}
|
||
|
||
if (m_pDamage)
|
||
{
|
||
m_pTarget->OnDamage(m_pOwner->GetArID(), m_hTarget, m_pDamage);
|
||
|
||
if (!(m_pDamage->flag & TS_ATTACK_EVENT::FLAG_MISS) && m_pDamage->nDamage > 0)
|
||
{
|
||
_addFX(m_pSkillFX->nStage_Type_Id);
|
||
|
||
if (m_pTarget->GetHP() > 0)
|
||
{
|
||
m_pTarget->SetAniLock(false);
|
||
m_pTarget->NPlayAnimation(ANI_DAMAGE01, SEQTYPE_LOOP);
|
||
}
|
||
|
||
m_pTarget->Damage();
|
||
|
||
// Removed FX in case of performance
|
||
//std::string strScript;
|
||
//XStringUtil::Format( strScript, "%s( %u, %u, %d, %d )", "avatar_basic_hit", m_pOwner->GetArID(), m_pTarget->GetArID(),
|
||
// (m_pDamage->flag & TS_ATTACK_EVENT::FLAG_CRITICAL),
|
||
// (m_pDamage->flag & TS_ATTACK_EVENT::FLAG_BLOCK) );
|
||
//if( strScript.length() )
|
||
// LUA()->RunString( strScript.c_str() );
|
||
}
|
||
}
|
||
|
||
SetStep(STEP_01);
|
||
break;
|
||
}
|
||
case STEP_01:
|
||
{
|
||
if (!m_pOwner->IsPlaying() || m_pOwner->GetCurrAnimationID() != m_nFireMotionID)
|
||
{
|
||
m_pOwner->Default();
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if( m_nFxSubHitID > 0 )
|
||
{
|
||
if( ( dwTime - m_dwStartTime ) > m_dwAddHitDelayTime )
|
||
{
|
||
_addEffect( m_pTarget->GetArID(),
|
||
m_nFxSubHitID,
|
||
m_nFxSubHitPos );
|
||
|
||
m_nFxSubHitID = -1;
|
||
}
|
||
}
|
||
if( m_nFxSubFireID > 0 )
|
||
{
|
||
if( ( dwTime - m_dwStartTime ) > m_dwAddFireDelayTime )
|
||
{
|
||
_addEffect( m_pTarget->GetArID(),
|
||
m_nFxSubFireID,
|
||
m_nFxSubFirePos );
|
||
|
||
m_nFxSubFireID = -1;
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
}
|
||
|
||
bool SChargeAttack::ProcessingDamage()
|
||
{
|
||
if( GetStep() != STEP_01 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
//==============================================================================================
|
||
//타기
|
||
SWorkMount::SWorkMount( class SGameAvatarEx * pOwner, AR_HANDLE hTarger ) : SGameWork( pOwner )
|
||
, m_pCreature( NULL )
|
||
{
|
||
m_hCreatrue = hTarger;
|
||
m_dwOldTime = 0;
|
||
/// 2011.09.06 바로 탑승하도록 수정 - prodongi
|
||
//SetStep( STEP_00 );
|
||
SetStep( STEP_01 );
|
||
}
|
||
|
||
SWorkMount::~SWorkMount()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pCreature = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hCreatrue );
|
||
if( m_pCreature )
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( m_hCreatrue, EFFECT_POS_SADDLE, m_pCreature->GetCreatureMountType() ) );
|
||
m_pOwner->SetMountMode();
|
||
|
||
m_pCreature->SetMountMode();
|
||
}
|
||
else
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( m_hCreatrue, EFFECT_POS_SADDLE ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkMount::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
// Fraun performance tweak
|
||
if( m_dwOldTime == 0 ) m_dwOldTime = dwTime;
|
||
|
||
m_pCreature = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hCreatrue );
|
||
|
||
int nStep = GetStep();
|
||
switch (nStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
// If movement occurs with the mount motion in Step 0, immediately switch to Step 1 (this can happen to other players)
|
||
if (m_pOwner->IsMoving() && (m_pOwner->CurrentlyAnimationIsMWalk() || m_pOwner->CurrentlyAnimationIsMRun())) // sonador #2.1.6
|
||
{
|
||
SetStep(STEP_01);
|
||
return;
|
||
}
|
||
|
||
// If movement to the position sent by the server has finished…
|
||
if (!m_pOwner->IsMoving())
|
||
{
|
||
m_pOwner->SetMotionBlend(false);
|
||
m_pOwner->SetIng(true);
|
||
|
||
if (m_pCreature)
|
||
{
|
||
int nAniType;
|
||
|
||
switch (m_pCreature->GetCreatureMountType())
|
||
{
|
||
case SGameAvatarEx::RIDE_HIGH_TYPE:
|
||
nAniType = ANI_M_MOUNT_HIGH;
|
||
break;
|
||
case SGameAvatarEx::RIDE_LOW_TYPE:
|
||
nAniType = ANI_M_MOUNT_LOW;
|
||
break;
|
||
case SGameAvatarEx::RIDE_WHITE_TYPE:
|
||
nAniType = ANI_M_MOUNT01_WHITE;
|
||
break;
|
||
case SGameAvatarEx::RIDE_UNICORN_TYPE:
|
||
nAniType = ANI_M_MOUNT01_UNICORN;
|
||
break;
|
||
default:
|
||
nAniType = ANI_M_MOUNT_HIGH;
|
||
break;
|
||
}
|
||
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->NPlayAnimation(nAniType);
|
||
m_pOwner->SetAniLock(true);
|
||
|
||
// Rotate the creature to face the player
|
||
m_pCreature->SetViewVectorForMount(m_pOwner->GetViewVector());
|
||
|
||
m_pCreature->SetIng(true);
|
||
|
||
m_pCreature->SetAniLock(false);
|
||
m_pCreature->NPlayAnimation(nAniType);
|
||
m_pCreature->SetAniLock(true);
|
||
}
|
||
SetStep(STEP_01);
|
||
}
|
||
break;
|
||
}
|
||
case STEP_01:
|
||
{
|
||
// Has the mounting animation finished?
|
||
// If movement occurs before the mounting animation finishes, link immediately
|
||
// (this can happen for other players as well)
|
||
// If the mounting animation differs from the currently playing animation, link immediately
|
||
if (!m_pOwner->IsPlaying() || m_pOwner->IsMoving() || !m_pOwner->CurrentlyAnimationIsMount())
|
||
{
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock(false);
|
||
|
||
if (m_pCreature)
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo(&SGameAvatarEx::RiderCreatureInfo(m_hCreatrue, EFFECT_POS_SADDLE, m_pCreature->GetCreatureMountType()));
|
||
|
||
// 2011.09.06 Modified to mount immediately – prodongi
|
||
m_pOwner->SetMotionBlend(false);
|
||
|
||
if (m_pOwner->IsMoving()) m_pOwner->NPlayAnimation( m_pOwner->GetPlayerMRunAniID(), SEQTYPE_LOOP );
|
||
else m_pOwner->NPlayAnimation( m_pOwner->GetPlayerMDefAniID(), SEQTYPE_LOOP );
|
||
|
||
m_pCreature->SetIng(false);
|
||
m_pCreature->SetAniLock(false);
|
||
m_pCreature->StandingDegree();
|
||
m_pCreature->SetViewVectorForMount(m_pOwner->GetViewVector());
|
||
|
||
if (m_pCreature->IsMoving()) m_pCreature->NPlayAnimation( ANI_RUN, SEQTYPE_LOOP );
|
||
else m_pCreature->NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
||
|
||
// 2011.09.06 Play mount effect – prodongi
|
||
// Normally, the effect ID should be obtained from the riding persistent effect,
|
||
// but since mount-type creatures don’t have related persistent effects, it is hardcoded.
|
||
FX_DATA fxdata;
|
||
fxdata.nFX_ID = 18015;
|
||
fxdata.nEffPos = EFFECT_POS_BOTTOM;
|
||
fxdata.owner = m_pOwner->GetArID();
|
||
fxdata.attack = m_pOwner->GetArID();
|
||
fxdata.target = m_pOwner->GetArID();
|
||
fxdata.fPlayRate = 4.8f;
|
||
fxdata.nPlayID = 0;//한번
|
||
fxdata.nMode = 0;//기본
|
||
|
||
m_pOwner->AddEffect(&fxdata);
|
||
}
|
||
|
||
SetStep(STEP_02);
|
||
}
|
||
break;
|
||
}
|
||
case STEP_02:
|
||
{
|
||
// 2011.09.06 Modified so that mounting happens immediately – prodongi
|
||
SetEnd(TRUE);
|
||
return;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// If 10 seconds have passed and it’s still in Step 0, immediately link and finish it
|
||
if( dwTime - m_dwOldTime > 10000 && nStep == STEP_00 )
|
||
{
|
||
m_pOwner->SetIng( false );
|
||
m_pOwner->SetAniLock( false );
|
||
|
||
if( m_pCreature )
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( m_hCreatrue, EFFECT_POS_SADDLE, m_pCreature->GetCreatureMountType() ) );
|
||
|
||
m_pCreature->SetIng( false );
|
||
m_pCreature->SetAniLock( false );
|
||
m_pCreature->StandingDegree();
|
||
|
||
if( m_pOwner->IsMoving() ) m_pOwner->NPlayAnimation( m_pOwner->GetPlayerMRunAniID(), SEQTYPE_LOOP );
|
||
else m_pOwner->NPlayAnimation( m_pOwner->GetPlayerMDefAniID(), SEQTYPE_LOOP );
|
||
|
||
if( m_pCreature->IsMoving() ) m_pCreature->NPlayAnimation( ANI_RUN, SEQTYPE_LOOP );
|
||
else m_pCreature->NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
||
}
|
||
|
||
SetStep( STEP_02 );
|
||
}
|
||
}
|
||
|
||
//==============================================================================================
|
||
// Dismount
|
||
SWorkUnMount::SWorkUnMount( class SGameAvatarEx * pOwner, AR_HANDLE hTarger, char Flag ) : SGameWork( pOwner )
|
||
, m_pCreature( NULL )
|
||
{
|
||
m_hCreatrue = hTarger;
|
||
m_Flag = Flag;
|
||
m_dwOldTime = 0;
|
||
SetStep( STEP_01 );
|
||
}
|
||
|
||
SWorkUnMount::~SWorkUnMount()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo();
|
||
m_pOwner->SetDefaultView();
|
||
m_pOwner->SetNormalMode();
|
||
|
||
m_pCreature = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hCreatrue );
|
||
if( m_pCreature )
|
||
{
|
||
m_pCreature->SetNormalMode();
|
||
}
|
||
}
|
||
}
|
||
|
||
void SWorkUnMount::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
// Fraun performance tweak
|
||
if( m_dwOldTime == 0 ) m_dwOldTime = dwTime;
|
||
|
||
m_pCreature = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hCreatrue );
|
||
int nStep = GetStep();
|
||
switch (nStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
// When the character falls off the creature or SP reaches 0 and the creature is summoned
|
||
switch (m_Flag)
|
||
{
|
||
case TS_SC_UNMOUNT_SUMMON::FALL:
|
||
case TS_SC_UNMOUNT_SUMMON::UNSUMMON:
|
||
{
|
||
m_pOwner->NPlayAnimation(ANI_DEFAULT01, SEQTYPE_LOOP); // t needs to be changed to a stun motion
|
||
|
||
// Unlink
|
||
m_pOwner->SetRiderCreatureInfo();
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetMotionBlend(true);
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->UnMountFallUnSummon();
|
||
|
||
if (m_pCreature)
|
||
{
|
||
m_pCreature->SetIng(false);
|
||
m_pCreature->SetAniLock(false);
|
||
m_pCreature->Default();
|
||
m_pCreature->SetBestPosition(); // Moving the creature
|
||
m_pCreature->UnMountFallUnSummon();
|
||
}
|
||
|
||
SetEnd(TRUE);
|
||
|
||
break;
|
||
}
|
||
case TS_SC_UNMOUNT_SUMMON::NORMAL:
|
||
{
|
||
if (!m_pOwner->IsMoving()) // The animation must play while in a standing state
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo(); // Unlink
|
||
m_pOwner->SetIng(true); // It is in the process of descending
|
||
m_pOwner->SetMotionBlend(false); // Disable motion interpolation
|
||
|
||
if (m_pCreature)
|
||
{
|
||
int nAniType;
|
||
|
||
switch (m_pCreature->GetCreatureMountType())
|
||
{
|
||
case SGameAvatarEx::RIDE_HIGH_TYPE:
|
||
nAniType = ANI_M_UNMOUNT_HIGH;
|
||
break;
|
||
case SGameAvatarEx::RIDE_LOW_TYPE:
|
||
nAniType = ANI_M_UNMOUNT_LOW;
|
||
break;
|
||
case SGameAvatarEx::RIDE_WHITE_TYPE:
|
||
nAniType = ANI_M_UNMOUNT01_WHITE;
|
||
break;
|
||
case SGameAvatarEx::RIDE_UNICORN_TYPE:
|
||
nAniType = ANI_M_UNMOUNT01_UNICORN;
|
||
break;
|
||
default:
|
||
nAniType = ANI_M_UNMOUNT_HIGH;
|
||
break;
|
||
}
|
||
|
||
m_pCreature->SetIng(true);
|
||
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->NPlayAnimation(nAniType);
|
||
m_pOwner->SetAniLock(true);
|
||
|
||
m_pCreature->SetAniLock(false);
|
||
m_pCreature->NPlayAnimation(nAniType);
|
||
m_pCreature->SetAniLock(true);
|
||
}
|
||
|
||
SetStep(STEP_01);
|
||
}
|
||
else
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo();
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetAniLock(false);
|
||
m_pOwner->Default();
|
||
|
||
if (m_pCreature)
|
||
{
|
||
m_pCreature->SetIng(false);
|
||
m_pCreature->SetAniLock(false);
|
||
m_pCreature->SetBestPosition(); //Moving the creature
|
||
m_pCreature->Default();
|
||
}
|
||
|
||
SetEnd(TRUE); // If moving, immediately disconnect the link (it must not descend while moving).
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case STEP_01:
|
||
{
|
||
// If the descending motion has finished
|
||
// If movement occurred even though the descending animation hasn’t finished, switch to the default animation
|
||
// (other players might see the character standing up)
|
||
// If the descending animation and the currently playing animation are different, switch to the default animation
|
||
|
||
m_pOwner->SetIng(false);
|
||
m_pOwner->SetMotionBlend(true);
|
||
m_pOwner->SetAniLock(false);
|
||
|
||
if (m_pOwner->IsMoving()) m_pOwner->Run();
|
||
else m_pOwner->Default();
|
||
|
||
if (m_pCreature)
|
||
{
|
||
m_pCreature->SetIng(false);
|
||
m_pCreature->SetAniLock(false);
|
||
|
||
if (m_pCreature->IsMoving()) m_pCreature->Run();
|
||
else m_pCreature->Default();
|
||
|
||
m_pCreature->SetBestPosition(); // Moving the creature
|
||
|
||
/// 2011.09.06 탑승 이펙트 출력 - prodongi
|
||
/// 원래는 이펙트 id를 라이딩 지속효과에서 갖고 와야 되나, 탑승형 크리처는 관련된 지속효과가 없기 때문에, 하드코딩으로 해줌
|
||
FX_DATA fxdata;
|
||
fxdata.nFX_ID = 18015;
|
||
fxdata.nEffPos = EFFECT_POS_BOTTOM;
|
||
fxdata.owner = m_pOwner->GetArID();
|
||
fxdata.attack = m_pOwner->GetArID();
|
||
fxdata.target = m_pOwner->GetArID();
|
||
fxdata.fPlayRate = 4.8f;
|
||
fxdata.nPlayID = 0; // Once
|
||
fxdata.nMode = 0; // Default
|
||
|
||
m_pOwner->AddEffect(&fxdata);
|
||
}
|
||
|
||
SetEnd(TRUE);
|
||
}
|
||
}
|
||
|
||
|
||
// If 10 seconds have passed and it’s still stuck at step 0, immediately switch to step 1
|
||
if( dwTime - m_dwOldTime > 10000 && nStep == STEP_00 )
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo();
|
||
m_pOwner->SetIng( false );
|
||
m_pOwner->SetAniLock( false );
|
||
m_pOwner->Default();
|
||
|
||
if( m_pCreature )
|
||
{
|
||
m_pCreature->SetIng( false );
|
||
m_pCreature->SetAniLock( false );
|
||
m_pCreature->SetBestPosition();
|
||
m_pCreature->Default();
|
||
}
|
||
|
||
SetEnd( TRUE );
|
||
}
|
||
}
|
||
|
||
//==============================================================================================
|
||
//애니 없이 타기
|
||
SWorkMountWithOutAnimation::SWorkMountWithOutAnimation( class SGameAvatarEx * pOwner, AR_HANDLE hTarger, int nFXID, int nFXPos ) : SGameWork( pOwner )
|
||
, m_hCreatrue( hTarger )
|
||
, m_nFXID( nFXID )
|
||
, m_nFXPos( nFXPos )
|
||
, m_pCreature( NULL )
|
||
{
|
||
SetStep( STEP_00 );
|
||
}
|
||
|
||
SWorkMountWithOutAnimation::~SWorkMountWithOutAnimation()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pOwner->SetMotionBlend( true );
|
||
|
||
m_pCreature = (SGameAvatarEx*)m_pOwner->GetGameTransportCreatureObject( m_hCreatrue ); // sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
||
if( m_pCreature )
|
||
{
|
||
m_pOwner->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( m_hCreatrue, EFFECT_POS_SADDLE, m_pCreature->GetCreatureMountType(), true ) );
|
||
m_pOwner->SetMountMode();
|
||
|
||
m_pCreature->SetVisibility( 1.0f );
|
||
m_pCreature->SetMountMode();
|
||
}
|
||
else
|
||
m_pOwner->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( m_hCreatrue, EFFECT_POS_SADDLE, 2, true ) );
|
||
}
|
||
}
|
||
|
||
void SWorkMountWithOutAnimation::Process( DWORD dwTime )
|
||
{
|
||
if( IsEnd() ) return;
|
||
|
||
m_pCreature = (SGameAvatarEx*)m_pOwner->GetGameTransportCreatureObject( m_hCreatrue );
|
||
if( m_pCreature == NULL ) return;
|
||
|
||
int nStep = GetStep();
|
||
if( nStep == STEP_00 )
|
||
{
|
||
if( m_pCreature->IsInit() && m_pCreature->Activate() )
|
||
{
|
||
// sonador #2.1.6
|
||
m_pOwner->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( m_hCreatrue, EFFECT_POS_SADDLE, m_pCreature->GetCreatureMountType(), true ) );
|
||
|
||
int nRunAniType = m_pOwner->GetPlayerMRunAniID();
|
||
int nDefaultAniType = m_pOwner->GetPlayerMDefAniID();
|
||
|
||
m_pOwner->SetMotionBlend( false );
|
||
|
||
if( m_pOwner->IsMoving() ) m_pOwner->NPlayAnimation( nRunAniType, SEQTYPE_LOOP );
|
||
else m_pOwner->NPlayAnimation( nDefaultAniType, SEQTYPE_LOOP );
|
||
|
||
//크리처를 플레이어 방향으로 돌리자
|
||
m_pCreature->StandingDegree();
|
||
m_pCreature->SetViewVectorForMount( m_pOwner->GetViewVector() );
|
||
|
||
if( m_pOwner->IsMoving() ) m_pCreature->NPlayAnimation( ANI_RUN, SEQTYPE_LOOP );
|
||
else m_pCreature->NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
||
|
||
m_pCreature->SetViewVectorStateIdle( K3DVector( 0.0f, 0.0f, 0.0f ) );
|
||
m_pCreature->SetVisibility( 1.0f );
|
||
|
||
m_pOwner->SetMountMode();
|
||
m_pCreature->SetMountMode();
|
||
|
||
if( m_nFXID != 0 )
|
||
{
|
||
FX_DATA fxdata;
|
||
fxdata.nFX_ID = m_nFXID;
|
||
fxdata.nEffPos = m_nFXPos;
|
||
fxdata.owner = m_pOwner->GetArID();
|
||
fxdata.attack = m_pOwner->GetArID();
|
||
fxdata.target = m_pOwner->GetArID();
|
||
fxdata.fPlayRate = 4.8f;
|
||
fxdata.nPlayID = 0;//한번
|
||
fxdata.nMode = 0;//기본
|
||
|
||
m_pOwner->AddEffect( &fxdata );
|
||
}
|
||
|
||
SetEnd( TRUE );
|
||
}
|
||
}
|
||
}
|
||
|
||
//==============================================================================================
|
||
//애니 없이 내리기
|
||
SWorkUnMountWithOutAnimation::SWorkUnMountWithOutAnimation( class SGameAvatarEx * pOwner, AR_HANDLE hTarger, int nFXID, int nFXPos ) : SGameWork( pOwner )
|
||
, m_nFXID( nFXID )
|
||
, m_nFXPos( nFXPos )
|
||
, m_pCreature( NULL )
|
||
{
|
||
m_pOwner->SetMotionBlend( false );
|
||
|
||
m_pOwner->SetNormalMode();
|
||
m_pOwner->SetRiderCreatureInfo();
|
||
m_pOwner->SetDefaultView();
|
||
|
||
if( m_pOwner->IsMoving() )
|
||
m_pOwner->Run();
|
||
else
|
||
m_pOwner->Default();
|
||
|
||
FX_DATA fxdata;
|
||
fxdata.nFX_ID = m_nFXID;
|
||
fxdata.nEffPos = m_nFXPos;
|
||
fxdata.owner = m_pOwner->GetArID();
|
||
fxdata.attack = m_pOwner->GetArID();
|
||
fxdata.target = m_pOwner->GetArID();
|
||
fxdata.fPlayRate = 4.8f;
|
||
fxdata.nPlayID = 0;//한번
|
||
fxdata.nMode = 0;//기본
|
||
|
||
m_pOwner->AddEffect( &fxdata );
|
||
|
||
SetEnd( TRUE );
|
||
}
|
||
|
||
SWorkUnMountWithOutAnimation::~SWorkUnMountWithOutAnimation()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
m_pOwner->SetMotionBlend( true );
|
||
m_pOwner->SetNormalMode();
|
||
}
|
||
}
|
||
|
||
void SWorkUnMountWithOutAnimation::Process( DWORD dwTime )
|
||
{
|
||
/* if( IsEnd() == false )
|
||
{
|
||
m_pOwner->SetMotionBlend( true );
|
||
m_pOwner->SetNormalMode();
|
||
|
||
SetEnd( TRUE );
|
||
}*/
|
||
}
|
||
|
||
//==============================================================================================
|
||
//광역 공격
|
||
SWorkMultiAttack::SWorkMultiAttack( class SGameAvatarEx * pOwner ) : SGameWork( pOwner )
|
||
, m_vStartDir( K3DVector( 0.0f, 0.0f, 0.0f ) )
|
||
, m_dwOldTime( 0 )
|
||
, m_dwRotationTime( 300 )
|
||
, m_fCheckAngle( 0.95f )
|
||
{
|
||
m_fRangeAngle = K3D_PI*2.0f; //범위 각도
|
||
}
|
||
|
||
SWorkMultiAttack::~SWorkMultiAttack()
|
||
{
|
||
if( m_pOwner )
|
||
{
|
||
std::vector< TargetInfo >::iterator iter = m_vTargetInfo.begin();
|
||
for( ; iter != m_vTargetInfo.end(); ++iter )
|
||
{
|
||
//처리가 안된넘들 체크
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( (*iter).hTarget );
|
||
if( pTarget )
|
||
{
|
||
//데미지 처리
|
||
pTarget->NPlayAnimation( ANI_DAMAGE01 );
|
||
}
|
||
}
|
||
}
|
||
|
||
m_vTargetInfo.clear();
|
||
}
|
||
|
||
void SWorkMultiAttack::SetTargetList( std::vector< AR_HANDLE > & vTargetList )
|
||
{
|
||
std::vector< AR_HANDLE >::iterator iter = vTargetList.begin();
|
||
for( ; iter != vTargetList.end(); ++iter )
|
||
{
|
||
TargetInfo target( (*iter) );
|
||
m_vTargetInfo.push_back( target );
|
||
}
|
||
}
|
||
|
||
void SWorkMultiAttack::Process( DWORD dwTime )
|
||
{
|
||
if( m_dwOldTime == 0 ) m_dwOldTime = dwTime;
|
||
|
||
int nStep = GetStep();
|
||
if( nStep == STEP_00 )
|
||
{
|
||
K3DVector vView = m_pOwner->GetViewVector();
|
||
K3DVector vUp = K3DVector( 0.0f, 0.0f, 1.0f );
|
||
m_vStartDir = CrossProduct( vView, vUp );
|
||
|
||
//타겟 정리
|
||
std::vector< TargetInfo >::iterator iter = m_vTargetInfo.begin();
|
||
for( ; iter != m_vTargetInfo.end(); ++iter )
|
||
{
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( (*iter).hTarget );
|
||
if( pTarget )
|
||
{
|
||
K3DVector vTarget;
|
||
vTarget.x = pTarget->GetPosition()->x - m_pOwner->GetPosition()->x;
|
||
vTarget.y = pTarget->GetPosition()->y - m_pOwner->GetPosition()->y;
|
||
vTarget.z = 0.0f;
|
||
K3DVectorNormalize( vTarget, vTarget );
|
||
|
||
K3DVector vCross = CrossProduct( m_vStartDir, vTarget );
|
||
if( vCross.z >= 0.0f )
|
||
{
|
||
(*iter).bCheckDamage = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
m_pOwner->NPlayAnimation( ANI_ATTACK01 );
|
||
|
||
SetStep( STEP_01 );
|
||
}
|
||
else if( nStep == STEP_01 )
|
||
{
|
||
float fRotation = 0.0f;
|
||
if( (dwTime - m_dwOldTime) <= m_dwRotationTime )
|
||
{
|
||
float fGap = (float)(dwTime - m_dwOldTime) / m_dwRotationTime;
|
||
fRotation = m_fRangeAngle * fGap;
|
||
}
|
||
else
|
||
{
|
||
fRotation = m_fRangeAngle;
|
||
SetEnd( true );
|
||
}
|
||
|
||
K3DMatrix matResult, matRot, matTrans;
|
||
|
||
K3DMatrixRotationZ( matRot, fRotation );
|
||
K3DMatrixTranslation( matTrans, m_vStartDir.x, m_vStartDir.y, m_vStartDir.z );
|
||
K3DMatrixMultiply( matResult, matTrans, matRot );
|
||
|
||
K3DVector vOut( matResult._41, matResult._42, matResult._43 );
|
||
K3DVectorNormalize( vOut, vOut );
|
||
|
||
std::vector< TargetInfo >::iterator iter = m_vTargetInfo.begin();
|
||
for( ; iter != m_vTargetInfo.end(); )
|
||
{
|
||
SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( (*iter).hTarget );
|
||
if( pTarget )
|
||
{
|
||
K3DVector vTarget;
|
||
vTarget.x = pTarget->GetPosition()->x - m_pOwner->GetPosition()->x;
|
||
vTarget.y = pTarget->GetPosition()->y - m_pOwner->GetPosition()->y;
|
||
vTarget.z = 0.0f;
|
||
K3DVectorNormalize( vTarget, vTarget );
|
||
|
||
if( CheckCrash( vOut, vTarget ) )
|
||
{
|
||
//데미지 처리
|
||
pTarget->NPlayAnimation( ANI_DAMAGE01 );
|
||
iter = m_vTargetInfo.erase( iter );
|
||
}
|
||
else
|
||
{
|
||
K3DVector vCross = CrossProduct( vOut, vTarget );
|
||
if( (*iter).bCheckDamage )
|
||
{
|
||
if( vCross.z <= 0.0f )
|
||
{
|
||
//데미지 처리
|
||
pTarget->NPlayAnimation( ANI_DAMAGE01 );
|
||
iter = m_vTargetInfo.erase( iter );
|
||
continue;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( vCross.z >= 0.0f )
|
||
{
|
||
(*iter).bCheckDamage = true;
|
||
}
|
||
}
|
||
++iter;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
iter = m_vTargetInfo.erase( iter );
|
||
}
|
||
}
|
||
|
||
if( m_vTargetInfo.empty() )
|
||
SetEnd( true );
|
||
}
|
||
}
|
||
|
||
bool SWorkMultiAttack::CheckCrash( const K3DVector & vView, const K3DVector & vTarget )
|
||
{
|
||
float fDot = DotProduct( vView, vTarget );
|
||
if( fDot >= m_fCheckAngle )
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//==============================================================================================
|
||
//노동기술
|
||
SWorkingSkill::SWorkingSkill( class SGameAvatarEx * pOwner, _SKILL_FX* pSkillFX ) : SNewSkill( pOwner, pSkillFX )
|
||
, m_szSwapWeaponName( NULL )
|
||
, m_bHideWeapon( false )
|
||
{
|
||
_MOTION_FX_SET* pFxSet = GetMotionFxSetDB().GetFXSet( pSkillFX->fStage_Data[0] );
|
||
if( pFxSet )
|
||
{
|
||
m_szSwapWeaponName = GetResourceDB().GetEffectResourceName( pFxSet->graphic_effect_start_file_ID );
|
||
}
|
||
else
|
||
{
|
||
if( pSkillFX->fStage_Data[1] != 0 )
|
||
{
|
||
m_bHideWeapon = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
SWorkingSkill::~SWorkingSkill()
|
||
{
|
||
}
|
||
|
||
void SWorkingSkill::CastCancel()
|
||
{
|
||
ForceEnd();
|
||
|
||
if( GetSkillMode() == SKILLMODE_CAST )
|
||
{
|
||
HideNSwapWeapon();
|
||
}
|
||
}
|
||
|
||
bool SWorkingSkill::ProcessingDamage()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
void SWorkingSkill::Process( DWORD dwTime )
|
||
{
|
||
m_dwTime = dwTime;
|
||
|
||
if( IsEnd() ) return;
|
||
|
||
// Fraun performance tweak
|
||
|
||
m_pTarget = (SGameAvatarEx*)m_pOwner->GetGameObject( m_hTarget );
|
||
if( !m_pTarget )
|
||
{
|
||
HideNSwapWeapon();
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(true);
|
||
return;
|
||
}
|
||
|
||
int nSkillMode = GetSkillMode();
|
||
|
||
switch (nSkillMode)
|
||
{
|
||
case SKILLMODE_CAST:
|
||
{
|
||
int nStep = GetStep();
|
||
|
||
switch (nStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
if (m_bHideWeapon)
|
||
{
|
||
m_pOwner->HideWeapon(FALSE);
|
||
}
|
||
else
|
||
{
|
||
if (m_szSwapWeaponName != NULL)
|
||
{
|
||
m_pOwner->AddMeshPart(ANIPART_WEAPON_LEFT, MPART_L_WEAPON, "");
|
||
m_pOwner->AddMeshPart(ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, m_szSwapWeaponName);
|
||
}
|
||
}
|
||
|
||
_processDefCast(dwTime);
|
||
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case SKILLMODE_FIRE:
|
||
{
|
||
int nStep = GetStep();
|
||
|
||
switch (nStep)
|
||
{
|
||
case STEP_00:
|
||
{
|
||
if (m_nFireMotionID != 0)
|
||
{
|
||
bool bPlayNextAnimation = false;
|
||
int nAniType = m_pOwner->GetCurrentlyAniType();
|
||
if (nAniType == SEQTYPE_NORMAL ||
|
||
nAniType == SEQTYPE_LASTPAGE ||
|
||
nAniType == SEQTYPE_REVERSE)
|
||
{
|
||
if (!m_pOwner->IsPlaying())
|
||
bPlayNextAnimation = true;
|
||
}
|
||
else
|
||
{
|
||
if (m_pOwner->CurrentlyAnimationIsLoopWrap())
|
||
bPlayNextAnimation = true;
|
||
}
|
||
|
||
if (bPlayNextAnimation)
|
||
{
|
||
m_pOwner->NPlayAnimation(m_nFireMotionID);
|
||
//시전시 동반 되는 이펙트
|
||
if (m_pSkillFX->nFire_Fx_Set_Id != 0)
|
||
_addEffect(m_pOwner->GetArID(), m_pOwner->GetArID(), m_pOwner->GetArID(), m_pSkillFX->nFire_Fx_Set_Id, EFFECT_POS_BOTTOM, SEQTYPE_NORMAL);
|
||
|
||
_getEventSet();
|
||
|
||
SetStep(STEP_01);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SetStep(STEP_01);
|
||
}
|
||
break;
|
||
}
|
||
case STEP_01:
|
||
{
|
||
if (m_nFireMotionID != 0)
|
||
{
|
||
if (m_pOwner->GetCurrAnimationID() == m_nFireMotionID && !m_pOwner->IsPlaying())
|
||
{ //시전 연출 끝났음.
|
||
SetStep(STEP_02);
|
||
}
|
||
}
|
||
else if (m_nFireMotionID == 0)
|
||
{ //시전 모션 없음.
|
||
SetStep(STEP_02);
|
||
}
|
||
break;
|
||
}
|
||
case STEP_02:
|
||
{
|
||
HideNSwapWeapon();
|
||
|
||
m_pOwner->EndUseSkill(m_pSkillFX->nID);
|
||
m_pOwner->Default();
|
||
|
||
SetEnd(TRUE);
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
if (m_pOwner->IsUseSkill_complete())
|
||
{
|
||
if (m_nFireMotionID != 0 && m_pOwner->GetCurrAnimationID() != m_nFireMotionID)
|
||
{
|
||
HideNSwapWeapon();
|
||
|
||
SetEnd(TRUE);
|
||
return;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
DWORD eventTime = ((dwTime - m_dwStartTime) * m_fPlayRate);
|
||
_processEventSet( eventTime );
|
||
|
||
_processView();
|
||
}
|
||
|
||
void SWorkingSkill::HideNSwapWeapon()
|
||
{
|
||
if( m_bHideWeapon )
|
||
{
|
||
m_pOwner->HideWeapon( TRUE );
|
||
}
|
||
else if (m_szSwapWeaponName != NULL)
|
||
{
|
||
int nRace = m_pOwner->GetInnRace();
|
||
int nSex = m_pOwner->GetInnSex();
|
||
|
||
std::string strRightHand = GetItemDB().GetFileName(nRace, nSex, m_pOwner->GetItemCode(ItemBase::WEAR_WEAPON), m_pOwner->GetItemLevel(ItemBase::WEAR_WEAPON));
|
||
std::string strLeftHand = GetItemDB().GetFileName(nRace, nSex, m_pOwner->GetItemCode(ItemBase::WEAR_SHIELD), m_pOwner->GetItemLevel(ItemBase::WEAR_SHIELD));
|
||
|
||
strRightHand += ".nx3";
|
||
strLeftHand += ".nx3";
|
||
|
||
ItemBase::ItemClass nRItemClass = m_pOwner->GetItemClass(ItemBase::WEAR_WEAPON);
|
||
if (nRItemClass == ItemBase::CLASS_LIGHT_BOW || nRItemClass == ItemBase::CLASS_HEAVY_BOW)
|
||
{
|
||
m_pOwner->AddMeshPart(ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, "");
|
||
m_pOwner->AddMeshPart(ANIPART_WEAPON_LEFT, MPART_L_WEAPON, strRightHand.c_str());
|
||
}
|
||
<<<<<<< HEAD
|
||
else if (nRItemClass == ItemBase::CLASS_CROSSBOW) //Double Crossbow
|
||
=======
|
||
|
||
// AziaMafia Double Crossbow // From ZONE source; dual crossbows
|
||
else if (nRItemClass == ItemBase::CLASS_CROSSBOW)
|
||
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
||
{
|
||
m_pOwner->AddMeshPart(ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, strRightHand.c_str());
|
||
m_pOwner->AddMeshPart(ANIPART_WEAPON_LEFT, MPART_L_WEAPON, "");
|
||
}
|
||
else
|
||
{
|
||
m_pOwner->AddMeshPart( ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, strRightHand.c_str() );
|
||
|
||
ItemBase::ItemClass nLItemClass = m_pOwner->GetItemClass( ItemBase::WEAR_SHIELD );
|
||
if( nLItemClass == ItemBase::CLASS_ONEHAND_SWORD || nLItemClass == ItemBase::CLASS_DAGGER || nLItemClass == ItemBase::CLASS_ONEHAND_AXE) // From ZONE source; dual crossbows
|
||
//if( nLItemClass == ItemBase::CLASS_ONEHAND_SWORD || nLItemClass == ItemBase::CLASS_DAGGER || nLItemClass == ItemBase::CLASS_ONEHAND_AXE || nLItemClass == ItemBase::CLASS_CROSSBOW)
|
||
{
|
||
if( strLeftHand.length() > 5 )
|
||
strLeftHand.replace( strLeftHand.size() - 4, 1, "_L." );
|
||
}
|
||
|
||
m_pOwner->AddMeshPart( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, strLeftHand.c_str() );
|
||
}
|
||
|
||
m_pOwner->RefreshDeform();
|
||
}
|
||
} |