Files
2026-06-01 12:46:52 +02:00

458 lines
11 KiB
C++

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