2572 lines
81 KiB
C++
2572 lines
81 KiB
C++
#include "stdafx.h"
|
|
#include ".\sgameplayer.h"
|
|
|
|
#include "GameDefine.h"
|
|
#include "KSeqAvatar.h"
|
|
#include "KSeqAvatarEx.h"
|
|
|
|
#include "KRenderObjectEtc.h"
|
|
|
|
#include "SStringDB.h"
|
|
#include "SItemDB.h"
|
|
#include "SGameWork.h"
|
|
#include "SGameMessage.h"
|
|
#include "SGameAniType.h"
|
|
#include "SSkillDB.h"
|
|
#include <toolkit/XStringUtil.h>
|
|
#include "SAvatarProperty.h"
|
|
#include "SAvatarStateMachine.h"
|
|
#include "SSkillStageType.h"
|
|
#include "SGameUtil.h"
|
|
|
|
#include "SGameCircleShadowFX.h"
|
|
#include "SGameForceSphereFX.h"
|
|
|
|
#include "SGameOption.h"
|
|
|
|
#include "SGameSystem.h" // 2011.11.04 - servantes
|
|
#include "SGameManager.h"
|
|
#include "SGame.h"
|
|
#include "SGameLocalCreature.h"
|
|
|
|
#include "SCreatureDB.h"
|
|
#include "SMonsterDB.h"
|
|
|
|
#include "SDebug_Util.h"
|
|
|
|
|
|
|
|
extern SGameSystem* g_pCurrentGameSystem; // 2011.11.04 - servantes
|
|
|
|
SGamePlayer* SGamePlayer::m_pLocalPlayer;
|
|
|
|
SGamePlayer::SGamePlayer( ENC_INT nContentID ) : SGameAvatarEx ( nContentID )
|
|
, m_nPrevAniType ( 0 )
|
|
, m_dwIdleTime ( 0 ) // sonador 1.8.13 아바타 IDLE 모션 동작 구현
|
|
{
|
|
memset( m_NudeItemCode, 0, sizeof(m_NudeItemCode) ); //아무것도 안 입었을때
|
|
memset( m_ItemCode , 0, sizeof(m_ItemCode) ); //장착시
|
|
memset( m_ItemLevel , 0, sizeof(m_ItemLevel) );
|
|
|
|
m_bIsUseSkill_complete = true;
|
|
|
|
m_idPrevState = SObjectState::STATE_NONE;
|
|
|
|
m_hCreatureMounthandle = 0;
|
|
|
|
m_nEnhanceCheatLevel = 0;
|
|
|
|
m_bWaitingAttackCancel = false;
|
|
|
|
SetRunNWalkAniSpeedDefault(); // sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
}
|
|
|
|
SGamePlayer::~SGamePlayer()
|
|
{
|
|
}
|
|
|
|
ANI_LIST_EX SGamePlayer::GetDefaultAnimation()
|
|
{
|
|
if( IsDead() ) return ANI_DEAD01; //죽었음
|
|
|
|
if( (GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN) ) return ANI_SIT;
|
|
|
|
return SGameAvatarEx::GetDefaultAnimation();
|
|
}
|
|
|
|
void SGamePlayer::SetItemCodeLevel( int nIndex, ItemBase::ItemCode code, int nLevel )
|
|
{
|
|
if( ItemBase::MAX_ITEM_WEAR > nIndex && nIndex > -1 )
|
|
{
|
|
m_ItemCode[nIndex] = code;
|
|
m_ItemLevel[nIndex] = nLevel;
|
|
}
|
|
}
|
|
|
|
ItemBase::ItemCode SGamePlayer::GetItemCode( int nIndex )
|
|
{
|
|
if( ItemBase::MAX_ITEM_WEAR > nIndex && nIndex > -1 )
|
|
return m_ItemCode[nIndex];
|
|
|
|
return -1;
|
|
}
|
|
|
|
int SGamePlayer::GetItemLevel( int nIndex )
|
|
{
|
|
if( ItemBase::MAX_ITEM_WEAR > nIndex && nIndex > -1 )
|
|
return m_ItemLevel[nIndex];
|
|
|
|
return -1;
|
|
}
|
|
|
|
ItemBase::ItemClass SGamePlayer::GetItemClass( int nIndex )
|
|
{
|
|
if( ItemBase::MAX_ITEM_WEAR > nIndex && nIndex > -1 )
|
|
return (ItemBase::ItemClass)m_itemClass[nIndex];
|
|
|
|
return ItemBase::CLASS_ETC;
|
|
}
|
|
|
|
void SGamePlayer::RefreshItemWearEx( class KSeqAvatarEx * pAvatarEx, std::vector< WEAR_DATA >& wearlist )
|
|
{
|
|
if( !pAvatarEx ) return;
|
|
|
|
if( wearlist.empty() ) return;
|
|
|
|
memset( m_itemClass, 0, sizeof( m_itemClass ) );
|
|
|
|
int nWearSize = (int)wearlist.size();
|
|
for( int i(0); nWearSize>i; ++i )
|
|
{
|
|
ItemWear( wearlist[i], pAvatarEx );
|
|
}
|
|
|
|
bool bAniLock = GetAniLock();
|
|
SetAniLock( false );
|
|
|
|
AttachAnimation( pAvatarEx );
|
|
|
|
SetAniLock( bAniLock );
|
|
}
|
|
|
|
//Item Wear Info
|
|
void SGamePlayer::RefreshItemWear( KSeqAvatarEx * pAvatarEx/* const char * pFileName, int nItemClass, int nWearType, int nItemLevel*/ )
|
|
{
|
|
// if( !IsActivated() )
|
|
// { //아직 로딩이 안된 상태
|
|
///* WEAR_DATA wear_data;
|
|
// wear_data.strFileName = pFileName;
|
|
// wear_data.nItemClass = nItemClass;
|
|
// wear_data.nWearType = nWearType;
|
|
// wear_data.nItemLevel = nItemLevel;*/
|
|
//
|
|
// m_vWearList.push_back( WearData );
|
|
// return;
|
|
// }
|
|
|
|
if( !pAvatarEx ) return;
|
|
|
|
if( m_vWearList.empty() ) return;
|
|
|
|
memset( m_itemClass, 0, sizeof( m_itemClass ) );
|
|
|
|
int nWearSize = (int)m_vWearList.size();
|
|
for( int i(0); nWearSize>i; ++i )
|
|
{
|
|
ItemWear( m_vWearList[i], pAvatarEx );
|
|
}
|
|
|
|
bool bAniLock = GetAniLock();
|
|
SetAniLock( false );
|
|
|
|
AttachAnimation( pAvatarEx );
|
|
|
|
SetAniLock( bAniLock );
|
|
}
|
|
|
|
void SGamePlayer::ItemWear( WEAR_DATA& WearData, class KSeqAvatarEx * pAvatarEx )
|
|
{
|
|
std::string strTexture = WearData.strTextureName;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
std::string strDecoTexture = WearData.strDecoTextureName;
|
|
|
|
m_itemClass[WearData.nWearType] = WearData.nItemClass;
|
|
|
|
ItemBase::ItemWearType nDecoWearType = ItemBase::WEAR_NONE;
|
|
switch( WearData.nWearType )
|
|
{
|
|
case ItemBase::WEAR_WEAPON: nDecoWearType = ItemBase::WEAR_DECO_WEAPON; break;
|
|
case ItemBase::WEAR_SHIELD: nDecoWearType = ItemBase::WEAR_DECO_SHIELD; break;
|
|
case ItemBase::WEAR_ARMOR: nDecoWearType = ItemBase::WEAR_DECO_ARMOR; break;
|
|
case ItemBase::WEAR_HELM: nDecoWearType = ItemBase::WEAR_DECO_HELM; break;
|
|
case ItemBase::WEAR_GLOVE: nDecoWearType = ItemBase::WEAR_DECO_GLOVE; break;
|
|
case ItemBase::WEAR_BOOTS: nDecoWearType = ItemBase::WEAR_DECO_BOOTS; break;
|
|
case ItemBase::WEAR_MANTLE: nDecoWearType = ItemBase::WEAR_DECO_MANTLE; break;
|
|
|
|
}
|
|
|
|
if( nDecoWearType != ItemBase::WEAR_NONE )
|
|
{
|
|
m_itemClass[nDecoWearType] = WearData.nDecoItemClass;
|
|
}
|
|
|
|
bool bAddDecoItem = WearData.bWithDecoItem;
|
|
if( bAddDecoItem )
|
|
{
|
|
//if( GetGameOption().GetAvatarDeco() == 0 ) // 2010.10.11. 게임플레이옵션에서 "꾸미기보이기" 제거.
|
|
//{
|
|
// bAddDecoItem = false;
|
|
//}
|
|
}
|
|
|
|
|
|
//Itemcode로 Ani 변경 지원 해야 한다.
|
|
switch( WearData.nItemClass )
|
|
{
|
|
case ItemBase::CLASS_ETCWEAPON : //= 100,// 기타무기
|
|
case ItemBase::CLASS_ONEHAND_SWORD : //= 101,// 한손검
|
|
m_nThreadAniClass = ANICLS_SWO;
|
|
break;
|
|
case ItemBase::CLASS_SHIELD :
|
|
if( m_itemClass[ItemBase::WEAR_RIGHTHAND] == 0 )// 오른손에 아무것도 없을때, 방패 착용시 한손검 모션
|
|
m_nThreadAniClass = ANICLS_SWO;
|
|
break;
|
|
case ItemBase::CLASS_DAGGER : //= 103,// 단검
|
|
m_nThreadAniClass = ANICLS_DGO;
|
|
break;
|
|
case ItemBase::CLASS_TWOHAND_SWORD : //= 102,// 양손검
|
|
m_nThreadAniClass = ANICLS_SWA;
|
|
break;
|
|
case ItemBase::CLASS_TWOHAND_SPEAR : m_nThreadAniClass = ANICLS_SPA;//= 104,// 창
|
|
break;
|
|
case ItemBase::CLASS_TWOHAND_AXE : m_nThreadAniClass = ANICLS_AXA;//= 105,// 도끼 => 나중에 리소스 추가 해야 함.
|
|
break;
|
|
case ItemBase::CLASS_ONEHAND_MACE : m_nThreadAniClass = ANICLS_MAO;//= 106,// 한손메이스
|
|
break;
|
|
case ItemBase::CLASS_TWOHAND_MACE : m_nThreadAniClass = ANICLS_MAA;//= 107,// 양손메이스
|
|
break;
|
|
case ItemBase::CLASS_LIGHT_BOW : //= 108,// 활
|
|
case ItemBase::CLASS_HEAVY_BOW : //= 109,// 활
|
|
m_nThreadAniClass = ANICLS_BWA;
|
|
break;
|
|
case ItemBase::CLASS_CROSSBOW : m_nThreadAniClass = ANICLS_CBO;//= 110,// 석궁
|
|
break;
|
|
|
|
<<<<<<< HEAD
|
|
=======
|
|
// AziaMafia Double Crossbow ANICLS_CBT
|
|
//case ItemBase::CLASS_DOUBLE_CROSSBOW : m_nThreadAniClass = ANICLS_CBO ;
|
|
// break;
|
|
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
case ItemBase::CLASS_ONEHAND_STAFF : m_nThreadAniClass = ANICLS_SWO;//ANICLS_SFO;//= 110,// 한손 지팡이 => 나중에 리소스 추가 해야 함.
|
|
break;
|
|
case ItemBase::CLASS_TWOHAND_STAFF : m_nThreadAniClass = ANICLS_SFA;//= 111,// 두손 지팡이 => 나중에 리소스 추가 해야 함.
|
|
break;
|
|
case ItemBase::CLASS_ONEHAND_AXE: m_nThreadAniClass = ANICLS_AXO; //113 한손 도끼
|
|
break;
|
|
}
|
|
|
|
switch( WearData.nWearType )
|
|
{
|
|
case ItemBase::WEAR_LEFTHAND :
|
|
{
|
|
m_bThreadUseLeftWeaponTrail = false;
|
|
|
|
if( WearData.nItemClass == ItemBase::CLASS_ONEHAND_SWORD )
|
|
{
|
|
m_nThreadAniClass = ANICLS_SWT; //장검 이도류 6
|
|
m_bThreadUseLeftWeaponTrail = true;
|
|
}
|
|
else if( WearData.nItemClass == ItemBase::CLASS_DAGGER )
|
|
{
|
|
m_nThreadAniClass = ANICLS_DGT; //단검 이도류 7
|
|
m_bThreadUseLeftWeaponTrail = true;
|
|
}
|
|
else if( WearData.nItemClass == ItemBase::CLASS_ONEHAND_AXE )
|
|
{
|
|
m_nThreadAniClass = ANICLS_AXT; //도끼 이도류
|
|
m_bThreadUseLeftWeaponTrail = true;
|
|
}
|
|
<<<<<<< HEAD
|
|
else if (WearData.nItemClass == ItemBase::CLASS_CROSSBOW) // Double Crossbow
|
|
=======
|
|
else if (WearData.nItemClass == ItemBase::CLASS_CROSSBOW) // ZONE Double cross bow 02.01.2021 // From ZONE source; dual crossbows
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
{
|
|
m_nThreadAniClass = ANICLS_CBT;
|
|
m_bThreadUseLeftWeaponTrail = true;
|
|
|
|
}
|
|
|
|
// AziaMafia Double Crossbow
|
|
//else if (WearData.nItemClass == ItemBase::CLASS_CROSSBOW)
|
|
//{
|
|
// m_nThreadAniClass = ANICLS_CBO; //µµ³¢ À̵µ·ù
|
|
// m_bThreadUseLeftWeaponTrail = true;
|
|
//}
|
|
|
|
// if( WearData.bIsDecoItem ) m_bThreadUseLeftWeaponTrail = false;
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_RIGHTHAND :
|
|
{
|
|
m_bThreadUseRightWeaponTrail = false;
|
|
|
|
if( WearData.nItemClass == 0 )
|
|
{
|
|
m_nThreadAniClass = ANICLS_UNA; //기본
|
|
}
|
|
else
|
|
{
|
|
//보우 계열 빼고, 검기 활성화
|
|
/*if( WearData.nItemClass != ItemBase::CLASS_LIGHT_BOW &&
|
|
WearData.nItemClass != ItemBase::CLASS_HEAVY_BOW &&
|
|
WearData.nItemClass != ItemBase::CLASS_CROSSBOW )*/
|
|
m_bThreadUseRightWeaponTrail = true;
|
|
}
|
|
|
|
// if( WearData.bIsDecoItem ) m_bThreadUseRightWeaponTrail = false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
bool bAddMesh = false;
|
|
|
|
//좀 복잡 하다. 단순화 시키자
|
|
//장착 시키자...외향 변경
|
|
switch( WearData.nWearType )
|
|
{
|
|
//Link 변경
|
|
case ItemBase::WEAR_LEFTHAND :
|
|
{
|
|
std::string strFile = WearData.strFileName.c_str();
|
|
assert( strFile.length() && "아이템 이름없음" );
|
|
|
|
std::string strDecoFile = WearData.strDecoFileName;
|
|
|
|
if( strFile.length() > 5 ) strFile.replace( strFile.size() - 4, 1, "_L." );
|
|
if( strDecoFile.length() > 5 ) strDecoFile.replace( strDecoFile.size() - 4, 1, "_L." );
|
|
|
|
_performance_print( "WEAR_LEFTHAND %s\n", strFile.c_str() );
|
|
|
|
if( WearData.nItemClass == ItemBase::CLASS_SHIELD )
|
|
{
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_SHIELD ) ) // 꾸미기방패.
|
|
{
|
|
if( WearData.bAttachDecoItem ) bAddMesh = true;
|
|
|
|
pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L_DECO, WearData.strDecoFileName.c_str() );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
{
|
|
pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L , WearData.strFileName.c_str(), strTexture ); //방패
|
|
}
|
|
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, "", strTexture ); //왼손에 장착 된거 사라지게
|
|
SetWeaponInfo( pAvatarEx, WearData, NULL );
|
|
}
|
|
<<<<<<< HEAD
|
|
else if (WearData.nItemClass == ItemBase::CLASS_ONEHAND_SWORD ||
|
|
WearData.nItemClass == ItemBase::CLASS_DAGGER ||
|
|
WearData.nItemClass == ItemBase::CLASS_ONEHAND_AXE ||
|
|
WearData.nItemClass == ItemBase::CLASS_CROSSBOW) //Double Crossbow
|
|
=======
|
|
else if( WearData.nItemClass == ItemBase::CLASS_ONEHAND_SWORD ||
|
|
WearData.nItemClass == ItemBase::CLASS_DAGGER ||
|
|
WearData.nItemClass == ItemBase::CLASS_ONEHAND_AXE ||
|
|
WearData.nItemClass == ItemBase::CLASS_CROSSBOW) // From ZONE source; dual crossbows
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
{ //이도류
|
|
pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L , "" ); //방패 사라지게
|
|
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_SHIELD ) ) // 꾸미기방패.
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
<<<<<<< HEAD
|
|
if (WearData.nItemClass == ItemBase::CLASS_CROSSBOW) //Double Crossbow
|
|
{
|
|
pAvatarEx->AddDecoMesh(ANIPART_WEAPON_LEFT, MDECOPART_L_WEAPON, WearData.strDecoFileName.c_str(), strDecoTexture);
|
|
}
|
|
else
|
|
{
|
|
pAvatarEx->AddDecoMesh(ANIPART_WEAPON_LEFT, MDECOPART_L_WEAPON, strDecoFile.c_str(), strDecoTexture);
|
|
|
|
}
|
|
=======
|
|
bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
if (WearData.nItemClass == ItemBase::CLASS_CROSSBOW)
|
|
{
|
|
pAvatarEx->AddDecoMesh(ANIPART_WEAPON_LEFT, MDECOPART_L_WEAPON, WearData.strDecoFileName.c_str(), strDecoTexture);
|
|
}
|
|
else
|
|
{
|
|
pAvatarEx->AddDecoMesh(ANIPART_WEAPON_LEFT, MDECOPART_L_WEAPON, strDecoFile.c_str(), strDecoTexture);
|
|
|
|
}
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if (bAddMesh)
|
|
{
|
|
if (WearData.nItemClass == ItemBase::CLASS_CROSSBOW)
|
|
{
|
|
pAvatarEx->AddMesh(ANIPART_WEAPON_LEFT, MPART_L_WEAPON, WearData.strFileName.c_str(), strTexture); //왼손에 장착 된거 사라지게
|
|
}
|
|
else
|
|
{
|
|
pAvatarEx->AddMesh(ANIPART_WEAPON_LEFT, MPART_L_WEAPON, strFile.c_str(), strTexture); //왼손에 장착 된거 사라지게
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<<<<<<< HEAD
|
|
if( m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_LIGHT_BOW &&
|
|
m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_HEAVY_BOW &&
|
|
m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_CROSSBOW ) //Double Crossbow
|
|
|
|
=======
|
|
//if( m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_LIGHT_BOW &&
|
|
// m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_HEAVY_BOW
|
|
//
|
|
// // AziaMafia Double Crossbow
|
|
// //&& m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_CROSSBOW
|
|
// )
|
|
|
|
// From ZONE source; dual crossbows
|
|
if (m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_LIGHT_BOW &&
|
|
m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_HEAVY_BOW &&
|
|
m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_CROSSBOW)
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
{
|
|
//삭제 하기 위함.
|
|
pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L , "" ); //방패
|
|
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_SHIELD ) ) // 꾸미기방패.
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_WEAPON_LEFT, MDECOPART_L_WEAPON, WearData.strDecoFileName.c_str(), strDecoTexture ); //그냥 왼손
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
{
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, WearData.strFileName.c_str(), strTexture ); //그냥 왼손
|
|
}
|
|
}
|
|
}
|
|
|
|
if( WearData.nItemClass == 0 )
|
|
{
|
|
if( m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_LIGHT_BOW &&
|
|
m_itemClass[ItemBase::WEAR_WEAPON] != ItemBase::CLASS_HEAVY_BOW )
|
|
SetWeaponInfo( pAvatarEx, WearData, NULL );
|
|
}
|
|
else
|
|
{
|
|
//방패가 아니라면 추가
|
|
if( WearData.nItemClass != ItemBase::CLASS_SHIELD && WearData.nItemClass != 265 )
|
|
{
|
|
std::string strEffectPosname = "wfx_";
|
|
strEffectPosname += strFile;
|
|
SetWeaponInfo( pAvatarEx, WearData, strEffectPosname.c_str() );
|
|
}
|
|
}
|
|
}
|
|
break; // Item Link 왼손전용 (방패라던가)
|
|
case ItemBase::WEAR_RIGHTHAND :
|
|
if( WearData.nItemClass == ItemBase::CLASS_LIGHT_BOW || WearData.nItemClass == ItemBase::CLASS_HEAVY_BOW )
|
|
{
|
|
pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L , "" ); //방패 사라지게 한다.
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, "" ); //오른손 사라지게 한다.
|
|
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_WEAPON ) ) // 꾸미기무기.
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_WEAPON_LEFT, MDECOPART_L_WEAPON, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
{
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, WearData.strFileName.c_str(), strTexture ); //왼손에 활 장착
|
|
}
|
|
|
|
|
|
//오른쪽 이펙트 사라지게 하기
|
|
WEAR_DATA tempwear = WearData;
|
|
tempwear.nItemCode = 0;
|
|
tempwear.nWearType = ItemBase::WEAR_RIGHTHAND;
|
|
SetWeaponInfo( pAvatarEx, tempwear, NULL );
|
|
}
|
|
else if( WearData.nItemClass == ItemBase::CLASS_CROSSBOW )
|
|
{
|
|
<<<<<<< HEAD
|
|
// Removed code that clears left-hand attachments to allow shield to remain equipped. //Double Crossbow
|
|
//pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L , "" ); //방패 사라지게 한다. // Remove shield from left hand.
|
|
//pAvatarEx->AddMesh( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, "" ); //왼손 사라지게 한다. // Clear left hand weapon.
|
|
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_WEAPON ) ) // 꾸미기무기. Decoration weapon hiding.
|
|
=======
|
|
// From ZONE source; dual crossbows
|
|
// Removed code that clears left-hand attachments to allow shield to remain equipped.
|
|
// pAvatarEx->AddAttachItem( ANIPART_BIPED, ATTACH_HAND_ARM2L , "" ); // Remove shield from left hand.
|
|
// pAvatarEx->AddMesh( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, "" ); // Clear left hand weapon.
|
|
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_WEAPON ) ) // Decoration weapon hiding.
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
bAddMesh = true;
|
|
|
|
pAvatarEx->AddDecoMesh( ANIPART_WEAPON_RIGHT, MDECOPART_R_WEAPON, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
{
|
|
<<<<<<< HEAD
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, WearData.strFileName.c_str(), strTexture ); //오른손에 활 장착 // Equip crossbow on right hand. //Double Crossbo
|
|
=======
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, WearData.strFileName.c_str(), strTexture ); // Equip crossbow on right hand.
|
|
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_WEAPON ) ) // 꾸미기무기.
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_WEAPON_RIGHT, MDECOPART_R_WEAPON, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
{
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_RIGHT, MPART_R_WEAPON, WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
}
|
|
|
|
if( WearData.nItemClass == 0 )
|
|
{
|
|
m_nThreadAniClass = ANICLS_UNA; //기본
|
|
SetWeaponInfo( pAvatarEx, WearData, NULL );
|
|
}
|
|
else
|
|
{
|
|
//방패가 아니라면 추가
|
|
if( WearData.nItemClass != ItemBase::CLASS_SHIELD )
|
|
{
|
|
if( WearData.nItemClass == ItemBase::CLASS_LIGHT_BOW || WearData.nItemClass == ItemBase::CLASS_HEAVY_BOW )
|
|
WearData.nWearType = ItemBase::WEAR_RIGHTHAND;
|
|
|
|
std::string strEffectPosname = "wfx_";
|
|
strEffectPosname += WearData.strFileName.c_str();
|
|
SetWeaponInfo( pAvatarEx, WearData, strEffectPosname.c_str() );
|
|
}
|
|
}
|
|
|
|
break; // Item Link 오른손전용
|
|
|
|
//Skin 변경
|
|
case ItemBase::WEAR_ARMOR :
|
|
{
|
|
std::string strTemp = WearData.strFileName.c_str();
|
|
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_ARMOR ) ) // 꾸미기의상.
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
bAddMesh = true;
|
|
|
|
// { sonador 1.8.1 액세서리 확장 표현 슬롯 추가
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_BIPED, MDECOPART_BODY, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
|
|
strTemp = WearData.strDecoFileName.c_str();
|
|
XStringUtil::Replace( strTemp, "body", "shortskirt" );
|
|
pAvatarEx->AddMesh( ANIPART_SHORTSKIRT , MDECOPART_S_SKIRT , strTemp.c_str() ); // 짧은 치마
|
|
strTemp = WearData.strDecoFileName.c_str();
|
|
XStringUtil::Replace( strTemp, "body", "middleskirt" );
|
|
pAvatarEx->AddMesh( ANIPART_MIDSKIRT , MDECOPART_M_SKIRT , strTemp.c_str() ); // 중 치마
|
|
strTemp = WearData.strDecoFileName.c_str();
|
|
XStringUtil::Replace( strTemp, "body", "long" );
|
|
pAvatarEx->AddMesh( ANIPART_LONGSKIRT , MDECOPART_L_SKIRT , strTemp.c_str() ); // 긴 치마
|
|
strTemp = WearData.strDecoFileName.c_str();
|
|
// }
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
{
|
|
//몸통과 일체형인데, 어떤 것이 올지 모르기 때문에, 모두 찾는다. 몸통과 치마류는 1:1 대응임.
|
|
pAvatarEx->AddMesh( ANIPART_BIPED , MPART_BODY , WearData.strFileName.c_str(), strTexture ); // 몸
|
|
|
|
XStringUtil::Replace( strTemp, "body", "shortskirt" );
|
|
pAvatarEx->AddMesh( ANIPART_SHORTSKIRT , MPART_S_SKIRT , strTemp.c_str(), strTexture ); // 짧은 치마
|
|
strTemp = WearData.strFileName.c_str();
|
|
XStringUtil::Replace( strTemp, "body", "fabric" );
|
|
pAvatarEx->AddMesh( ANIPART_FABRIC , MPART_FABRIC , strTemp.c_str(), strTexture ); // 앞가리개
|
|
strTemp = WearData.strFileName.c_str();
|
|
XStringUtil::Replace( strTemp, "body", "middleskirt" );
|
|
pAvatarEx->AddMesh( ANIPART_MIDSKIRT , MPART_M_SKIRT , strTemp.c_str(), strTexture ); // 중 치마
|
|
strTemp = WearData.strFileName.c_str();
|
|
XStringUtil::Replace( strTemp, "body", "long" );
|
|
pAvatarEx->AddMesh( ANIPART_LONGSKIRT , MPART_L_SKIRT , strTemp.c_str(), strTexture ); // 긴 치마
|
|
}
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_HELM : // 투구
|
|
{
|
|
// 2010.05.19 - prodongi
|
|
// 수정. 2010.10.08. 게임플레이설정 - 투구보이기 를 해제한 경우에 꾸미기투구가 안보이는 문제때문에 꾸미기투구 조건추가.
|
|
if (!isHideEquipInfo(ItemBase::HIDE_EQUIP_HELM) || isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_HELM ) )
|
|
//if( GetGameOption().Is
|
|
// Helm() ) //투구보이기 옵션에 따른 리소스 추가
|
|
{
|
|
const ItemBaseEx_info* pItemInfo = NULL;
|
|
|
|
bool bHideHair = false;
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_HELM ) ) // 꾸미기투구.
|
|
{
|
|
if( WearData.bAttachDecoItem ) bAddMesh = true;
|
|
else
|
|
{
|
|
bHideHair = true;
|
|
pItemInfo = GetItemDB().GetItemData( WearData.nDecoItemCode );
|
|
}
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_BIPED, MDECOPART_HELM, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
int itemCode;
|
|
if( WearData.nAppearanceItemCode )
|
|
itemCode = WearData.nAppearanceItemCode;
|
|
else
|
|
itemCode = WearData.nItemCode;
|
|
|
|
if( bAddMesh )
|
|
{
|
|
//헬멧이 제대로 들어가면
|
|
bHideHair = pAvatarEx->AddMesh( ANIPART_BIPED, MPART_HELM, WearData.strFileName.c_str(), strTexture );
|
|
pItemInfo = GetItemDB().GetItemData( itemCode );
|
|
}
|
|
|
|
if( pItemInfo )
|
|
{
|
|
// 2010.08.16 - prodongi
|
|
/*
|
|
int nFlag = 0;
|
|
if( GetRace() == GCLAN_GAIA )
|
|
{
|
|
if( GetSex() == SEX_MALE ) nFlag = pItemInfo->model_type_gam;
|
|
else if( GetSex() == SEX_FEMALE ) nFlag = pItemInfo->model_type_gaf;
|
|
}
|
|
else if( GetRace() == GCLAN_DEVA )
|
|
{
|
|
if( GetSex() == SEX_MALE ) nFlag = pItemInfo->model_type_dem;
|
|
else if( GetSex() == SEX_FEMALE ) nFlag = pItemInfo->model_type_def;
|
|
}
|
|
else if( GetRace() == GCLAN_ASURA )
|
|
{
|
|
if( GetSex() == SEX_MALE ) nFlag = pItemInfo->model_type_asm;
|
|
else if( GetSex() == SEX_FEMALE ) nFlag = pItemInfo->model_type_asf;
|
|
}
|
|
*/
|
|
int nFlag = getHelmItemModelType(GetRace(), GetSex(), pItemInfo);
|
|
|
|
// sonador #2.1.22
|
|
if( bHideHair )
|
|
{
|
|
if( nFlag & ItemBaseEx_info::HAIR_FLAG ) // 헤어를 숨김
|
|
//pAvatarEx->AddMesh( ANIPART_HAIR, MPART_HAIR, "hide_hair" );
|
|
pAvatarEx->AddMesh( ANIPART_BIPED, MPART_HAIR, "hide_hair" );
|
|
if( nFlag & ItemBaseEx_info::FACE_FLAG ) // 페이스 숨김
|
|
pAvatarEx->AddMesh( ANIPART_BIPED, MPART_FACE, "hide_face" );
|
|
// 2010.08.16 - prodongi
|
|
if( nFlag & ItemBaseEx_info::EARRING_FLAG ) // 귀걸이 숨김
|
|
pAvatarEx->AddMesh( ANIPART_BIPED, MPART_ACCE_EAR, "hide_earring" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_GLOVE : // 손
|
|
{
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_GLOVE ) ) // 꾸미기장갑.
|
|
{
|
|
if( WearData.bAttachDecoItem )
|
|
bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_BIPED, MDECOPART_HAND, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
pAvatarEx->AddMesh( ANIPART_BIPED, MPART_HAND, WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_BOOTS : // 발
|
|
{
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_BOOTS ) ) // 꾸미기부츠.
|
|
{
|
|
if( WearData.bAttachDecoItem ) bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_BIPED, MDECOPART_FOOT, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
pAvatarEx->AddMesh( ANIPART_BIPED, MPART_FOOT , WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_MANTLE :
|
|
{
|
|
if( GetGameOption().IsShowMantle() ) //망토 보이기 옵션에 따른 리소스 추가
|
|
{
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_CLOAK ) ) // 꾸미기망토.
|
|
{
|
|
if( WearData.bAttachDecoItem ) bAddMesh = true;
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_MANTLE, MDECOPART_MANTLE, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
else
|
|
{
|
|
bAddMesh = true;
|
|
}
|
|
|
|
if( bAddMesh )
|
|
pAvatarEx->AddMesh( ANIPART_MANTLE , MPART_MANTLE, WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
}
|
|
break; // 망토
|
|
case ItemBase::WEAR_EAR : //귀
|
|
if (GameRule::GetCurrentLocalBitSet() != GameRule::LOCAL_BITSET::ME) // 귀걸이 감추기. 무슬림 국가에서는 다 막아야 할 듯. 일단 중동만
|
|
{
|
|
// 2010.08.16 - prodongi
|
|
// 투구를 착용 했을 경우에 투구의 "투구 모델 적용 타입"에 따라서 귀걸이 적용/비적용을 결정한다
|
|
bool renderEarring = true;
|
|
KSeqAvatar* seqAvatar = pAvatarEx->getAvatarPart(ANIPART_BIPED);
|
|
if (seqAvatar->isRenderMesh(MPART_HELM))
|
|
{
|
|
int nWearSize = (int)m_vWearList.size();
|
|
for( int i(0); nWearSize>i; ++i )
|
|
{
|
|
if (ItemBase::WEAR_HELM == m_vWearList[i].nWearType)
|
|
{
|
|
ItemBaseEx_info const* pItemInfo = GetItemDB().GetItemData( m_vWearList[i].nItemCode );
|
|
if (!pItemInfo)
|
|
break;
|
|
|
|
int flag = getHelmItemModelType(GetRace(), GetSex(), pItemInfo);
|
|
if (ItemBaseEx_info::EARRING_FLAG & flag)
|
|
{
|
|
renderEarring = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (renderEarring)
|
|
pAvatarEx->AddMesh( ANIPART_BIPED , MPART_ACCE_EAR , WearData.strFileName.c_str(), strTexture );
|
|
else
|
|
pAvatarEx->AddMesh(ANIPART_BIPED, MPART_ACCE_EAR, "hide_earring");
|
|
//pAvatarEx->AddMesh( ANIPART_BIPED , MPART_ACCE_EAR , WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_ARMULET : pAvatarEx->AddMesh( ANIPART_NECKLACE, MPART_ACCE_NECK, WearData.strFileName.c_str() ); break; //목걸이
|
|
|
|
case ItemBase::WEAR_FACE :
|
|
{
|
|
// 2010.05.19 - prodongi
|
|
if (!isHideEquipInfo(ItemBase::HIDE_EQUIP_HELM))
|
|
//if( GetGameOption().IsShowHelm() ) //투구보이기 옵션에 따른 리소스 추가
|
|
{
|
|
const ItemBaseEx_info* pItemInfo = GetItemDB().GetItemData( WearData.nItemCode );
|
|
if( pItemInfo )
|
|
{
|
|
// 2010.08.16 - prodongi
|
|
/*
|
|
int nFlag = 0;
|
|
if( GetRace() == GCLAN_GAIA )
|
|
{
|
|
if( GetSex() == SEX_MALE ) nFlag = pItemInfo->model_type_gam;
|
|
else if( GetSex() == SEX_FEMALE ) nFlag = pItemInfo->model_type_gaf;
|
|
}
|
|
else if( GetRace() == GCLAN_DEVA )
|
|
{
|
|
if( GetSex() == SEX_MALE ) nFlag = pItemInfo->model_type_dem;
|
|
else if( GetSex() == SEX_FEMALE ) nFlag = pItemInfo->model_type_def;
|
|
}
|
|
else if( GetRace() == GCLAN_ASURA )
|
|
{
|
|
if( GetSex() == SEX_MALE ) nFlag = pItemInfo->model_type_asm;
|
|
else if( GetSex() == SEX_FEMALE ) nFlag = pItemInfo->model_type_asf;
|
|
}
|
|
*/
|
|
int nFlag = getHelmItemModelType(GetRace(), GetSex(), pItemInfo);
|
|
|
|
if( (nFlag & ItemBaseEx_info::HAIR_FLAG) == ItemBaseEx_info::HAIR_FLAG ) //투구가 있을 경우, 투구로 대체
|
|
{
|
|
if( pAvatarEx->IsExistMesh( ANIPART_BIPED, MPART_HELM ) == 0 &&
|
|
pAvatarEx->IsExistDecoMesh( ANIPART_BIPED, MDECOPART_HELM ) == 0 )
|
|
{ //투구가 없으므로, 가면 추가
|
|
pAvatarEx->AddMesh( ANIPART_BIPED , MPART_ACCE_EYE , WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pAvatarEx->AddMesh( ANIPART_BIPED , MPART_ACCE_EYE , WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ //투구 안 보일 경우에는 무조건 표시
|
|
pAvatarEx->AddMesh( ANIPART_BIPED , MPART_ACCE_EYE , WearData.strFileName.c_str(), strTexture );
|
|
}
|
|
}
|
|
break; //눈
|
|
|
|
//예외
|
|
// case ItemBase::WEAR_EYE : <- WEAR_FACE로 바뀜
|
|
// case ItemBase::WEAR_MOUTH : pAvatarEx->AddMesh( ANIPART_BIPED , MPART_ACCE_LIP , WearData.strFileName.c_str() ); break; //입 MPART_ACCESS
|
|
// case ItemBase::WEAR_EAR_EYE : pAvatarEx->AddMesh( ANIPART_BIPED, MPART_ACCE_EAR , WearData.strFileName.c_str() ); break; // 귀+눈
|
|
// case ItemBase::WEAR_EAR_MOUTH : pAvatarEx->AddMesh( ANIPART_BIPED, MPART_ACCE_EAR , WearData.strFileName.c_str() ); break; // 귀+입
|
|
// case ItemBase::WEAR_EYE_MOUTH : pAvatarEx->AddMesh( ANIPART_BIPED, MPART_ACCE_EYE , WearData.strFileName.c_str() ); break; // 눈+입
|
|
// case ItemBase::WEAR_EYE_EAR_MOUTH : pAvatarEx->AddMesh( ANIPART_BIPED, MPART_ACCE_EYE , WearData.strFileName.c_str() ); break; // 눈+귀+입
|
|
// case ItemBase::WEAR_TWOFINGER_RING : pAvatarEx->AddMesh( ); break; // 반지 두칸 소모
|
|
|
|
//보이는거 아님
|
|
case ItemBase::WEAR_BELT : break; //
|
|
case ItemBase::WEAR_RING : break; //
|
|
case (ItemBase::WEAR_RING+1) : break; //
|
|
|
|
//Link 예외//= 108,// 활//= 109,// 석궁
|
|
case ItemBase::WEAR_TWOHAND :
|
|
{
|
|
pAvatarEx->AddMesh( ANIPART_WEAPON_LEFT, MPART_L_WEAPON, WearData.strFileName.c_str(), strTexture ); //그냥 왼손
|
|
|
|
if( WearData.nItemClass == 0 )
|
|
{
|
|
SetWeaponInfo( pAvatarEx, WearData, NULL );
|
|
}
|
|
else
|
|
{
|
|
std::string strEffectPosname = "wfx_";
|
|
strEffectPosname += WearData.strFileName.c_str();
|
|
SetWeaponInfo( pAvatarEx, WearData, strEffectPosname.c_str() );
|
|
}
|
|
}
|
|
break;
|
|
|
|
//새로 추가됨
|
|
case ItemBase::WEAR_BACKPACK: //어깨
|
|
{
|
|
if (bAddDecoItem && isHideEquipInfo(ItemBase::HIDE_EQUIP_SHOULDER)) // 꾸미기어깨.
|
|
{
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh(ANIPART_BIPED, MDECOPART_SHOULDER2, WearData.strDecoFileName.c_str(), strDecoTexture);
|
|
}
|
|
}
|
|
break;
|
|
case ItemBase::WEAR_DECO_SHOULDER: //어깨
|
|
{
|
|
if( bAddDecoItem && isHideEquipInfo( ItemBase::DECO_HIDE_EQUIP_SHOULDER ) ) // 꾸미기어깨.
|
|
{
|
|
/// 2011.06.11 mantis 13327 - prodongi
|
|
pAvatarEx->AddDecoMesh( ANIPART_BIPED, MDECOPART_SHOULDER, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
}
|
|
}
|
|
break;
|
|
|
|
//case ItemBase::WEAR_DECO_HAIR: //머리 카락
|
|
// {
|
|
// if( bAddDecoItem )
|
|
// {
|
|
// if( m_itemClass[ItemBase::WEAR_DECO_HELM] != 0 ) //치장용 투구가 있으면 헤어 숨김
|
|
// {
|
|
// }
|
|
// else
|
|
// {
|
|
// if( !WearData.bAttachDecoItem ) //기존 헤어 없애기
|
|
// //pAvatarEx->AddMesh( ANIPART_HAIR, MPART_HAIR, "" );
|
|
// pAvatarEx->AddMesh( ANIPART_BIPED, MPART_HAIR, "" );
|
|
// /// 2011.06.11 mantis 13327 - prodongi
|
|
// pAvatarEx->AddDecoMesh( ANIPART_HAIR, MDECOPART_HAIR, WearData.strDecoFileName.c_str(), strDecoTexture );
|
|
// }
|
|
// }
|
|
// }
|
|
// break;
|
|
}
|
|
}
|
|
|
|
AR_UNIT SGamePlayer::GetAttackRange()
|
|
{
|
|
//서버에서 보내준 AttackRange을 적용시키자
|
|
return SGameAvatarEx::GetAttackRange();
|
|
|
|
/* if( m_ItemCode[ItemBase::WEAR_RIGHTHAND] == 0 )
|
|
{
|
|
return SGameAvatarEx::GetAttackRange();
|
|
}
|
|
else
|
|
{
|
|
int nAttackRange = GetItemDB().GetItemData( m_ItemCode[ItemBase::WEAR_RIGHTHAND] )->nRange;
|
|
|
|
return ( nAttackRange / float(GameRule::ATTACK_RANGE_UNIT) ) * GameRule::DEFAULT_UNIT_SIZE ;
|
|
}*/
|
|
}
|
|
|
|
int SGamePlayer::GetItemClass() //현재 장착하고 있는 아이템 클래스 얻기
|
|
{
|
|
//우선 왼손만 리턴한다.
|
|
return m_itemClass[ItemBase::WEAR_RIGHTHAND];
|
|
}
|
|
|
|
int SGamePlayer::GetMaterial() //재질
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// 2011.11.07 - servantes : 크리처 소환시 핸들을 넣어준다
|
|
// 2010.08.12 - prodongi
|
|
void SGamePlayer::SetCreature(AR_HANDLE hCreature, bool enter)
|
|
{
|
|
if (enter)
|
|
{
|
|
m_hCreatureTemp = m_hCreature;
|
|
m_hCreature = hCreature;
|
|
}
|
|
else
|
|
{
|
|
if (m_hCreatureTemp == hCreature)
|
|
{
|
|
m_hCreatureTemp = 0;
|
|
}
|
|
else
|
|
{
|
|
if (m_hCreatureTemp)
|
|
{
|
|
SGameObject* object = GetGameObject(m_hCreatureTemp);
|
|
if (object && object->IsActivated())
|
|
{
|
|
m_hCreature = m_hCreatureTemp;
|
|
m_hCreatureTemp = NULL;
|
|
}
|
|
else
|
|
{
|
|
m_hCreature = 0;
|
|
m_hCreatureTemp = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_hCreature = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SGamePlayer::SetMountMode()
|
|
{
|
|
if( m_pStateVM )
|
|
m_pStateVM->SetMode( SObjectStateMachine::MODE_MOUNT );
|
|
|
|
// sonador 7.0.16 Mantis 0002790: [모션] 아바타가 활을 착용하고 오르니토를 탔을 때 모션 문제
|
|
//if( IsMountMode() )
|
|
// HideWeapon( FALSE );
|
|
|
|
// sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
SetRunNWalkAniSpeedMount();
|
|
}
|
|
|
|
void SGamePlayer::SetAttackMode()
|
|
{
|
|
if( m_pStateVM )
|
|
m_pStateVM->SetMode( SObjectStateMachine::MODE_ATTACK );
|
|
}
|
|
|
|
void SGamePlayer::SetNormalMode()
|
|
{
|
|
if( m_pStateVM )
|
|
m_pStateVM->SetMode( SObjectStateMachine::MODE_NORMAL );
|
|
|
|
// sonador 7.0.16 Mantis 0002790: [모션] 아바타가 활을 착용하고 오르니토를 탔을 때 모션 문제
|
|
//if( !IsMountMode() )
|
|
// HideWeapon( TRUE );
|
|
|
|
// sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
// sonador #2.1.15 변신시 모션 연결 적용
|
|
switch( GetInnObjType() )
|
|
{
|
|
case TS_ENTER::GAME_PLAYER:
|
|
{
|
|
SetRunNWalkAniSpeedDefault();
|
|
}
|
|
break;
|
|
case TS_ENTER::GAME_MOB:
|
|
{
|
|
_MONSTER_INFO_FILE* pMonsterInfo = GetMonsterDB().GetMonsterData( GetInnContentID() );
|
|
if( pMonsterInfo && GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
SetRunNWalkAniSpeed( pMonsterInfo );
|
|
}
|
|
break;
|
|
case TS_ENTER::GAME_SUMMON:
|
|
{
|
|
_SUMMON_INFO_FILE * pSummon = GetCreatureDB().GetCreatureData( GetInnContentID() );
|
|
if( pSummon && GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
SetRunNWalkAniSpeed( pSummon );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SGamePlayer::Damage()
|
|
{
|
|
if( m_pStateVM == NULL ) return;
|
|
|
|
if( _damage() ) return;
|
|
|
|
//이미 공격 중이면, 모션 플레이 안됨.
|
|
if( GetAttackAniLock() )
|
|
return;
|
|
|
|
////이동 중, 공격 중 에는 영향 안 받는다.
|
|
if( GetCurrAnimationID() == ANI_WALK ||
|
|
GetCurrAnimationID() == ANI_RUN ||
|
|
GetCurrAnimationID() == ANI_DEAD01 ) return;
|
|
|
|
//공격 모드 인가, 일반 모드 인가 검사 후 따로 처리
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_ATTACK )
|
|
{
|
|
if( GetCurrAnimationID() == ANI_DEFAULT02 )
|
|
NPlayAnimation( ANI_DAMAGE02, SEQTYPE_NORMAL );
|
|
|
|
if( GetCurrAnimationID() == ANI_DAMAGE02 && !IsPlaying() )
|
|
{
|
|
NPlayAnimation( ANI_DAMAGE02, SEQTYPE_NORMAL );
|
|
}
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL )
|
|
{
|
|
int nAniID = GetCurrAnimationID(); // sonador 1.8.13 아바타 IDLE 모션 동작 구현
|
|
if( nAniID == ANI_DEFAULT01 || nAniID == ANI_IDLE )
|
|
NPlayAnimation( ANI_DAMAGE01, SEQTYPE_NORMAL );
|
|
|
|
if( nAniID == ANI_DAMAGE01 && !IsPlaying() )
|
|
{
|
|
NPlayAnimation( ANI_DAMAGE01, SEQTYPE_NORMAL );
|
|
}
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void SGamePlayer::Default( bool bForce/*=false*/ )
|
|
{
|
|
//if( GetHP() <= 0 )
|
|
// return;
|
|
if( m_pStateVM == NULL ) return;
|
|
|
|
if( !bForce )
|
|
{
|
|
if( IsAniLock() )
|
|
return;
|
|
|
|
if( GetAttackAniLock() )
|
|
return;
|
|
|
|
if( CurrentlyAnimationIsAttack() && IsPlaying() )
|
|
return;
|
|
}
|
|
|
|
//전투 대기 상태 이면, 전투 대기 기본 애니
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_ATTACK )
|
|
{
|
|
if( GetCurrAnimationID() != ANI_DEFAULT02 && m_isKMoving==0)
|
|
NPlayAnimation( ANI_DEFAULT02, SEQTYPE_LOOP );
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL )
|
|
{ //
|
|
_resetIdleTime(); // sonador 1.8.13 아바타 IDLE 모션 동작 구현
|
|
if( GetCurrAnimationID() != ANI_DEFAULT01 )
|
|
NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
switch( GetRideType() )
|
|
{
|
|
case SGameAvatarEx::RIDE_HIGH_TYPE:
|
|
{
|
|
if( GetCurrAnimationID() != ANI_M_DEFAULT01_HIGH )
|
|
NPlayAnimation( ANI_M_DEFAULT01_HIGH, SEQTYPE_LOOP );
|
|
}
|
|
break;
|
|
case SGameAvatarEx::RIDE_LOW_TYPE:
|
|
{
|
|
if( GetCurrAnimationID() != ANI_M_DEFAULT01_LOW )
|
|
NPlayAnimation( ANI_M_DEFAULT01_LOW, SEQTYPE_LOOP );
|
|
}
|
|
break;
|
|
case SGameAvatarEx::RIDE_QILIN_TYPE: // #2.1.6 sonador
|
|
{
|
|
if( GetCurrAnimationID() != ANI_M_DEFAULT01_QILIN )
|
|
NPlayAnimation( ANI_M_DEFAULT01_QILIN, SEQTYPE_LOOP );
|
|
}
|
|
break;
|
|
case SGameAvatarEx::RIDE_WHITE_TYPE: // #2.1.14
|
|
{
|
|
if( GetCurrAnimationID() != ANI_M_DEFAULT01_WHITE )
|
|
NPlayAnimation( ANI_M_DEFAULT01_WHITE, SEQTYPE_LOOP );
|
|
}
|
|
break;
|
|
case SGameAvatarEx::RIDE_UNICORN_TYPE: // #2.1.14
|
|
{
|
|
if( GetCurrAnimationID() != ANI_M_DEFAULT01_UNICORN )
|
|
NPlayAnimation( ANI_M_DEFAULT01_UNICORN, SEQTYPE_LOOP );
|
|
}
|
|
break;
|
|
case SGameAvatarEx::RIDE_BEAKHO_TYPE: /// 2011.02.08 - prodongi
|
|
{
|
|
if( GetCurrAnimationID() != ANI_M_DEFAULT01_BEAKHO )
|
|
NPlayAnimation( ANI_M_DEFAULT01_BEAKHO, SEQTYPE_LOOP );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
SetVisibleWeaponTrail( false );
|
|
}
|
|
|
|
void SGamePlayer::Default3()
|
|
{
|
|
if( m_pStateVM == NULL ) return;
|
|
|
|
m_pStateVM->SetMode( SObjectStateMachine::MODE_ATTACK );
|
|
|
|
//if( GetHP() <= 0 )
|
|
// return;
|
|
|
|
if( !( GetCurrAnimationID() == ANI_DEFAULT01 || GetCurrAnimationID() == ANI_IDLE ) ) return; // sonador 1.8.13 아바타 IDLE 모션 동작 구현
|
|
|
|
if( CurrentlyAnimationIsAttack() && IsPlaying() )
|
|
return;
|
|
|
|
//전투 대기 상태 이면, 전투 대기 기본 애니
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_ATTACK )
|
|
{
|
|
if( GetCurrAnimationID() != ANI_DEFAULT02 )
|
|
NPlayAnimation( ANI_DEFAULT02, SEQTYPE_LOOP );
|
|
}
|
|
|
|
SetVisibleWeaponTrail( false );
|
|
}
|
|
|
|
//void SGamePlayer::MDefault()
|
|
//{
|
|
// if( !m_pSeqAvatar ) return;
|
|
//
|
|
// if( CurrentlyAnimationIsAttack() && IsPlaying() )
|
|
// return;
|
|
//
|
|
// //전투 대기 상태 이면, 전투 대기 기본 애니
|
|
// if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
// {
|
|
// if( GetCurrAnimationID() != ANI_M_DEFAULT01 )
|
|
// NPlayAnimation( ANI_M_DEFAULT01, SEQTYPE_LOOP );
|
|
// }
|
|
//}
|
|
|
|
void SGamePlayer::Throw() //던지기
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void SGamePlayer::PickUp() //줍기
|
|
{
|
|
if( m_pStateVM == NULL ) return;
|
|
|
|
if( IsDead() ) return;
|
|
|
|
//전투 대기
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_ATTACK ||
|
|
m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL )
|
|
{
|
|
if( GetCurrAnimationID() == ANI_DEFAULT02 )
|
|
NPlayAnimation( ANI_PICKUP01, SEQTYPE_NORMAL );
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
|
|
}
|
|
|
|
//보통
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_ATTACK ||
|
|
m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL )
|
|
{
|
|
NPlayAnimation( ANI_PICKUP01, SEQTYPE_NORMAL );
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
// NPlayAnimation( ANI_PICKUP01, SEQTYPE_NORMAL );
|
|
}
|
|
}
|
|
|
|
|
|
void SGamePlayer::PickUpEx()
|
|
{
|
|
NPlayAnimation( ANI_PICKUP01, SEQTYPE_NORMAL );
|
|
}
|
|
|
|
void SGamePlayer::Walk( bool bLoop, int nAniType )
|
|
{
|
|
if( GetCurrAnimationID() != nAniType )
|
|
NPlayAnimation( nAniType, SEQTYPE_LOOP, m_fPlayRate );
|
|
}
|
|
void SGamePlayer::Run( bool bAutoRun, int nAniType )
|
|
{
|
|
if( GetCurrAnimationID() != nAniType )
|
|
NPlayAnimation( nAniType, SEQTYPE_LOOP, m_fPlayRate );
|
|
}
|
|
|
|
void SGamePlayer::Rush( int nAniType, float fPlayRate )
|
|
{
|
|
NPlayAnimation( nAniType, SEQTYPE_LOOP, fPlayRate );
|
|
}
|
|
|
|
void SGamePlayer::SitProcess( int nAniType, int nType ) //앉은 상태
|
|
{
|
|
NPlayAnimation( nAniType, nType );
|
|
}
|
|
|
|
void SGamePlayer::StandUp( DWORD time ) //기본 자세
|
|
{
|
|
if( m_pStateVM == NULL ) return;
|
|
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_ATTACK )
|
|
{
|
|
NPlayAnimation( ANI_DEFAULT02, SEQTYPE_LOOP );
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL )
|
|
{
|
|
NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
|
}
|
|
else if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
|
}
|
|
}
|
|
|
|
void SGamePlayer::Cast01() //손 올리기
|
|
{
|
|
NPlayAnimation( ANI_CAST01_A, SEQTYPE_LOOP );
|
|
}
|
|
|
|
void SGamePlayer::Cast02(bool bLoop) //모으기
|
|
{
|
|
if( bLoop )
|
|
{
|
|
if( GetCurrAnimationID() == ANI_CAST01_A )
|
|
NPlayAnimation( ANI_CAST01_B, SEQTYPE_LOOP );
|
|
}
|
|
else
|
|
{
|
|
if( GetCurrAnimationID() == ANI_CAST01_A )
|
|
NPlayAnimation( ANI_CAST01_B );
|
|
}
|
|
}
|
|
|
|
void SGamePlayer::Fire( int nAniID )
|
|
{
|
|
if( ANI_FIRE_MAGIC01 == nAniID ||
|
|
ANI_FIRE_MAGIC02 == nAniID ||
|
|
ANI_FIRE_MAGIC03 == nAniID ||
|
|
ANI_FIRE_MAGIC04 == nAniID ||
|
|
ANI_FIRE_MAGIC05 == nAniID )
|
|
NPlayAnimation( nAniID );
|
|
}
|
|
|
|
void SGamePlayer::NPlayAnimation( int nType , int nAniType, float fPlayRate )
|
|
{
|
|
// _oprint( "다른 플레이 Ani 변경 %d\n", nType );
|
|
if( IsDead() && GetHP() <= 0 )
|
|
{
|
|
if( nType == ANI_DEAD01 ||
|
|
nType == ANI_DEAD02 )
|
|
{
|
|
if( nType == m_nPrevAniType )
|
|
return;
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
|
|
if( m_pSeqAvatar )
|
|
{
|
|
m_nPrevAniType = nType;
|
|
}
|
|
|
|
SGameAvatarEx::NPlayAnimation( nType , nAniType, fPlayRate );
|
|
}
|
|
|
|
void SGamePlayer::OnNetInput( struct SGameMessage * pMsg )
|
|
{
|
|
if( !m_pStateVM ) return;
|
|
m_pStateVM->OnNetInput( pMsg );
|
|
}
|
|
|
|
void SGamePlayer::SetPlayerViewVector( const K3DVector& vTargetPos )
|
|
{
|
|
if( !IsLocalPlayer() )
|
|
{
|
|
SetViewVector( vTargetPos ); //몸통 방향 바꾸기
|
|
}
|
|
else
|
|
{
|
|
if( vTargetPos.y == GetPosition()->y && vTargetPos.x == GetPosition()->x )
|
|
return;
|
|
m_fTargetRoll = atan2( vTargetPos.y-GetPosition()->y, vTargetPos.x-GetPosition()->x );
|
|
m_dwPrevTime = m_dwTime;
|
|
m_bUseRot = true;
|
|
}
|
|
}
|
|
|
|
void SGamePlayer::OnChangeState( SObjectState::ID stateid, const SStateInfo &info )
|
|
{
|
|
if( m_pStateVM == NULL ) return;
|
|
|
|
//STATE_FIRE가 2번째 들어온 상태에서 RUN 에니매이션이면 Default로 바꿔준다
|
|
if( m_idPrevState == SObjectState::STATE_FIRE &&
|
|
stateid == SObjectState::STATE_FIRE )
|
|
{
|
|
if( GetCurrAnimationID() == ANI_RUN )
|
|
{
|
|
SetAniLock( false );
|
|
Default();
|
|
}
|
|
}
|
|
|
|
if (IsLocalPlayer())
|
|
{
|
|
if (stateid==SObjectState::STATE_IDLE || stateid==SObjectState::STATE_ATTACK_END || stateid== SObjectState::STATE_SHOOTING || stateid== SObjectState::STATE_FIRE)
|
|
setKMoveType(0);
|
|
}
|
|
// _oprint( "*****상태 머신 : %d\n", stateid );
|
|
|
|
//상태가 바뀌었다.. 애니메이션 바꾸자, Work 기반으로
|
|
switch( stateid )
|
|
{
|
|
case SObjectState::STATE_IDLE :
|
|
{
|
|
//_oprint( "*****상태 머신 : 기본 상태 변경\n" );
|
|
//서기도 같이 온다.
|
|
// SWorkAniStandUp standup( this, m_dwTime );
|
|
// standup.Process(0);
|
|
|
|
//앉기, 줍기 프로세스 되도록 고치자~
|
|
if( GetCurrAnimationID() == ANI_SIT )
|
|
{
|
|
SetAniLock( false );
|
|
Default();
|
|
}
|
|
|
|
if( (GetCurrAnimationID() == ANI_RUN ||
|
|
GetCurrAnimationID() == ANI_WALK ) && !IsMoving() )
|
|
{
|
|
// Default();
|
|
}
|
|
|
|
////스킬 취소가 왔을 경우 인데..
|
|
//if( GetCurrAnimationID() == ANI_CAST01_B ||
|
|
// GetCurrAnimationID() == ANI_FIRE_MAGIC01 ||
|
|
// GetCurrAnimationID() == ANI_FIRE_MAGIC02 ||
|
|
// GetCurrAnimationID() == ANI_FIRE_MAGIC03 ||
|
|
// GetCurrAnimationID() == ANI_FIRE_MAGIC04 ||
|
|
// GetCurrAnimationID() == ANI_FIRE_MAGIC05 )
|
|
//{
|
|
// SetAniLock( false );
|
|
// Default();
|
|
//}
|
|
|
|
if( !IsPlaying() && ( CurrentlyAnimationIsAttack() || CurrentlyAnimationIsDamage() ) )
|
|
{
|
|
// Default();
|
|
}
|
|
|
|
//전투 대기 모션 && 기본 모드, 모드가 바뀌 었다.
|
|
if( GetCurrAnimationID() == ANI_DEFAULT02 && m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL )
|
|
{
|
|
Default();
|
|
}
|
|
|
|
// sonador #2.1.6
|
|
if( CurrentlyAnimationIsMRun() || CurrentlyAnimationIsMWalk() && !IsMoving() &&
|
|
m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
Default();
|
|
}
|
|
|
|
break; //기본 상태
|
|
}
|
|
case SObjectState::STATE_ATTACK :
|
|
{
|
|
//_oprint( "*****상태 머신 : 공격 상태 시간\n" );
|
|
// _oprint( "공격 상태 시간 : %d\n", m_dwTime );
|
|
|
|
SetPlayerViewVector( info.vTargetPos );
|
|
|
|
//일반 공격
|
|
OnAttack( info );
|
|
|
|
}
|
|
break; // 공격 (1회)
|
|
case SObjectState::STATE_ATTACK_END :
|
|
{
|
|
//_oprint( "SKILL - SObjectState::STATE_CAST_CANCEL\n" );
|
|
m_bIsUseSkill_complete = true;
|
|
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; i++)
|
|
m_vAttackEventList[i]->ForceEnd();
|
|
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->ForceEnd();
|
|
|
|
// for( unsigned int i(0); m_vFireSkillList.size()>i; i++ )
|
|
// m_vFireSkillList[i]->ForceEnd();
|
|
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default(true);
|
|
break;
|
|
}
|
|
case SObjectState::STATE_MOVE :
|
|
{
|
|
if( info.dwSpeed == 0 )
|
|
{
|
|
//달리다 죽은 것이므로 Ani 처리는 스킵한다.
|
|
return;
|
|
}
|
|
|
|
// _oprint( "SObjectState::STATE_MOVE : %f, %f, %f \n", info.vTargetPos.x, info.vTargetPos.y, info.vTargetPos.z );
|
|
|
|
//ProcessDEF에서 처리한다
|
|
// SetPlayerViewVector( info.vTargetPos );
|
|
|
|
SetAniLock( false );
|
|
|
|
//_oprint( "*****상태 머신 : 이동\n" );
|
|
if( info.dwSpeed >= m_fWalkSpeed )
|
|
{
|
|
if( GetInnObjType() != TS_ENTER::GAME_PLAYER )
|
|
CalcCreatureRunPlayRate( (float)info.dwSpeed );
|
|
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
CalcCreatureRunPlayRate( (float)info.dwSpeed );
|
|
Run( false, GetPlayerMRunAniID() ); // sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
}
|
|
else
|
|
{
|
|
Run();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( GetInnObjType() != TS_ENTER::GAME_PLAYER )
|
|
CalcCreatureWalkPlayRate( (float)info.dwSpeed );
|
|
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
CalcCreatureWalkPlayRate( (float)info.dwSpeed );
|
|
Walk( true, GetPlayerMWalkAniID() ); // sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
}
|
|
else
|
|
Walk(true);
|
|
}
|
|
}
|
|
break; // 이동
|
|
|
|
case SObjectState::STATE_CHASE :
|
|
{
|
|
//ProcessDEF에서 처리한다
|
|
// SetPlayerViewVector( info );
|
|
|
|
SetAniLock( false );
|
|
//_oprint( "*****상태 머신 : 추적\n" );
|
|
if( info.dwSpeed >= 10 )
|
|
{
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
Run( false, GetPlayerMRunAniID() ); // sonador #2.1.6
|
|
}
|
|
else //( m_pStateVM->GetMode() == SObjectStateMachine::MODE_NORMAL || SObjectStateMachine::MODE_ATTACK )
|
|
Run();
|
|
}
|
|
else
|
|
{
|
|
if( m_pStateVM->GetMode() == SObjectStateMachine::MODE_MOUNT )
|
|
{
|
|
Walk( true, GetPlayerMWalkAniID() ); // sonador #2.1.6
|
|
}
|
|
else
|
|
Walk(true);
|
|
}
|
|
}
|
|
break; // 추격
|
|
case SObjectState::STATE_MOUNT:
|
|
{
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; i++)
|
|
m_vAttackEventList[i]->ForceEnd();
|
|
|
|
SWorkMount* pMount = new SWorkMount( this, info.hTarget );
|
|
// SWorkMountWithOutAnimation* pMount = new SWorkMountWithOutAnimation( this, info.hTarget );
|
|
m_vAttackEventList.push_back( pMount );
|
|
}
|
|
break;
|
|
case SObjectState::STATE_UNMOUNT:
|
|
{
|
|
/* if( info.UnMountFlag == TS_SC_UNMOUNT_SUMMON::FALL ||
|
|
info.UnMountFlag == TS_SC_UNMOUNT_SUMMON::UNSUMMON )*/
|
|
{
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; i++)
|
|
m_vAttackEventList[i]->ForceEnd();
|
|
}
|
|
|
|
//자동이동 경로 삭제
|
|
ClearWayPointList();
|
|
|
|
SWorkUnMount* pUnMount = new SWorkUnMount( this, info.hTarget, info.UnMountFlag );
|
|
// SWorkUnMountWithOutAnimation* pUnMount = new SWorkUnMountWithOutAnimation( this, info.hTarget, info.UnMountFlag );
|
|
m_vAttackEventList.push_back( pUnMount );
|
|
}
|
|
break;
|
|
case SObjectState::STATE_AIMING :
|
|
{
|
|
_oprint( "AIMING - SObjectState::STATE_AIMING\n" );
|
|
//활쏘기 예외 처리
|
|
if( info.attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_BOW ||
|
|
info.attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_CROSS_BOW )
|
|
{
|
|
if( info.attack_action == TS_ATTACK_EVENT::ATTACK_AIMING )
|
|
{ //활 조준
|
|
SWorkAimingBow * pAiming = new SWorkAimingBow( this, info.hTarget, info.attack_flag );
|
|
m_vCastSkillList.push_back( pAiming );
|
|
|
|
_oprint( "활 조준 Cast \n" );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case SObjectState::STATE_CAST :
|
|
{
|
|
//_oprint( "SKILL - SObjectState::STATE_CAST\n" );
|
|
|
|
//_oprint( "*****상태 머신 : 캐스팅\n" );
|
|
|
|
m_bIsUseSkill_complete = false;
|
|
|
|
/// 2011.05.09 만약 지면 타겟 스킬이면 타겟 위치로 플레이어의 방향을 바꿔준다 - prodongi
|
|
if (info.isRegionTarget)
|
|
{
|
|
SetPlayerViewVector(info.vTargetPos);
|
|
}
|
|
|
|
//캐스팅 표시
|
|
if( IsLocalPlayer() )
|
|
UseSkill( GetArID(), info.nSkillID, info.nSkillLv, info.dwSpeed );
|
|
|
|
//캐스팅 관련 연출 설정
|
|
//1) 애니메이션 연출 -> 설정 된 애니메이션의 이벤트 핸들 처리
|
|
//2) FX 출력
|
|
//New Process
|
|
_SKILL_FX* pSkillFXDB = GetSkillStageDB().GetSkillStageData( info.nSkillID );
|
|
if( !pSkillFXDB )
|
|
{
|
|
_oprint( "스킬 연출 데이타 없음!!! [스킬ID:%d]\n", info.nSkillID );
|
|
// assert( 0 && "스킬 연출 데이타 없음!!!" );
|
|
return;
|
|
}
|
|
|
|
_SKILL_FX* pSkillFX = new _SKILL_FX;
|
|
*pSkillFX = *pSkillFXDB;
|
|
|
|
float fRate = 1.f;
|
|
if( pSkillFX->nCasting_Type_Id != 1 && (pSkillFX->nCasting_Start_Motion_Id !=0 || pSkillFX->nCasting_Middle_Motion_Id != 0) )
|
|
{
|
|
std::string strAniKey;
|
|
int nBoneCount = 0;
|
|
DWORD dwMinTime, dwMaxTime, totalTime;
|
|
dwMinTime = 0;
|
|
dwMaxTime = 0;
|
|
totalTime = 0;
|
|
|
|
if( pSkillFX->nCasting_Start_Motion_Id != 0 )
|
|
{
|
|
strAniKey = GetAniKey( GetObjType(), pSkillFX->nCasting_Start_Motion_Id, true );
|
|
if( m_pSeqAvatar )
|
|
m_pSeqAvatar->GetFrameInfo( ANIPART_BIPED, strAniKey.c_str(), nBoneCount, dwMinTime, dwMaxTime );
|
|
|
|
totalTime = dwMaxTime;
|
|
}
|
|
|
|
if( pSkillFX->nCasting_Middle_Motion_Id )
|
|
{
|
|
strAniKey = GetAniKey( GetObjType(), pSkillFX->nCasting_Middle_Motion_Id, true );
|
|
if( m_pSeqAvatar )
|
|
m_pSeqAvatar->GetFrameInfo( ANIPART_BIPED, strAniKey.c_str(), nBoneCount, dwMinTime, dwMaxTime );
|
|
|
|
totalTime += dwMaxTime;
|
|
}
|
|
|
|
float fAttack = GetAttackSpeed( info.dwSpeed*10 );
|
|
//기본 배율
|
|
fRate = GetAniPlayRate( fAttack, totalTime, false );
|
|
|
|
|
|
}
|
|
|
|
//switch( pSkillFX->nCasting_Type_Id )
|
|
//{
|
|
//case _SKILL_FX::SKILLTYPE_NOACT : break;
|
|
//case _SKILL_FX::SKILLTYPE_MAGIC : break;
|
|
//case _SKILL_FX::SKILLTYPE_INSTANT : break;
|
|
//case _SKILL_FX::SKILLTYPE_INSTANT_CONTINUE : break;
|
|
//case _SKILL_FX::SKILLTYPE_CHARGE : break;
|
|
//case _SKILL_FX::SKILLTYPE_CHARGE_CONTINUE : break;
|
|
//}
|
|
|
|
//pSkillFX->nCasting_Start_Motion_Id; //시작
|
|
//pSkillFX->nCasting_Middle_Motion_Id; //시작 Loop
|
|
|
|
SNewSkill * pSkill_Cast = NULL;
|
|
SGameAvatarEx * pTarget = NULL;
|
|
|
|
if( info.hTarget )
|
|
{
|
|
pTarget = (SGameAvatarEx *)GetGameObject( info.hTarget );
|
|
}
|
|
|
|
switch( pSkillFX->nStage_Type_Id )
|
|
{
|
|
//크리처 소환 캐스팅일 경우 타겟 위치를 저장한다
|
|
case SS_TYPE_001 : { SWorkSummonCall * pSkill = new SWorkSummonCall( this, pSkillFX ); pSkill->SetPosition( (K3DVector*)&info.vTargetPos ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_002 : { SWorkSummonReCall * pSkill = new SWorkSummonReCall( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_101 : { SWorkWeaponSwingHit * pSkill = new SWorkWeaponSwingHit( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_111 : { SWorkShieldSwingHit * pSkill = new SWorkShieldSwingHit( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_121 : { SWorkWeaponSwing_3Motion * pSkill = new SWorkWeaponSwing_3Motion( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_122 : { SWorkWeaponSwing_ContinuousHits * pSkill = new SWorkWeaponSwing_ContinuousHits( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_123 : { SWorkWeaponSwing_Zeal * pSkill = new SWorkWeaponSwing_Zeal( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_151 : { SWorkWeaponSwing_Leech * pSkill = new SWorkWeaponSwing_Leech( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_171 : break;//{ //TODO : 밀기 - 서버 메세지 처리 넣어야 함. SWorkRush_Shove* pSkill = new SWorkRush_Shove( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
// case SS_TYPE_172 : { break;
|
|
// case SS_TYPE_173 : { break;
|
|
// case SS_TYPE_174 : { break;
|
|
case SS_TYPE_201 : { SWorkBowShoot* pSkill = new SWorkBowShoot( this, pSkillFX ); pSkill_Cast = pSkill; fRate = 1.f; } break;
|
|
case SS_TYPE_212 : { SWorkBowShoot* pSkill = new SWorkBowShoot( this, pSkillFX ); pSkill_Cast = pSkill; fRate = 1.f; } break;
|
|
case SS_TYPE_251 : { SWorkBowShoot* pSkill = new SWorkBowShoot( this, pSkillFX ); pSkill_Cast = pSkill; fRate = 1.f; } break;
|
|
// case SS_TYPE_211 : { break;
|
|
// case SS_TYPE_212 : { SWorkBowShoot_Shove * pSkill = new SWorkBowShoot_Shove( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
// case SS_TYPE_251 : { SWorkBowShoot_Leech * pSkill = new SWorkBowShoot_Leech( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_301 : { SWorkSelf * pSkill = new SWorkSelf( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_404 :
|
|
case SS_TYPE_401 :
|
|
{ SWorkMotion * pSkill = new SWorkMotion( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_402 : { SWorkMotion_Leech * pSkill = new SWorkMotion_Leech( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_403 : { SWorkMotion_SummonMotion_Leech * pSkill = new SWorkMotion_SummonMotion_Leech( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_411 : { SWorkMotion_FXMotion * pSkill = new SWorkMotion_FXMotion( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_412 : { SWorkMotion_FXMotionMultiple * pSkill = new SWorkMotion_FXMotionMultiple( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_501 : { SWorkShoot_FXShoot * pSkill = new SWorkShoot_FXShoot( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_502 : { SWorkShoot_FXShootMultiple * pSkill = new SWorkShoot_FXShootMultiple( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_503 : { SWorkShoot_FXShootPenetrate * pSkill = new SWorkShoot_FXShootPenetrate( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
/// 2011.03.23 - prodongi
|
|
case SS_TYPE_504 : { SWorkShoot_FXShootChain * pSkill = new SWorkShoot_FXShootChain( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
case SS_TYPE_601 :
|
|
case SS_TYPE_604 : { SWorkGround_FXContinue * pSkill = new SWorkGround_FXContinue( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
// case SS_TYPE_602 : break;
|
|
// case SS_TYPE_603 : break;
|
|
// case SS_TYPE_701 : break;
|
|
case SS_TYPE_1001: { SWorkingSkill* pSkill = new SWorkingSkill( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
default:
|
|
{
|
|
_oprint( "구현 보류 중인 스킬입니다.기획팀에 사용 여부를 확인 후, 프로그램 팀에 구현 여부를 확인 바랍니다.\n" );
|
|
// assert( 0 && "구현 보류 중인 스킬입니다.기획팀에 사용 여부를 확인 후, 프로그램 팀에 구현 여부를 확인 바랍니다.\n" );
|
|
}
|
|
break;
|
|
}
|
|
|
|
if( pSkill_Cast )
|
|
{ //변경 되었으면, PlayRate 수정
|
|
if( fRate != 1.f && pSkillFX->nCasting_Type_Id != 1 ) //마법류는 PlayRate 수정 하지 않는다.
|
|
|
|
pSkill_Cast->SetPlayRate( fRate/4.8f );
|
|
if( pTarget )
|
|
{
|
|
pSkill_Cast->SetTarget( info.hTarget, pTarget );
|
|
|
|
if(pSkillFX->nStage_Type_Id == SS_TYPE_402 )
|
|
{
|
|
pTarget->SetReservation(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SkillBaseEx* skillBase = GetSkillDB().GetSkillData(info.nSkillID);
|
|
if (skillBase && skillBase->getTargetType() == SkillBase::SKILL_TARGET_POSITION)
|
|
{
|
|
pSkill_Cast->SetTarget(info.hSelf, (SGameAvatarEx *)GetGameObject(info.hSelf));
|
|
}
|
|
}
|
|
|
|
pSkill_Cast->SetStartTime( m_dwTime );
|
|
pSkill_Cast->SetSkillMode( SNewSkill::SKILLMODE_CAST );
|
|
pSkill_Cast->SetCastingTime( info.dwSpeed );
|
|
m_vCastSkillList.push_back( pSkill_Cast );
|
|
|
|
m_nWeaponSwing_RepeatMotion = 0;
|
|
}
|
|
else
|
|
SAFE_DELETE( pSkillFX );
|
|
|
|
break; // 캐스팅
|
|
}
|
|
case SObjectState::STATE_SHOOTING :
|
|
{
|
|
_oprint( "SHOOTING - SObjectState::STATE_SHOOTING\n" );
|
|
//활쏘기 예외 처리
|
|
if( info.attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_BOW ||
|
|
info.attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_CROSS_BOW )
|
|
{
|
|
if( info.attack_action == TS_ATTACK_EVENT::ATTACK_ATTACK )
|
|
{
|
|
//돌고 있는 케스팅은 모두 강제 끝
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->ForceEnd();
|
|
|
|
//활쏘기
|
|
SWorkShootingBow * pShooting = new SWorkShootingBow( this, info.hTarget, info.attack_flag );
|
|
pShooting->SetDamegeInfo( &info );
|
|
m_vFireSkillList.push_back( pShooting );
|
|
|
|
_oprint( "활 쏘기 Fire \n" );
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case SObjectState::STATE_FIRE :
|
|
{
|
|
//SkillResult가 0이면 Fire실패 Default모션으로
|
|
if(info.vSkillResult.empty())
|
|
{
|
|
m_bIsUseSkill_complete = true;
|
|
|
|
/// 2011.05.09 프랍 범위 스킬을 발동 할 때, 발동 모션이 나오도록 수정- prodongi
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->CastCancel();
|
|
|
|
_SKILL_FX* pSkillFXDB = GetSkillStageDB().GetSkillStageData( info.nSkillID );
|
|
if (pSkillFXDB && pSkillFXDB->nFire_Motion_Id)
|
|
{
|
|
_SKILL_FX* pSkillFX = new _SKILL_FX;
|
|
*pSkillFX = *pSkillFXDB;
|
|
SNewSkill* pSkill_Fire = new SNewSkill(this, pSkillFX);
|
|
|
|
pSkill_Fire->SetTarget(GetArID(), this);
|
|
pSkill_Fire->SetStartTime( m_dwTime );
|
|
pSkill_Fire->SetSkillMode( SNewSkill::SKILLMODE_FIRE );
|
|
m_vFireSkillList.push_back( pSkill_Fire );
|
|
}
|
|
else
|
|
{
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default( true );
|
|
}
|
|
|
|
/*
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->CastCancel();
|
|
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default( true );
|
|
*/
|
|
|
|
return;
|
|
}
|
|
|
|
//_oprint( "SKILL - SObjectState::STATE_FIRE\n" );
|
|
// _oprint( "*****상태 머신 : 발사\n" );
|
|
|
|
//New Process
|
|
//Cast 관련 사운드 끄기
|
|
//Cast 관련 이펙트 끄기
|
|
_SKILL_FX* pSkillFXDB = GetSkillStageDB().GetSkillStageData( info.nSkillID );
|
|
|
|
if( !pSkillFXDB )
|
|
{
|
|
_oprint( "스킬 연출 데이타 없음!!! [스킬ID:%d]\n", info.nSkillID );
|
|
// assert( 0 && "스킬 연출 데이타 없음!!!" );
|
|
return;
|
|
}
|
|
|
|
_SKILL_FX* pSkillFX = new _SKILL_FX;
|
|
*pSkillFX = *pSkillFXDB;
|
|
|
|
SNewSkill * pSkill_Fire = NULL;
|
|
SGameAvatarEx * pTarget = NULL;
|
|
|
|
if( info.hTarget )
|
|
{
|
|
pTarget = (SGameAvatarEx *)GetGameObject( info.hTarget );
|
|
}
|
|
|
|
switch( pSkillFX->nStage_Type_Id )
|
|
{
|
|
case SS_TYPE_001 : { SWorkSummonCall * pSkill = new SWorkSummonCall( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_002 : { SWorkSummonReCall * pSkill = new SWorkSummonReCall( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_101 : { SWorkWeaponSwingHit * pSkill = new SWorkWeaponSwingHit( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_111 : { SWorkShieldSwingHit * pSkill = new SWorkShieldSwingHit( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_121 : { SWorkWeaponSwing_3Motion * pSkill = new SWorkWeaponSwing_3Motion( this, pSkillFX ); pSkill_Fire = pSkill; pSkill->SetCurHitCount( m_nWeaponSwing_RepeatMotion ); } break;
|
|
case SS_TYPE_122 : { SWorkWeaponSwing_ContinuousHits * pSkill = new SWorkWeaponSwing_ContinuousHits( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_123 : { SWorkWeaponSwing_Zeal * pSkill = new SWorkWeaponSwing_Zeal( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_151 : { SWorkWeaponSwing_Leech * pSkill = new SWorkWeaponSwing_Leech( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_171 : break;//{ //TODO : 밀기 - 서버 메세지 처리 넣어야 함. SWorkRush_Shove* pSkill = new SWorkRush_Shove( this, pSkillFX ); pSkill_Cast = pSkill; } break;
|
|
// case SS_TYPE_172 : { break;
|
|
// case SS_TYPE_173 : { break;
|
|
// case SS_TYPE_174 : { break;
|
|
case SS_TYPE_201 : { SWorkBowShoot* pSkill = new SWorkBowShoot( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_212 : { SWorkBowShoot* pSkill = new SWorkBowShoot( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_251 : { SWorkBowShoot* pSkill = new SWorkBowShoot( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
// case SS_TYPE_211 : { break;
|
|
// case SS_TYPE_212 : { SWorkBowShoot_Shove * pSkill = new SWorkBowShoot_Shove( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
// case SS_TYPE_251 : { SWorkBowShoot_Leech * pSkill = new SWorkBowShoot_Leech( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_301 : { SWorkSelf * pSkill = new SWorkSelf( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_401 :
|
|
case SS_TYPE_404 :
|
|
{ SWorkMotion * pSkill = new SWorkMotion( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_402 : { SWorkMotion_Leech * pSkill = new SWorkMotion_Leech( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_403 : { SWorkMotion_SummonMotion_Leech * pSkill = new SWorkMotion_SummonMotion_Leech( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_411 : { SWorkMotion_FXMotion * pSkill = new SWorkMotion_FXMotion( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_412 : { SWorkMotion_FXMotionMultiple * pSkill = new SWorkMotion_FXMotionMultiple( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_501 : { SWorkShoot_FXShoot * pSkill = new SWorkShoot_FXShoot( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_502 : { SWorkShoot_FXShootMultiple * pSkill = new SWorkShoot_FXShootMultiple( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_503 : { SWorkShoot_FXShootPenetrate * pSkill = new SWorkShoot_FXShootPenetrate( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_504 : { SWorkShoot_FXShootChain * pSkill = new SWorkShoot_FXShootChain( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
case SS_TYPE_601 :
|
|
case SS_TYPE_604 : { SWorkGround_FXContinue * pSkill = new SWorkGround_FXContinue( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
// case SS_TYPE_602 : break;
|
|
// case SS_TYPE_603 : break;
|
|
// case SS_TYPE_701 : break;
|
|
case SS_TYPE_1001: { SWorkingSkill* pSkill = new SWorkingSkill( this, pSkillFX ); pSkill_Fire = pSkill; } break;
|
|
default:
|
|
{
|
|
_oprint( "구현 보류 중인 스킬입니다.기획팀에 사용 여부를 확인 후, 프로그램 팀에 구현 여부를 확인 바랍니다.\n" );
|
|
// assert( 0 && "구현 보류 중인 스킬입니다.기획팀에 사용 여부를 확인 후, 프로그램 팀에 구현 여부를 확인 바랍니다.\n" );
|
|
}
|
|
break;
|
|
}
|
|
|
|
if( pSkillFX->nStage_Type_Id == SS_TYPE_121 )
|
|
{
|
|
//최대 연타 수 ( DB에 정의됨 )
|
|
if( m_nWeaponSwing_RepeatMotion < pSkillFXDB->fStage_Data[9] )
|
|
++m_nWeaponSwing_RepeatMotion;
|
|
else
|
|
m_nWeaponSwing_RepeatMotion = 0;
|
|
}
|
|
else
|
|
m_nWeaponSwing_RepeatMotion = 0;
|
|
|
|
if( pSkill_Fire )
|
|
{
|
|
//SAction에서 데미지 처리하고 있기 때문에 데미지 표시가 2번뜬다
|
|
switch( pSkillFX->nStage_Type_Id )
|
|
{
|
|
case SS_TYPE_001 :
|
|
case SS_TYPE_002 :
|
|
case SS_TYPE_101 :
|
|
case SS_TYPE_111 :
|
|
case SS_TYPE_121 :
|
|
case SS_TYPE_122 :
|
|
case SS_TYPE_123 : pSkill_Fire->SetDamegeInfo( &info );
|
|
break;
|
|
// AziaMafia SkillFix Animation
|
|
/*default:
|
|
pSkill_Fire->SetActionSkillEvent( &info );
|
|
break;*/
|
|
}
|
|
|
|
//돌고 있는 케스팅은 모두 강제 끝
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->ForceEnd();
|
|
|
|
if( pSkillFX->nCasting_Type_Id == 1 ) //마법류 스킬이면
|
|
{
|
|
//5번 타인에게 사용하는 해로운 스킬
|
|
pSkill_Fire->SetFireMotionID( 92 ); //나쁜 스킬 설정
|
|
|
|
//1번 소환/역소환 스킬이면
|
|
if( pSkillFX->nStage_Type_Id == SS_TYPE_001 || pSkillFX->nStage_Type_Id == SS_TYPE_002 )
|
|
pSkill_Fire->SetFireMotionID( 94 );
|
|
else if( pSkillFX->nStage_Type_Id == SS_TYPE_1001 ) //채광 관련
|
|
pSkill_Fire->SetFireMotionID( pSkillFX->nFire_Motion_Id );
|
|
else
|
|
{
|
|
SkillBaseEx * pSkill = GetSkillDB().GetSkillData( info.nSkillID );
|
|
if( pSkill )
|
|
{
|
|
//2번 자신에게만 주는 이로운 스킬
|
|
if( (pSkill->GetSkillTargetType() == 1 || pSkill->GetSkillTargetType() == 4 || pSkill->GetSkillTargetType() == 31 ) && info.hTarget == GetArID() )
|
|
{
|
|
pSkill_Fire->SetFireMotionID( 90 );
|
|
}
|
|
else
|
|
{
|
|
//3번 자신의 주변에 영향을 주는 스킬
|
|
if( info.hTarget == GetArID() )
|
|
pSkill_Fire->SetFireMotionID( 93 );
|
|
else
|
|
{
|
|
//4번 타인에게 사용하는 이로운 스킬
|
|
if( !pSkill->IsHarmful() )
|
|
pSkill_Fire->SetFireMotionID( 91 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else //전투 기술임
|
|
{
|
|
SetVisibleWeaponTrail( true );
|
|
}
|
|
|
|
if( pTarget )
|
|
pSkill_Fire->SetTarget( info.hTarget, pTarget );
|
|
|
|
pSkill_Fire->SetStartTime( m_dwTime );
|
|
pSkill_Fire->SetSkillMode( SNewSkill::SKILLMODE_FIRE );
|
|
m_vFireSkillList.push_back( pSkill_Fire );
|
|
}
|
|
else
|
|
{
|
|
if( pSkillFX->nStage_Type_Id != SS_TYPE_171 )
|
|
{
|
|
SAFE_DELETE( pSkillFX ); // 무조건 삭제. 이하 fx는 생성해서 사용하기로 한다.
|
|
return;
|
|
}
|
|
}
|
|
|
|
//RUSH, KNOCK_BACK, DAMAGE 처리
|
|
if( pSkillFX->nStage_Type_Id != SS_TYPE_171 ) return;
|
|
|
|
std::vector<SkillResult>::const_iterator it;
|
|
for( it = info.vSkillResult.begin(); it != info.vSkillResult.end(); it++ )
|
|
{
|
|
_SKILL_FX* ptSkillFX = new _SKILL_FX;
|
|
*ptSkillFX = *pSkillFXDB;
|
|
|
|
if( SkillResult::RUSH == (*it).GetType() )
|
|
{
|
|
if( (*it).rush.bResult )
|
|
{
|
|
SWorkRush_Shove* pRushShove = new SWorkRush_Shove( this, ptSkillFX, &info );
|
|
m_vFireSkillList.push_back( pRushShove );
|
|
return;
|
|
}
|
|
}
|
|
else if( SkillResult::DAMAGE_WITH_KNOCK_BACK == (*it).GetType() )
|
|
{
|
|
SWorkKnockBack* pWorkKnockBack = new SWorkKnockBack( this, ptSkillFX, &(*it) );
|
|
pWorkKnockBack->SetStartTime( m_dwTime );
|
|
m_vFireSkillList.push_back( pWorkKnockBack );
|
|
}
|
|
else if( SkillResult::DAMAGE == (*it).GetType() )
|
|
{
|
|
SChargeAttack* pChargerAttack = new SChargeAttack( this, ptSkillFX, &(*it) );
|
|
pChargerAttack->SetStartTime( m_dwTime );
|
|
m_vFireSkillList.push_back( pChargerAttack );
|
|
}
|
|
}
|
|
}
|
|
break; // 캐스팅
|
|
|
|
case SObjectState::STATE_SKILL_END :
|
|
{
|
|
//_oprint( "SKILL - SObjectState::STATE_SKILL_END\n" );
|
|
m_bIsUseSkill_complete = true;
|
|
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->ForceEnd();
|
|
|
|
// for( unsigned int i(0); m_vFireSkillList.size()>i; i++ )
|
|
// m_vFireSkillList[i]->ForceEnd();
|
|
|
|
break;
|
|
}
|
|
|
|
case SObjectState::STATE_THROW : Throw(); break; // 던지기
|
|
{
|
|
// _oprint( "상태 머신 : 던지기 상태 변경\n" );
|
|
|
|
break; // 서기
|
|
}
|
|
|
|
case SObjectState::STATE_SIT :
|
|
{
|
|
// _oprint( "상태 머신 : 앉기 상태 변경\n" );
|
|
SWorkAniSit * pSitSit = new SWorkAniSit( this, m_dwTime );
|
|
m_vAttackEventList.push_back( pSitSit );
|
|
break; // 앉기
|
|
}
|
|
case SObjectState::STATE_STAND_UP :
|
|
{
|
|
SWorkAniStandUp * pSitSit = new SWorkAniStandUp( this, m_dwTime );
|
|
m_vAttackEventList.push_back( pSitSit );
|
|
break; // 서기
|
|
}
|
|
case SObjectState::STATE_CAST_CANCEL :
|
|
{
|
|
//_oprint( "SKILL - SObjectState::STATE_CAST_CANCEL\n" );
|
|
m_bIsUseSkill_complete = true;
|
|
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; i++)
|
|
{
|
|
if( ( m_vAttackEventList[i]->GetWorkType() == SGameWork::WORK_ATTACKEX ||
|
|
m_vAttackEventList[i]->GetWorkType() == SGameWork::WORK_SHOOTINGBOW ) &&
|
|
!m_vAttackEventList[i]->ProcessingDamage() ) //데미지 처리가 아직 안됐다면
|
|
{
|
|
m_bWaitingAttackCancel = true;
|
|
}
|
|
else
|
|
m_vAttackEventList[i]->CastCancel();
|
|
}
|
|
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->CastCancel();
|
|
|
|
// for( unsigned int i(0); m_vFireSkillList.size()>i; i++ )
|
|
// m_vFireSkillList[i]->CastCancel();
|
|
|
|
if( !m_bWaitingAttackCancel )
|
|
{
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default( true );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SGamePlayer::MotionCancel()
|
|
{
|
|
if( m_vAttackEventList.empty() && m_vCastSkillList.empty() && m_vFireSkillList.empty() )
|
|
{
|
|
m_bIsUseSkill_complete = true;
|
|
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default();
|
|
|
|
return true;
|
|
}
|
|
|
|
//애니메이션 진행과 상관없이 히트 후 바로 캔슬 가능
|
|
/*
|
|
int nBoneCnt = 0;
|
|
DWORD dwMinTime = 0, dwMaxTime = 0;
|
|
DWORD dwCurAniTime = 0;
|
|
GetCurrentAnimationInfo( nBoneCnt, dwMinTime, dwMaxTime, dwCurAniTime );
|
|
dwMaxTime = dwMaxTime / 160;
|
|
dwCurAniTime = (dwCurAniTime / 160) * 4.8f;
|
|
|
|
float fPlayProgress = (dwCurAniTime / (float)dwMaxTime);
|
|
//80프로 애니메이션 진행되면 모션 캔슬 가능
|
|
if( fPlayProgress < 0.13f )
|
|
return;
|
|
*/
|
|
|
|
//데미지 처리 완료했는지 체크
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; i++)
|
|
{
|
|
if( !m_vAttackEventList[i]->ProcessingDamage() )
|
|
return false;
|
|
}
|
|
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
{
|
|
if( !m_vCastSkillList[i]->ProcessingDamage() )
|
|
return false;
|
|
}
|
|
|
|
for( unsigned int i(0); m_vFireSkillList.size()>i; i++ )
|
|
{
|
|
if( !m_vFireSkillList[i]->ProcessingDamage() )
|
|
return false;
|
|
}
|
|
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; i++)
|
|
m_vAttackEventList[i]->ForceEnd();
|
|
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->ForceEnd();
|
|
|
|
for( unsigned int i(0); m_vFireSkillList.size()>i; i++ )
|
|
m_vFireSkillList[i]->ForceEnd();
|
|
|
|
m_bIsUseSkill_complete = true;
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default();
|
|
|
|
return true;
|
|
}
|
|
|
|
//방향 설정
|
|
void SGamePlayer::SetViewVector( const K3DVector &tpos )
|
|
{
|
|
if( IsMount() || IsMountMode() ) return;
|
|
|
|
m_fTargetRoll = atan2( tpos.y-GetPosition()->y, tpos.x-GetPosition()->x );
|
|
m_dwPrevTime = m_dwTime;
|
|
m_bUseRot = true;
|
|
}
|
|
|
|
// sonador 1.8.13 아바타 IDLE 모션 동작 구현
|
|
void SGamePlayer::_processIdle()
|
|
{
|
|
if( GetCurrAnimationID() == ANI_IDLE )
|
|
{
|
|
if( !IsPlaying() )
|
|
NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
|
}
|
|
else if( GetCurrAnimationID() == ANI_DEFAULT01 )
|
|
{
|
|
int timeDiff = m_dwTime - m_dwIdleTime;
|
|
int rand = XFastRandom( 1, 10000000 );
|
|
if( rand < (int)timeDiff )
|
|
{
|
|
NPlayAnimation( ANI_IDLE, SEQTYPE_NORMAL );
|
|
_resetIdleTime();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SGamePlayer::Process( DWORD time, unsigned long uProcessBitVector )
|
|
{
|
|
if( m_bWaitingAttackCancel )
|
|
{
|
|
m_bWaitingAttackCancel = false;
|
|
for( unsigned int i(0); m_vAttackEventList.size()>i; ++i)
|
|
{
|
|
if( m_vAttackEventList[i]->GetWorkType() == SGameWork::WORK_ATTACKEX ||
|
|
m_vAttackEventList[i]->GetWorkType() == SGameWork::WORK_SHOOTINGBOW )
|
|
m_bWaitingAttackCancel = true;
|
|
}
|
|
|
|
if( !m_bWaitingAttackCancel )
|
|
{
|
|
if( m_vCastSkillList.empty() && m_vCastSkillList.empty() )
|
|
{
|
|
SetIng(false);
|
|
SetAniLock( false );
|
|
Default( true );
|
|
}
|
|
}
|
|
}
|
|
|
|
SGameAvatarEx::Process( time, uProcessBitVector );
|
|
|
|
_processIdle(); // sonador 1.8.13 아바타 IDLE 모션 동작 구현
|
|
|
|
if( !m_vCastSkillList.empty() )
|
|
CheckWorkDel( m_vCastSkillList );
|
|
|
|
if( !m_vFireSkillList.empty() )
|
|
CheckWorkDel( m_vFireSkillList );
|
|
|
|
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
|
|
m_vCastSkillList[i]->Process( m_dwTime );
|
|
|
|
for( unsigned int i(0); m_vFireSkillList.size()>i; i++ )
|
|
m_vFireSkillList[i]->Process( m_dwTime );
|
|
|
|
return true;
|
|
}
|
|
|
|
//플레이어만 탑승 가능
|
|
//크리처에 탑승한 상태냐
|
|
bool SGamePlayer::IsStateRide()
|
|
{
|
|
if( GetRiderCreatureObject() == NULL )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
SGameAvatarEx* SGamePlayer::GetRiderCreatureObject( bool bOnlyTransportCreature )
|
|
{
|
|
AR_HANDLE hCreature = m_RiderCreatureInfo.GetCreatureMountHandle();
|
|
if( hCreature != 0 )
|
|
{
|
|
if( bOnlyTransportCreature)
|
|
{
|
|
if( m_RiderCreatureInfo.IsTransportCreature() )
|
|
return (SGameAvatarEx*)GetGameTransportCreatureObject( hCreature );
|
|
else
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
if( m_RiderCreatureInfo.IsTransportCreature() )
|
|
{
|
|
return (SGameAvatarEx*)GetGameTransportCreatureObject( hCreature );
|
|
}
|
|
else
|
|
{
|
|
return (SGameAvatarEx*)GetGameObject( hCreature );
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//소환수에 의한 플레이어 프러스텀 체크
|
|
void SGamePlayer::AvatarClipTestByCreature( struct K3DVector *pFrustum )
|
|
{
|
|
SGameAvatarEx* pCreature = GetRiderCreatureObject();
|
|
if( !pCreature ) return;
|
|
|
|
K3DMatrix matPlayer = *GetTransform();
|
|
K3DMatrix matCreature = *pCreature->GetTransform();
|
|
K3DMatrix matTransform = matPlayer;
|
|
|
|
matTransform._41 = matCreature._41;
|
|
matTransform._42 = matCreature._42;
|
|
matTransform._43 = matCreature._43;
|
|
|
|
m_pSeqAvatar->SetTransform( matTransform );
|
|
m_pSeqAvatar->ClipTest( pFrustum );
|
|
m_pSeqAvatar->SetTransform( matPlayer );
|
|
}
|
|
|
|
//소환수에 의한 플레이어 회전
|
|
void SGamePlayer::AvatarRotationByCreature()
|
|
{
|
|
SGameAvatarEx* pCreature = GetRiderCreatureObject();
|
|
if( !pCreature ) return;
|
|
|
|
K3DMatrix mat, matResult;
|
|
mat = *GetTransform();
|
|
|
|
m_pSeqRideLink = pCreature->GetSaddleEffectPos();
|
|
if( m_pSeqRideLink )
|
|
{
|
|
K3DMatrix* pAttachMatrix = (K3DMatrix*)m_pSeqRideLink->GetAttachTransform();
|
|
K3DMatrix* pPointMatrix = (K3DMatrix*)&m_pSeqRideLink->GetPoint();
|
|
K3DMatrix* pMatCreature = pCreature->GetTransform();
|
|
if( pAttachMatrix && pPointMatrix && pMatCreature )
|
|
{
|
|
// sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
if( m_RiderCreatureInfo.GetRideType() == RIDE_LOW_TYPE || m_RiderCreatureInfo.GetRideType() == RIDE_HIGH_TYPE )
|
|
{
|
|
// 기존 탈것
|
|
K3DMatrixMultiply( matResult, *pAttachMatrix, *pMatCreature );
|
|
K3DMatrixMultiply( mat, *pPointMatrix, matResult );
|
|
}
|
|
else if( m_RiderCreatureInfo.GetRideType() == RIDE_UNICORN_TYPE)
|
|
{
|
|
|
|
K3DMatrixTranslation( matResult, pAttachMatrix->_41 + 0.001f, pAttachMatrix->_42 - 2.4f, pAttachMatrix->_43 + 3.1f );
|
|
K3DMatrixMultiply( mat, matResult, *pMatCreature );
|
|
}
|
|
else
|
|
{
|
|
// sonador
|
|
// 변경된 탈것
|
|
// 데이터 타입에 의해 코드가 영향을 받으면 안되지만 ... -_ㅜ
|
|
// RIDE_QILIN_TYPE & RIDE_WHITE_TYPE 은 아바타가 타야하는 위치가
|
|
// AttachMatrix 의 회전 행렬에 영향을 받으면 안된다.
|
|
// translation of [ Mp x Ma ] = Tp x Ra + Ta : Ra = I
|
|
// hence, Tp x I + Ta = Tp + Ta
|
|
K3DMatrixTranslation( matResult, pAttachMatrix->_41 + pPointMatrix->_41, pAttachMatrix->_42 + pPointMatrix->_42, pAttachMatrix->_43 + pPointMatrix->_43 );
|
|
//K3DMatrixTranslation( matResult, pAttachMatrix->_41, pAttachMatrix->_42, pAttachMatrix->_43);
|
|
//K3DMatrixTranslation( matResult, pPointMatrix->_41, pPointMatrix->_42, pPointMatrix->_43 );
|
|
K3DMatrixMultiply( mat, matResult, *pMatCreature );
|
|
}
|
|
//mat = *pMatCreature;
|
|
//mat._41 += pAttachMatrix->_41 - pPointMatrix->_41;
|
|
//mat._42 += pAttachMatrix->_42 - pPointMatrix->_42;
|
|
//mat._43 += pAttachMatrix->_43 - pPointMatrix->_43;
|
|
/*K3DMatrixTranslation( matResult, pAttachMatrix->_41 + pPointMatrix->_41, pAttachMatrix->_42 + pPointMatrix->_42, pAttachMatrix->_43 + pPointMatrix->_43 );
|
|
K3DMatrixMultiply( mat, matResult, *pMatCreature );*/
|
|
|
|
//mat = *pPointMatrix;
|
|
//mat._41 *= -1.f;
|
|
//mat._42 *= -1.f;
|
|
//mat._43 *= -1.f;
|
|
//K3DMatrixMultiply( matResult, mat, matResult );
|
|
|
|
//mat = *pMatCreature;
|
|
//mat._41 = matResult._41;
|
|
//mat._42 = matResult._42;
|
|
//mat._43 = matResult._43;
|
|
/*mat._41 = pos.x;
|
|
mat._42 = pos.y;
|
|
mat._43 = pos.z;*/
|
|
}
|
|
else if( pAttachMatrix && pMatCreature )
|
|
{
|
|
K3DMatrixMultiply( matResult, *pAttachMatrix, *pMatCreature );
|
|
mat = *pMatCreature;
|
|
mat._41 = matResult._41;
|
|
mat._42 = matResult._42;
|
|
mat._43 = matResult._43;
|
|
}
|
|
else if( pMatCreature )
|
|
{
|
|
mat = *pMatCreature;
|
|
}
|
|
|
|
m_fTargetRoll = pCreature->GetTargetRoll();
|
|
m_fPresentRoll = pCreature->GetPresentRoll();
|
|
|
|
K3DMatrix zRollMat;
|
|
if( pCreature->IsActivateTerrainDegree() )
|
|
{
|
|
float fAngleX = pCreature->GetCurAngleX();
|
|
float fAngleY = pCreature->GetCurAngleY();
|
|
K3DMatrixRotationYawPitchRoll( zRollMat, (fAngleX-3.1415926f/2), (fAngleY-3.1415926f/2), m_fPresentRoll + 3.1415926f/2 );
|
|
}
|
|
else
|
|
K3DMatrixRotationZ( zRollMat, m_fPresentRoll + 3.1415926f/2 );
|
|
|
|
m_vView = K3DVector( 0.0f, 1.0f, 0.0f );
|
|
K3DVectorTransform( m_vView, m_vView, zRollMat );
|
|
|
|
zRollMat._41 = mat._41;
|
|
zRollMat._42 = mat._42;
|
|
zRollMat._43 = mat._43;
|
|
|
|
mat = zRollMat;
|
|
SetTransform( mat );
|
|
}
|
|
|
|
m_pAddOnMgr->SetCreatureHandle( SGameAvatarAddOnMgr::SGAME_CIRCLE_SHADOW_FX, pCreature->GetArID() );
|
|
m_pAddOnMgr->SetCreatureHandle( SGameAvatarAddOnMgr::SGAME_FORCE_SPHERE_FX, pCreature->GetArID() );
|
|
}
|
|
|
|
void SGamePlayer::SetDefaultView()
|
|
{
|
|
m_dwPrevTime = m_dwTime;
|
|
m_bUseRot = true;
|
|
}
|
|
|
|
void SGamePlayer::CheatWhirlWindSkill( std::vector< AR_HANDLE > & vTargetList )
|
|
{
|
|
SWorkMultiAttack* pMultiAttack = new SWorkMultiAttack( this );
|
|
pMultiAttack->SetTargetList( vTargetList );
|
|
m_vFireSkillList.push_back( pMultiAttack );
|
|
}
|
|
|
|
void SGamePlayer::AddMeshPart( ANIPART nAniPart, MPART nMeshPart, const char* szMeshFileName )
|
|
{
|
|
if( m_pSeqAvatar && szMeshFileName )
|
|
m_pSeqAvatar->AddMesh( nAniPart, nMeshPart, szMeshFileName );
|
|
}
|
|
|
|
void SGamePlayer::AddDecoMeshPart( ANIPART nAniPart, MDECOPART nDecoMeshPart, const char* szMeshFileName )
|
|
{
|
|
if( m_pSeqAvatar && szMeshFileName )
|
|
m_pSeqAvatar->AddDecoMesh( nAniPart, nDecoMeshPart, szMeshFileName );
|
|
}
|
|
|
|
void SGamePlayer::AddAttachItemPart( ANIPART nAniPart, ATTACH nAttachPart, const char* szMeshFileName )
|
|
{
|
|
if( m_pSeqAvatar && szMeshFileName )
|
|
m_pSeqAvatar->AddAttachItem( nAniPart, nAttachPart, szMeshFileName );
|
|
}
|
|
|
|
// sonador #2.1.6 크리쳐 기린(spirit_qilin) 테스트
|
|
void SGamePlayer::SetRunNWalkAniSpeedDefault()
|
|
{
|
|
m_fPlayRate = DEFAULT_ANI_PLAY_RATE;
|
|
m_fStandardWalkPlayRate = DEFAULT_ANI_PLAY_RATE;
|
|
m_fStandardRunPlayRate = DEFAULT_ANI_PLAY_RATE;
|
|
m_fRdbScale = 1.0f;
|
|
m_fWalkSpeed = (float)DEF_SPEED;
|
|
}
|
|
|
|
void SGamePlayer::SetRunNWalkAniSpeedMount()
|
|
{
|
|
if( !m_pMsgHandler )
|
|
return;
|
|
|
|
SGameAvatarEx* Creature = 0;
|
|
|
|
//추가 : 탑승 유닛일 경우
|
|
// OnMount : 페킷을 받은 탈거인 경우 AddTransportCreature 함수를 통하여 탑승 전용 해쉬를 만들지만
|
|
// 탑승 가능 크리쳐인 경우는 그냥 오브젝트 해쉬에 집어 넣는다.
|
|
// 따라서 플레이어의 타기 애니메이션의 재생 시간이 적용되지 않아서 빠른속도로 애니메이션을
|
|
// 하고 있었다.
|
|
// 탑승 크리쳐 (대여용) 우선 검사후 애니메이션 속도룰 적용 하였다.
|
|
// 2009-11-20 : hunee
|
|
Creature = (SGameAvatarEx*)m_pMsgHandler->GetGameTransportCreatureObject( this->GetCreatureMountHandle() );
|
|
if( !Creature )
|
|
{
|
|
Creature = (SGameAvatarEx*)m_pMsgHandler->GetGameObject( this->GetCreatureMountHandle() );
|
|
if( !Creature )
|
|
return;
|
|
}
|
|
|
|
_SUMMON_INFO_FILE* SummonInfo = 0;
|
|
SummonInfo = GetCreatureDB().GetCreatureData( Creature->GetContentID() );
|
|
|
|
if( SummonInfo )
|
|
this->SetRunNWalkAniSpeed( SummonInfo );
|
|
}
|
|
|
|
void SGamePlayer::SetRunNWalkAniSpeed( _MONSTER_INFO_FILE* pMonsterInfo )
|
|
{
|
|
if( pMonsterInfo == NULL ) return;
|
|
|
|
m_fStandardWalkPlayRate = (float)pMonsterInfo->standard_walk_speed / 7.0f;
|
|
m_fStandardRunPlayRate = (float)pMonsterInfo->standard_run_speed / 7.0f;
|
|
m_fWalkSpeed = (float)((pMonsterInfo->standard_walk_speed + pMonsterInfo->standard_run_speed) / 2.0f) / 7.0f;
|
|
m_fRdbScale = GetScale();
|
|
}
|
|
|
|
void SGamePlayer::SetRunNWalkAniSpeed( _SUMMON_INFO_FILE* pSummonInfo )
|
|
{
|
|
if( pSummonInfo == NULL ) return;
|
|
|
|
m_fStandardWalkPlayRate = (float)pSummonInfo->standard_walk_speed / 7.0f;
|
|
m_fStandardRunPlayRate = (float)pSummonInfo->standard_run_speed / 7.0f;
|
|
m_fWalkSpeed = (float)((pSummonInfo->standard_walk_speed + pSummonInfo->standard_run_speed) / 2.0f) / 7.0f;
|
|
m_fRdbScale = pSummonInfo->scale;
|
|
}
|
|
|
|
void SGamePlayer::CalcCreatureRunPlayRate( float fSpeed )
|
|
{
|
|
m_fPlayRate = DEFAULT_ANI_PLAY_RATE * ( (fSpeed / m_fStandardRunPlayRate) / m_fRdbScale );
|
|
}
|
|
|
|
void SGamePlayer::CalcCreatureWalkPlayRate( float fSpeed )
|
|
{
|
|
m_fPlayRate = DEFAULT_ANI_PLAY_RATE * ( (fSpeed / m_fStandardWalkPlayRate) / m_fRdbScale );
|
|
}
|
|
|
|
// 2.1.16 변신 효과 중첩시 아바타 사라지는 오류 수정
|
|
void SGamePlayer::UnDisguise( unsigned int stateHandle )
|
|
{
|
|
if( SGameAvatarEx::IsLastDisguise() )
|
|
{
|
|
m_fPlayRate = DEFAULT_ANI_PLAY_RATE;
|
|
m_fStandardWalkPlayRate = DEFAULT_ANI_PLAY_RATE;
|
|
m_fStandardRunPlayRate = DEFAULT_ANI_PLAY_RATE;
|
|
m_fRdbScale = 1.0f;
|
|
m_fWalkSpeed = (float)DEF_SPEED;
|
|
}
|
|
|
|
SGameAvatarEx::UnDisguise( stateHandle );
|
|
|
|
//if( IsMountMode() ) // 2.1.15 변신시 모션 연결 적용
|
|
// HideWeapon( FALSE );
|
|
}
|
|
|
|
// sonador #2.1.6
|
|
int SGamePlayer::GetPlayerMDefAniID() const
|
|
{
|
|
switch( GetRideType() )
|
|
{
|
|
case RIDE_LOW_TYPE:
|
|
return ANI_M_DEFAULT01_LOW;
|
|
case RIDE_HIGH_TYPE:
|
|
return ANI_M_DEFAULT01_HIGH;
|
|
case RIDE_QILIN_TYPE:
|
|
return ANI_M_DEFAULT01_QILIN;
|
|
case RIDE_WHITE_TYPE:
|
|
return ANI_M_DEFAULT01_WHITE;
|
|
case RIDE_UNICORN_TYPE:
|
|
return ANI_M_DEFAULT01_UNICORN;
|
|
/// 2011.02.08 - prodongi
|
|
case RIDE_BEAKHO_TYPE:
|
|
return ANI_M_DEFAULT01_BEAKHO;
|
|
default:
|
|
return ANI_M_DEFAULT01_HIGH;
|
|
}
|
|
}
|
|
|
|
// sonador #2.1.6
|
|
int SGamePlayer::GetPlayerMWalkAniID() const
|
|
{
|
|
switch( GetRideType() )
|
|
{
|
|
case RIDE_QILIN_TYPE:
|
|
return ANI_M_WALK_QILIN;
|
|
case RIDE_WHITE_TYPE:
|
|
return ANI_M_WALK_WHITE;
|
|
case RIDE_UNICORN_TYPE:
|
|
return ANI_M_WALK_UNICORN;
|
|
/// 2011.02.08 - prodongi
|
|
case RIDE_BEAKHO_TYPE:
|
|
return ANI_M_WALK_BEAKHO;
|
|
default:
|
|
return ANI_M_WALK;;
|
|
}
|
|
}
|
|
|
|
// sonador #2.1.6
|
|
int SGamePlayer::GetPlayerMRunAniID() const
|
|
{
|
|
switch( GetRideType() )
|
|
{
|
|
case RIDE_LOW_TYPE:
|
|
return ANI_M_RUN_LOW;
|
|
case RIDE_HIGH_TYPE:
|
|
return ANI_M_RUN_HIGH;
|
|
case RIDE_QILIN_TYPE:
|
|
return ANI_M_RUN_QILIN;
|
|
case RIDE_WHITE_TYPE:
|
|
return ANI_M_RUN_WHITE;
|
|
case RIDE_UNICORN_TYPE:
|
|
return ANI_M_RUN_UNICORN;
|
|
/// 2011.02.08 - prodongi
|
|
case RIDE_BEAKHO_TYPE:
|
|
return ANI_M_RUN_BEAKHO;
|
|
default:
|
|
return ANI_M_RUN_HIGH;
|
|
}
|
|
}
|
|
|
|
|