Files
Leviathan/Client/Game/game/Player/SGamePet.cpp
T
2026-06-01 12:46:52 +02:00

279 lines
6.8 KiB
C++

#include "stdafx.h"
// sonador 10.2.1 팻 시스템 구현
#include "SGamePet.h"
#include "KSeqAvatarEx.h"
#include "SCreatureDB.h"
#include "SSkillDB.h"
//#include "Util.h"
#include "SGameAniType.h"
#include "SGameWork.h"
#include "SGameMessage.h"
#include "SSkillStageType.h"
#include "SGameUtil.h"
#include "SMonsterDB.h"
#include "SPetDB.h"
#include "SAvatarProperty.h"
#include "SDebug_Util.h"
SGamePet::SGamePet( ENC_INT nPetID )
: SGameAvatarEx ( nPetID )
, m_pMasterPlayer ( 0 )
, m_hMasterHandle ( 0 )
, m_bIsUseSkill_complete ( true )
, m_fRdbScale ( 1.0f )
, m_fWalkSpeed ( DEF_SPEED )
, m_fPlayRate ( DEFAULT_ANI_PLAY_RATE )
, m_fStandardWalkPlayRate ( 6 ) //DEFAULT_ANI_PLAY_RATE )
, m_fStandardRunPlayRate ( 11 ) //DEFAULT_ANI_PLAY_RATE )
, m_dwIdleTime ( 0 )
, m_fObjSize ( 1 )
{
// TODO: rearrange speed and scale factors when the manager of pet's database is ready
SPetInfoEx PetInfo = GetPetDB().Find( nPetID );
m_fRdbScale = PetInfo.getScale();
//m_fStandardWalkPlayRate = (float)PetInfo.getStandardWalkSpeed() / 7.0f;
//m_fStandardRunPlayRate = (float)PetInfo.getStandardRunSpeed() / 7.0f;
//m_fWalkSpeed = (float)( ( PetInfo.getStandardWalkSpeed() + PetInfo.getStandardRunSpeed() ) / 2.0f ) / 7.0f;
SetScale( PetInfo.getScale() );
m_fObjSize = PetInfo.getSize();
}
SGamePet::~SGamePet()
{
}
void SGamePet::_processIdle() // sonador 1.8.13 아바타 IDLE 모션 동작 구현
{
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 SGamePet::Process( DWORD time, unsigned long procBitSet )
{
SGameAvatarEx::Process( time, procBitSet );
_processIdle(); // sonador 1.8.13 아바타 IDLE 모션 동작 구현
// TODO: there is no need to process events of pet, 'cause pet doesn't damage, be damaged, cast skill and fire skill
return true;
}
void SGamePet::OnChangeState( SObjectState::ID stateID, const SStateInfo& info )
{
if( 0 == m_pStateVM )
return;
switch( stateID )
{
case SObjectState::STATE_IDLE:
{
if( GetCurrAnimationID() == ANI_RUN || GetCurrAnimationID() == ANI_WALK )
Default();
}
break;
case SObjectState::STATE_MOVE:
{
SetAniLock( false );
if( info.dwSpeed < m_fWalkSpeed )
{
SetWalkPlayRateBy( info.dwSpeed );
Walk( true );
}
else
{
SetRunPlayRateBy( info.dwSpeed );
Run();
}
}
break;
// sonador #2.1.2.4.3 팻 조작 UI 연동
case SObjectState::STATE_CHASE :
{
SetAniLock( false );
if( info.dwSpeed < m_fWalkSpeed )
{
SetWalkPlayRateBy( info.dwSpeed );
Walk( true );
}
else
{
SetRunPlayRateBy( info.dwSpeed );
Run();
}
}
break; // 추격
case SObjectState::STATE_FIRE:
{
if( info.vSkillResult.empty() )
{
m_bIsUseSkill_complete = true;
for( unsigned int i( 0 ); i < m_vCastSkillList.size(); ++i )
m_vCastSkillList[ i ]->ForceEnd();
SetAniLock( false );
Default();
return;
}
_SKILL_FX* SkillFxFromDB = GetSkillStageDB().GetSkillStageData( info.nSkillID );
if( !SkillFxFromDB )
{
_oprint( "스킬 연출 데이타 없음!!! [스킬ID:%d]\n", info.nSkillID );
return;
}
_SKILL_FX* SkillFx = new _SKILL_FX;
*SkillFx = *SkillFxFromDB;
SNewSkill* FireWork = 0;
SGameAvatarEx* TargetAvatar = 0;
// find fire work
//switch( SkillFx->nStage_Type_Id )
//{
// // TODO: 팻 스킬 Fire 시 연출 선택
//default:
// {
// _oprint( "구현 보류 중인 스킬입니다.기획팀에 사용 여부를 확인 후, 프로그램 팀에 구현 여부를 확인 바랍니다.\n" );
// SAFE_DELETE( FireWork );
// return;
// }
// break;
//}
assert("구현 보류 중인 스킬입니다.기획팀에 사용 여부를 확인 후, 프로그램 팀에 구현 여부를 확인 바랍니다." && false);
// find target avatar
if( info.hTarget )
TargetAvatar = static_cast< SGameAvatarEx* >( this->GetGameObject( info.hTarget ) );
if( FireWork )
{
if( TargetAvatar )
FireWork->SetTarget( info.hTarget, TargetAvatar );
FireWork->SetStartTime( m_dwTime );
FireWork->SetSkillMode( SNewSkill::SKILLMODE_FIRE );
m_vFireSkillList.push_back( FireWork );
}
else
{
SAFE_DELETE( FireWork );
return;
}
}
break;
case SObjectState::STATE_SKILL_END:
{
m_bIsUseSkill_complete = true;
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
m_vCastSkillList[i]->ForceEnd();
}
break;
case SObjectState::STATE_CAST_CANCEL :
{
m_bIsUseSkill_complete = true;
for( unsigned int i(0); m_vCastSkillList.size()>i; i++ )
m_vCastSkillList[i]->ForceEnd();
Default();
}
break;
default:
break;
}
}
void SGamePet::OnNetInput( struct SGameMessage* msg )
{
if( m_pStateVM )
m_pStateVM->OnNetInput( msg );
}
void SGamePet::Default( bool force )
{
_resetIdleTime(); // sonador 1.8.13 아바타 IDLE 모션 동작 구현
if( GetCurrAnimationID() != ANI_DEFAULT01 )
NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
}
void SGamePet::Walk( bool loop )
{
if( GetCurrAnimationID() != ANI_WALK || m_fCurPlayRate != m_fPlayRate )
NPlayAnimation( ANI_WALK, SEQTYPE_LOOP, m_fPlayRate );
}
void SGamePet::Run( bool autorun, int aniType )
{
if( GetCurrAnimationID() != aniType || m_fCurPlayRate != m_fPlayRate )
NPlayAnimation( aniType, SEQTYPE_LOOP, m_fPlayRate );
}
bool SGamePet::MotionCancel()
{
// TODO: there is no need to check events of pet, 'cause pet doesn't damage, be damaged, cast skill and fire skill
m_bIsUseSkill_complete = true;
SetIng(false);
SetAniLock( false );
Default();
return true;
}
void SGamePet::SetViewVectorStateIdle( const K3DVector& position )
{
float fTargetRoll = atan2( position.y, position.x );
if( fTargetRoll != m_fTargetRoll )
{
m_fTargetRoll = atan2( position.y, position.x );
m_dwPrevTime = m_dwTime;
m_bUseRot = true;
StandingDegree();
}
}
void SGamePet::SetMaster( AR_HANDLE handle, SGameAvatarEx* master )
{
m_pMasterPlayer = master;
m_hMasterHandle = handle;
}
void SGamePet::SetWalkPlayRateBy( float speed )
{
m_fPlayRate = DEFAULT_ANI_PLAY_RATE * ( ( speed / m_fStandardWalkPlayRate) / m_fRdbScale );
}
void SGamePet::SetRunPlayRateBy( float speed )
{
m_fPlayRate = DEFAULT_ANI_PLAY_RATE * ( ( speed / m_fStandardRunPlayRate) / m_fRdbScale );
}
void SGamePet::RefreshTextureGroup( vec_cobset* pCobSet )
{
if ( pCobSet == NULL || m_pSeqAvatar == NULL || pCobSet->empty() ) return;
assert( GetInnObjType() == TS_ENTER::GAME_MOB );
int texture_group_index = GetPetDB().Find( GetInnContentID() ).getTextureGroupIndex();
_RefreshTextureGroup( texture_group_index, pCobSet );
}
AR_UNIT SGamePet::GetSize()
{
return m_fObjSize;
}