#include "stdafx.h" #include "SGameSkillFx.h" #include "SGameObject.h" #include "SGameViewPort.h" #include "KResourceManager.h" #include "KRenderObject.h" #include "SkillBase.h" SGameSkillFx::SGameSkillFx() : m_pGameObject( NULL ), m_pPrimitive( NULL ), m_nVertexSize( 0 ), m_spTexture( NULL ), m_bEnd( false ) { K3DMatrixIdentity( m_matRoot ); K3DMatrixIdentity( m_matBillborad ); } SGameSkillFx::~SGameSkillFx() { SAFE_DELETE_ARRAY( m_pPrimitive ); } void SGameSkillFx::SetVertex( void* pVertex ) { m_pPrimitive = pVertex; } void SGameSkillFx::SetVertexSize( int nVertexSize ) { m_nVertexSize = nVertexSize; } void SGameSkillFx::SetTexture( K3DTexture *pTexture ) { m_spTexture = pTexture; } void SGameSkillFx::SetBillboardMatrix( K3DMatrix matBillboard ) { m_matBillborad = matBillboard; } //라이트닝 SGameLightningFx::SGameLightningFx() : m_pLightningPrimitive( new SGameLightningPrimitive ), m_fMeter(1.0f), m_nFrameCnt(0), m_nLength(0), m_fSpeed(0.0f) { } SGameLightningFx::~SGameLightningFx() { m_vLinkInfo.clear(); SAFE_DELETE( m_pLightningPrimitive ); } void SGameLightningFx::Init( SGameObject* pCaster, AR_HANDLE hCaster, std::vector< struct SkillResult > & vTargetList ) { m_pGameObject = pCaster; std::vector< SkillResult >::iterator iter = vTargetList.begin(); if( iter != vTargetList.end() ) { LinkInfo link( hCaster, (*iter).GetTargetHandle(), true ); m_vLinkInfo.push_back( link ); } for( ; iter != vTargetList.end(); ++iter ) { if( iter + 1 != vTargetList.end() ) { SkillResult & pReulst = *(iter + 1); LinkInfo link( (*iter).GetTargetHandle(), pReulst.GetTargetHandle() ); m_vLinkInfo.push_back( link ); } } if( m_vLinkInfo.empty() ) { m_bEnd = true; return; } NX3LoadPack loadpack; loadpack.Init(); //d001_dun_d001_p_magicalpowers3.dds //rcfx_ch_standard_lvup_lv02.dds //rcfx_ch_standard_black_02.dds K3DTexture* pTexTure = KTextureManager::GetManager()->GetTexture( "rcfx_ch_standard_lvup_lv02.dds", &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); m_fMeter = 10.0f; //유효 거리 m_nLength = 2; m_nFrameCnt = m_fMeter*m_nLength; m_fSpeed = 500.0f; m_pVertex = new K3DUNLITVERTEX[(m_nFrameCnt*2)*(int)m_vLinkInfo.size()]; m_pLightningPrimitive->SetVertex( m_pVertex ); m_pLightningPrimitive->SetTexture( pTexTure ); m_pLightningPrimitive->SetTransparent( true ); m_pLightningPrimitive->SetBlendMode( K3DMaterial::MBM_ADDITIVE ); m_pLightningPrimitive->SetRootMat( &m_matRoot ); } void SGameLightningFx::Process( DWORD dwTime ) { m_nVertexSize = 0; if( m_vLinkInfo.empty() ) m_bEnd = true; if( m_bEnd ) return; std::vector< LinkInfo >::iterator iter = m_vLinkInfo.begin(); for( ; iter != m_vLinkInfo.end(); ) { LinkInfo & link = (*iter); SGameObject* pStart = m_pGameObject->GetGameObject( link.hStart ); SGameObject* pEnd = m_pGameObject->GetGameObject( link.hEnd ); if( pStart && pEnd ) { if( link.bStartHealingWave ) { if( link.dwOldTime == 0 ) link.dwOldTime = dwTime; else StartLightning( pStart, pEnd, dwTime, link ); } else if( link.bEndHealingWave ) { if( iter + 1 != m_vLinkInfo.end() ) { LinkInfo & nextlink = *(iter + 1); if( nextlink.bStartHealingWave == false && nextlink.bEndHealingWave == false ) nextlink.bStartHealingWave = true; } if( EndLightning( pStart, pEnd, dwTime, link ) ) { iter = m_vLinkInfo.erase( iter ); continue; } } m_nVertexSize += link.nVertexSize; ++iter; } else { iter = m_vLinkInfo.erase( iter ); } } } void SGameLightningFx::Render( KViewportObject *viewport ) { if( m_bEnd ) return; if( m_nVertexSize > 1 ) { K3DMatrix matTransPos; K3DMatrixIdentity( m_matBillborad ); K3DMatrixTranspose( matTransPos, *viewport->GetViewMatrix() ); m_matBillborad._11 = matTransPos._11; m_matBillborad._12 = matTransPos._12; m_matBillborad._13 = matTransPos._13; m_matBillborad._21 = matTransPos._21; m_matBillborad._22 = matTransPos._22; m_matBillborad._23 = matTransPos._23; // m_matBillborad._31 = matTransPos._31; // m_matBillborad._32 = matTransPos._32; // m_matBillborad._33 = matTransPos._33; m_pLightningPrimitive->SetBillboardMatrix(m_matBillborad); m_pLightningPrimitive->SetVertexSize( m_nVertexSize ); viewport->Register( m_pLightningPrimitive, KRenderObject::RENDEREFX_NONE ); } } void SGameLightningFx::StartLightning( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link ) { K3DVector vStart = *pStart->GetPosition(); K3DVector vEnd = *pEnd->GetPosition(); link.nVertexSize = 0; float fLength = K3DVectorLength( vEnd - vStart ); float fTime = (fLength / m_fSpeed) * 1000.f; K3DVectorLerp( link.vHeadPosition, vStart, vEnd, (float)(dwTime - link.dwOldTime) / fTime ); if( (float)(dwTime - link.dwOldTime) < fTime ) { int nMeter = (int)(K3DVectorLength( link.vHeadPosition - vStart ) / m_fMeter); nMeter *= m_nLength; if( nMeter > m_nFrameCnt ) nMeter = m_nFrameCnt; int nVertexSize = m_nVertexSize*2; for( int x = 0; x < nMeter; ++x ) { K3DVector vOut; K3DVectorLerp( vOut, vStart, link.vHeadPosition, (float)x / nMeter ); vOut.z += 10.0f; m_pVertex[nVertexSize+(link.nVertexSize*2)].pos = vOut; m_pVertex[nVertexSize+(link.nVertexSize*2+1)].pos = vOut; ++link.nVertexSize; } } else { link.bStartHealingWave = false; link.bEndHealingWave = true; EndLightning( pStart, pEnd, dwTime, link ); } } bool SGameLightningFx::EndLightning( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link ) { K3DVector vStart = *pStart->GetPosition(); K3DVector vEnd = *pEnd->GetPosition(); link.nVertexSize = 0; int nMeter = (int)(K3DVectorLength( vEnd - vStart ) / m_fMeter); nMeter *= m_nLength; if( nMeter > m_nFrameCnt ) nMeter = m_nFrameCnt; int nVertexSize = m_nVertexSize*2; for( int x = 0; x < nMeter; ++x ) { K3DVector vOut; K3DVectorLerp( vOut, vStart, vEnd, (float)x / nMeter ); vOut.z += 10.0f; m_pVertex[nVertexSize+(link.nVertexSize*2)].pos = vOut; m_pVertex[nVertexSize+(link.nVertexSize*2+1)].pos = vOut; ++link.nVertexSize; } return false; } //힐링 웨이브 SGameHealingWaveFx::SGameHealingWaveFx() : m_pHealingWavePrimitive( new SGameHealingWavePrimitive ), m_fMeter(1.0f), m_nFrameCnt(0), m_nLength(0), m_fSpeed(0.0f) { } SGameHealingWaveFx::~SGameHealingWaveFx() { m_vLinkInfo.clear(); SAFE_DELETE( m_pHealingWavePrimitive ); } void SGameHealingWaveFx::Init( SGameObject* pCaster, AR_HANDLE hCaster, std::vector< struct SkillResult > & vTargetList ) { m_pGameObject = pCaster; std::vector< SkillResult >::iterator iter = vTargetList.begin(); if( iter != vTargetList.end() ) { LinkInfo link( hCaster, (*iter).GetTargetHandle(), true ); m_vLinkInfo.push_back( link ); } for( ; iter != vTargetList.end(); ++iter ) { if( iter + 1 != vTargetList.end() ) { SkillResult & pReulst = *(iter + 1); LinkInfo link( (*iter).GetTargetHandle(), pReulst.GetTargetHandle() ); m_vLinkInfo.push_back( link ); } } if( m_vLinkInfo.empty() ) { m_bEnd = true; return; } NX3LoadPack loadpack; loadpack.Init(); //rcfx_ch_skill_lightning01_lv01.dds //rcfx_ch_standard_lvup_lv02.dds K3DTexture* pTexTure = KTextureManager::GetManager()->GetTexture( "rcfx_ch_standard_lvup_lv02.dds", &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); m_fMeter = 12.0f; //유효 거리 m_nLength = 4; m_nFrameCnt = m_fMeter*m_nLength; m_fSpeed = 150.0f; m_pVertex = new K3DUNLITVERTEX[(m_nFrameCnt*2)*(int)m_vLinkInfo.size()]; m_pHealingWavePrimitive->SetVertex( m_pVertex ); m_pHealingWavePrimitive->SetTexture( pTexTure ); m_pHealingWavePrimitive->SetTransparent( true ); m_pHealingWavePrimitive->SetBlendMode( K3DMaterial::MBM_ADDITIVE ); m_pHealingWavePrimitive->SetRootMat( &m_matRoot ); } void SGameHealingWaveFx::Process( DWORD dwTime ) { m_nVertexSize = 0; if( m_vLinkInfo.empty() ) m_bEnd = true; if( m_bEnd ) return; std::vector< LinkInfo >::iterator iter = m_vLinkInfo.begin(); for( ; iter != m_vLinkInfo.end(); ) { LinkInfo & link = (*iter); SGameObject* pStart = m_pGameObject->GetGameObject( link.hStart ); SGameObject* pEnd = m_pGameObject->GetGameObject( link.hEnd ); if( pStart && pEnd ) { if( link.bStartHealingWave ) { if( link.dwOldTime == 0 ) link.dwOldTime = dwTime; else StartHealingWave( pStart, pEnd, dwTime, link ); } else if( link.bEndHealingWave ) { if( iter + 1 != m_vLinkInfo.end() ) { LinkInfo & nextlink = *(iter + 1); if( nextlink.bStartHealingWave == false && nextlink.bEndHealingWave == false ) nextlink.bStartHealingWave = true; } if( EndHealingWave( pStart, pEnd, dwTime, link ) ) { iter = m_vLinkInfo.erase( iter ); continue; } } m_nVertexSize += link.nVertexSize; ++iter; } else { iter = m_vLinkInfo.erase( iter ); } } } void SGameHealingWaveFx::StartHealingWave( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link ) { K3DVector vStart = *pStart->GetPosition(); K3DVector vEnd = *pEnd->GetPosition(); link.nVertexSize = 0; float fLength = K3DVectorLength( vEnd - vStart ); float fTime = (fLength / m_fSpeed) * 1000.f; K3DVectorLerp( link.vHeadPosition, vStart, vEnd, (float)(dwTime - link.dwOldTime) / fTime ); if( (float)(dwTime - link.dwOldTime) < fTime ) { int nMeter = (int)(K3DVectorLength( link.vHeadPosition - vStart ) / m_fMeter); nMeter *= m_nLength; if( nMeter > m_nFrameCnt ) nMeter = m_nFrameCnt; float fCos = 0.0f; int nVertexSize = m_nVertexSize*2; for( int x = 0; x < nMeter; ++x ) { K3DVector vOut; K3DVectorLerp( vOut, vStart, link.vHeadPosition, (float)x / nMeter ); vOut.z += 10.0f; m_pVertex[nVertexSize+(link.nVertexSize*2)].pos = vOut; m_pVertex[nVertexSize+(link.nVertexSize*2+1)].pos = vOut; ++link.nVertexSize; } } else { link.bStartHealingWave = false; link.bEndHealingWave = true; EndHealingWave( pStart, pEnd, dwTime, link ); } } bool SGameHealingWaveFx::EndHealingWave( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link ) { K3DVector vStart = *pStart->GetPosition(); K3DVector vEnd = *pEnd->GetPosition(); float fLength = K3DVectorLength( vEnd - vStart ); float fTime = (fLength / m_fSpeed) * 1000.f; link.nVertexSize = 0; int nMeter = (int)(K3DVectorLength( vEnd - vStart ) / m_fMeter); nMeter *= m_nLength; if( nMeter > m_nFrameCnt ) nMeter = m_nFrameCnt; int nVertexSize = m_nVertexSize*2; for( int x = 0; x < nMeter; ++x ) { K3DVector vOut; K3DVectorLerp( vOut, vStart, vEnd, (float)x / nMeter ); vOut.z += 10.0f; m_pVertex[nVertexSize+(link.nVertexSize*2)].pos = vOut; m_pVertex[nVertexSize+(link.nVertexSize*2+1)].pos = vOut; ++link.nVertexSize; } return false; } void SGameHealingWaveFx::Render( KViewportObject *viewport ) { if( m_bEnd ) return; if( m_nVertexSize > 1 ) { m_pHealingWavePrimitive->SetVertexSize(m_nVertexSize); viewport->Register(m_pHealingWavePrimitive, KRenderObject::RENDEREFX_NONE); } }