#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; }