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

484 lines
13 KiB
C++

#include "stdafx.h"
#include "SGameskilprop.h"
#include "KSeqModel.h"
#include "KRenderObjectMesh.h"
#include "SAction.h"
#include "SSkillDB.h"
#include "SMotionDB.h"
#include "SAvatarProperty.h"
#include "SSkillStageType.h"
#include "SGameUtil.h"
#include "kviewport.h"
#include "SSoundResourceDB.h"
#include "SDebug_Util.h"
extern float g_fEffectSpeed;
extern const char * pEP_Name[];
extern const char * pEffectAniKey[];
SSkilPropData::SSkilPropData()
{
m_pSkillProp = NULL;
m_vStartPos = K3DVector( 0.f, 0.f, 0.f );
m_vEndPos = K3DVector( 0.f, 0.f, 0.f );
m_bUse = true;
m_nStep = STEP_00;
m_pThrowFxSet = NULL;
m_pHitFxSet = NULL;
K3DMatrixIdentity( m_matMatrix );
m_nSoundId = -1;
m_bDelay = true;
}
SSkilPropData::~SSkilPropData()
{
SAFE_DELETE( m_pSkillProp );
}
void SSkilPropData::SetAnimationData( struct _SKILL_FX* pSkillFx, int nEffectType )
{
if( nEffectType == SS_TYPE_604 )
{
m_pThrowFxSet = GetMotionFxSetDB().GetFXSet( pSkillFx->fStage_Data[0] );
m_pHitFxSet = GetMotionFxSetDB().GetFXSet( pSkillFx->fStage_Data[5] );
if( m_pThrowFxSet && m_pHitFxSet )
{
NX3LoadPack loadpack;
loadpack.Init();
m_pSkillProp = new KSeqModel;
m_pSkillProp->AddAnimation( pEffectAniKey[0], GetResourceDB().GetEffectResourceName( m_pHitFxSet->graphic_effect_start_file_ID ), KNX3Manager::SEQTYPE_ALL, &loadpack);
m_pSkillProp->AddAnimation( pEffectAniKey[1], GetResourceDB().GetEffectResourceName( m_pThrowFxSet->graphic_effect_middle_file_ID ), KNX3Manager::SEQTYPE_ALL, &loadpack);
}
else
m_bUse = false;
}
else
{
m_pThrowFxSet = GetMotionFxSetDB().GetFXSet( pSkillFx->fStage_Data[0] );
if( m_pThrowFxSet )
{
NX3LoadPack loadpack;
loadpack.Init();
m_pSkillProp = new KSeqModel;
m_pSkillProp->AddAnimation( pEffectAniKey[0], GetResourceDB().GetEffectResourceName( m_pThrowFxSet->graphic_effect_start_file_ID ), KNX3Manager::SEQTYPE_ALL, &loadpack);
m_pSkillProp->AddAnimation( pEffectAniKey[1], GetResourceDB().GetEffectResourceName( m_pThrowFxSet->graphic_effect_middle_file_ID ), KNX3Manager::SEQTYPE_ALL, &loadpack);
m_pSkillProp->AddAnimation( pEffectAniKey[2], GetResourceDB().GetEffectResourceName( m_pThrowFxSet->graphic_effect_end_file_ID ), KNX3Manager::SEQTYPE_ALL, &loadpack);
}
else
m_bUse = false;
}
}
void SSkilPropData::PlaySoundFx( struct _MOTION_FX_SET* pFxSet, int nPlayStep, K3DVector* vPosition, SGameObject* pGameObject, AR_HANDLE hCaster )
{
if( m_nSoundId != -1 )
{
pGameObject->StopSound( m_strSoundName.c_str(), m_nSoundId );
m_nSoundId = -1;
m_strSoundName = "";
}
if( pFxSet )
{
SGameAvatarEx* pCaster = (SGameAvatarEx*)pGameObject->GetGameObject( hCaster );
if( nPlayStep == 0 && pFxSet->IsSound[nPlayStep] )
{
m_strSoundName = GetResourceDB().GetSoundResourceName( pFxSet->sound_start_file_ID );
m_nSoundId = pGameObject->StartSound( pCaster, m_strSoundName.c_str(), *vPosition, false, pFxSet->nSound_volumn, false, pFxSet->sound_option );
}
else if( nPlayStep == 1 && pFxSet->IsSound[nPlayStep] )
{
m_strSoundName = GetResourceDB().GetSoundResourceName( pFxSet->sound_middle_file_ID );
m_nSoundId = pGameObject->StartSound( pCaster, m_strSoundName.c_str(), *vPosition, false, pFxSet->nSound_volumn, true, pFxSet->sound_option );
}
else if( nPlayStep == 2 && pFxSet->IsSound[nPlayStep] )
{
m_strSoundName = GetResourceDB().GetSoundResourceName( pFxSet->sound_end_file_ID );
m_nSoundId = pGameObject->StartSound( pCaster, m_strSoundName.c_str(), *vPosition, false, pFxSet->nSound_volumn, false, pFxSet->sound_option );
}
}
}
SGameSkilProp::SGameSkilProp( int nSkillID )
{
m_pSkillPropData = NULL;
m_nSkillID = nSkillID;
m_nSkillPropType = TYPE_01;
m_nVisualFxCount = 0;
m_dwDelayTime = 0;
m_fSpeed = 0.f;
m_fAcc = 0.f;
m_dwOldTime = 0;
m_bHide = false;
m_bIsHideSkillProp = false;
m_hCaster = 0;
}
SGameSkilProp::~SGameSkilProp(void)
{
SAFE_DELETE(m_pProperty );
Destroy();
}
float SGameSkilProp::RandomNumber(float fMin, float fMax)
{
if (fMin == fMax) return(fMin);
float fRandom = (float)rand() / (float)RAND_MAX;
return((fRandom * (float)fabs(fMax-fMin))+fMin);
};
bool SGameSkilProp::Initialize( class K3DRenderDeviceDX *pDevice )
{
_SKILL_FX* pSkillFx = GetSkillStageDB().GetSkillStageData( m_nSkillID );
if( pSkillFx == NULL ) return false;
m_fSpeed = pSkillFx->fStage_Data[2];
m_fAcc = pSkillFx->fStage_Data[3];
if( pSkillFx->nStage_Type_Id == SS_TYPE_604 )
{
float fHitAniTime = 0.0f;
_MOTION_FX_SET* pHitMontionFxSet = GetMotionFxSetDB().GetFXSet( pSkillFx->fStage_Data[5] );
if( pHitMontionFxSet )
{
NX3LoadPack loadpack;
loadpack.Init();
_CID( GETMESH_ANIINFO );
KMsgGET_MESHANI_INFO msg;
msg.strFindName = GetResourceDB().GetEffectResourceName( pHitMontionFxSet->graphic_effect_start_file_ID );
KSeqModel* pHitSeqModel = new KSeqModel;
pHitSeqModel->AddAnimation( pEffectAniKey[0], msg.strFindName.c_str(), KNX3Manager::SEQTYPE_ALL, &loadpack);
pHitSeqModel->PlayAnimation( 0, pEffectAniKey[0] );
pHitSeqModel->Perform( id_GETMESH_ANIINFO, msg );
if( msg.nStart != -1 && msg.nEnd != -1 )
{
fHitAniTime = (float)( ( (msg.nEnd-msg.nStart) / 160 ) * 4.8f) / 100.0f;
}
SAFE_DELETE( pHitSeqModel );
}
float fLength = K3DVectorLength( K3DVector( 50.f, 150.f, 0.f ) );
float fTime = fLength / m_fSpeed;
float fAcc = fTime * m_fAcc;
fTime = ( fLength / (m_fSpeed + fAcc) ) + fHitAniTime;
m_nVisualFxCount = (int)(fTime / pSkillFx->fStage_Data[4]) + 1;
m_dwDelayTime = pSkillFx->fStage_Data[4] * 1000;
m_dwEndTime = ( fLength / (m_fSpeed + fAcc) ) * 1000.f;
m_nSkillPropType = TYPE_02;
}
else
{
m_nVisualFxCount = 1;
m_nSkillPropType = TYPE_01;
}
m_pSkillPropData = new SSkilPropData[m_nVisualFxCount];
for( unsigned short x = 0; x < m_nVisualFxCount; x++ )
{
m_pSkillPropData[x].SetAnimationData( pSkillFx, pSkillFx->nStage_Type_Id );
}
if( pSkillFx->fStage_Data[9] != 0 )
{
m_bIsHideSkillProp = true;
}
m_bIsInit = true;
return true;
}
void SGameSkilProp::Destroy()
{
SAFE_DELETE_ARRAY(m_pSkillPropData);
}
bool SGameSkilProp::Activate()
{
m_bIsActivated = true;
return true;
}
void SGameSkilProp::SetCasterHandle( AR_HANDLE handle )
{
m_hCaster = handle;
}
void SGameSkilProp::SetHideProp()
{
if( m_hCaster == 0 || !m_bIsHideSkillProp ) return;
if( IsPartyRaidMemeber( m_hCaster ) )
m_bHide = false; //파티 맴버면 렌더
else
m_bHide = true; //파티 맴버가 아니라면
}
bool SGameSkilProp::Deactivate()
{
//Leave메시지가 오면 바로 Deactivate를 해주면 안된다 Prop이 사라지는 효과가 끝난뒤 삭제
/* for( unsigned short visu = 0; visu < m_nVisualFxCount; visu++ )
m_pSkillPropData[visu].SetStep( SSkilPropData::STEP_02 );*/
SetReservation(true); //잠시 보류 시킨담에 Prop이 사라지는 효과가 끝난뒤 삭제
// m_bIsActivated = false;
return true;
}
bool SGameSkilProp::Render( unsigned long uRenderBitVector, KViewportObject** ppViewportList, int nViewportCount )
{
if( !m_bIsActivated ) return false;
if( m_bHide ) return true;
for(int vit = 0; vit < nViewportCount; ++vit)
{
if( (ppViewportList[vit]->GetAttributes() & KViewportObject::VIEWPORT_GAME) == 0)
continue;
for( unsigned short visu = 0; visu < m_nVisualFxCount; visu++ )
{
if( !m_pSkillPropData[visu].GetDelay() )
{
KSeqModel* pSeqModel = m_pSkillPropData[visu].GetSkillProp();
if( pSeqModel )
{
pSeqModel->Render( ppViewportList[vit] );
}
}
}
}
return true;
}
bool SGameSkilProp::Process( DWORD dwTime, unsigned long uProcessBitVector )
{
if( !m_bIsActivated ) return false;
if( m_nSkillPropType == TYPE_01 )
{
ProcessType01( dwTime );
}
else if( m_nSkillPropType == TYPE_02 )
{
ProcessType02( dwTime );
}
return true;
}
void SGameSkilProp::ProcessType01( DWORD dwTime )
{
K3DVector vPos = GetCurPosWithChangeDir();
GetHeight( vPos.x, vPos.y, vPos.z,m_wCurTile );
SetPosition( vPos );
bool bEnd = true;
for( unsigned short visu = 0; visu < m_nVisualFxCount; visu++ )
{
if( m_pSkillPropData[visu].GetUse() == false ) continue;
KSeqModel* pSeqModel = m_pSkillPropData[visu].GetSkillProp();
if( !pSeqModel ) continue;
bEnd = false;
pSeqModel->SetPosition( vPos );
m_pSkillPropData[visu].SetDelay( false );
switch( m_pSkillPropData[visu].GetStep() )
{
case SSkilPropData::STEP_00:
{
pSeqModel->PlayAnimation( dwTime, pEffectAniKey[0] );
m_pSkillPropData[visu].PlaySoundFx( m_pSkillPropData[visu].GetThrowFxSet(), 0, &vPos, this, m_hCaster );
m_pSkillPropData[visu].SetStep( SSkilPropData::STEP_01 );
}
break;
case SSkilPropData::STEP_01:
{
if( !pSeqModel->IsPlaying() )
{
pSeqModel->PlayAnimation( dwTime, pEffectAniKey[1], SEQTYPE_LOOP );
m_pSkillPropData[visu].PlaySoundFx( m_pSkillPropData[visu].GetThrowFxSet(), 1, &vPos, this, m_hCaster );
m_pSkillPropData[visu].SetStep( SSkilPropData::STEP_02 );
}
}
break;
case SSkilPropData::STEP_02:
{
if( IsReservation() )
{
pSeqModel->PlayAnimation( dwTime, pEffectAniKey[2] );
m_pSkillPropData[visu].PlaySoundFx( m_pSkillPropData[visu].GetThrowFxSet(), 2, &vPos, this, m_hCaster );
m_pSkillPropData[visu].SetStep( SSkilPropData::STEP_03 );
}
}
break;
case SSkilPropData::STEP_03:
{
if( !pSeqModel->IsPlaying() )
{
m_pSkillPropData[visu].PlaySoundFx( NULL, 0, NULL, this, m_hCaster );
m_pSkillPropData[visu].SetUse( false );
}
}
break;
}
pSeqModel->Process(dwTime);
}
if( IsReservation() && bEnd )
{
m_bIsActivated = false;
SetReservation(false);
}
}
void SGameSkilProp::ProcessType02( DWORD dwTime )
{
K3DVector vPos = GetCurPosWithChangeDir();
GetHeight( vPos.x, vPos.y, vPos.z,m_wCurTile );
SetPosition( vPos );
bool bEnd = true;
for( unsigned short visu = 0; visu < m_nVisualFxCount; ++visu )
{
SSkilPropData* pSkillProp = &m_pSkillPropData[visu];
if( pSkillProp->GetUse() == false ) continue;
KSeqModel* pSeqModel = pSkillProp->GetSkillProp();
if( !pSeqModel ) continue;
bEnd = false;
K3DMatrix* pMatrix = pSkillProp->GetMatrix();
K3DVector* vStartPos = pSkillProp->GetStartPosition();
K3DVector* vEndPos = pSkillProp->GetEndPosition();
int nStep = pSkillProp->GetStep();
if(nStep == SSkilPropData::STEP_00)
{
if( (dwTime - m_dwOldTime) > m_dwDelayTime )
m_dwOldTime = dwTime;
else
{
continue;
}
pSkillProp->SetDelay( false );
//랜덤 위치 만들기
vStartPos->x = RandomNumber( -20.f, 20.f );
vStartPos->y = RandomNumber( -20.f, 20.f );
vStartPos->z = 0.0f;
*vEndPos = *vStartPos;
//실제 위치와 랜덤 위치 더하기
*vStartPos = vPos + (*vStartPos);
*vEndPos = vPos + (*vEndPos);
//지형 높이 값 구하기
GetHeight( vEndPos->x, vEndPos->y, vEndPos->z,m_wCurTile );
vStartPos->z = vEndPos->z;
vStartPos->x += 50.0f;
vStartPos->z += 150.0f;
//시작 위치 적용
GetDirection( *pMatrix, *vStartPos, *vEndPos );
pMatrix->SetPosVector( *vStartPos );
//속도 구하기
// m_fSpeed = K3DVectorLength( &( (*vStartPos) - (*vEndPos) ) );
// m_fSpeed = ( m_fSpeed / GameRule::DEFAULT_UNIT_SIZE ) * 70.f;
pSkillProp->SetTime( dwTime );
pSeqModel->Initialize();
pSeqModel->PlayAnimation( dwTime, pEffectAniKey[1], SEQTYPE_LOOP );
pSeqModel->ReSet();
pSkillProp->PlaySoundFx( pSkillProp->GetThrowFxSet(), 1, &K3DVector( pMatrix->_41, pMatrix->_42, pMatrix->_43 ), this, m_hCaster );
pSkillProp->SetStep( SSkilPropData::STEP_01 );
}
else if(nStep == SSkilPropData::STEP_01)
{
K3DVector vTemp;
K3DVectorLerp( vTemp, *vStartPos, *vEndPos, (float)(dwTime - pSkillProp->GetTime()) / m_dwEndTime );
if( (float)(dwTime - pSkillProp->GetTime()) > m_dwEndTime )
{
K3DMatrixIdentity( *pMatrix );
pMatrix->SetPosVector( *vEndPos );
pSeqModel->Initialize();
pSeqModel->PlayAnimation( dwTime, pEffectAniKey[0] );
pSeqModel->ReSet();
pSkillProp->PlaySoundFx( pSkillProp->GetHitFxSet(), 0, &K3DVector( pMatrix->_41, pMatrix->_42, pMatrix->_43 ), this, m_hCaster );
pSkillProp->SetStep( SSkilPropData::STEP_02 );
}
else
pMatrix->SetPosVector( vTemp );
}
else if(nStep == SSkilPropData::STEP_02)
{
pMatrix->SetPosVector( *vEndPos );
if( !pSeqModel->IsPlaying() )
{
pSkillProp->SetDelay( true );
//보류중이 풀렸다면
if( IsReservation() )
{
pSkillProp->PlaySoundFx( NULL, 0, NULL, this, m_hCaster );
pSkillProp->SetUse( false );
}
else
{
pSkillProp->SetStep( SSkilPropData::STEP_00 );
}
}
}
pSeqModel->SetTransform( *pMatrix );
pSeqModel->Process( dwTime );
}
if( IsReservation() && bEnd )
{
m_bIsActivated = false;
SetReservation(false);
}
}
void SGameSkilProp::SetDelete( bool bDelete )
{
m_bDelete = bDelete;
}