#include "SunClientPrecompiledHeader.h" #include "ProjectileEffect.h" #include "GlobalFunc.h" #include "GameFunc.h" #include "ResourceManager.h" namespace nProjectileFunc { void GetProjectileBlendColor( float TotalLifeTimeRate, OUT WzColor& Color ) { if( TotalLifeTimeRate < 0.5f ) { // ÆäÀÌµå¾Æ¿ôÀÌ È°¼ºÈ­ µÇ¾îÀÖ´Â °æ¿ì¿¡´Â ±âÁ¸¿¡ ¼³Á¤µÈ Ä÷¯´Â ¹«½ÃµÊ return; //Color = 0xFFFFFFFF; } else { float fRate = (1.0f - TotalLifeTimeRate) * 2.0f; // 0~1 if( fRate < 0.0f ) fRate = 0.0f; if( fRate > 1.0f ) fRate = 1.0f; BYTE Alpha = (BYTE)(255 * fRate); Color = WzColor_ChangeAlpha(Color, Alpha); } } }; cProjectileEffect::cProjectileEffect() : m_EffectID(0) , m_hEffect(INVALID_HANDLE_VALUE) , m_Actived(FALSE) , m_ActiveDelayTime(0) , m_EffectScale(c_UnitVector) , m_StaticRotate(FALSE) , m_EffectRotate(c_ZeroVector) , m_FadeOut(FALSE) { } BOOL cProjectileEffect::CreateEffect( WzID EffectID, DWORD CasterObjectKey, DWORD TargetObjectKey ) { m_StartedTime = GetCurrentTime(); m_EffectID = EffectID; m_CasterObjectKey = CasterObjectKey; m_TargetObjectKey = TargetObjectKey; return TRUE; } void cProjectileEffect::Process() { if( m_Actived == FALSE ) { if( m_StartedTime + m_ActiveDelayTime <= GetCurrentTime() ) { m_Actived = TRUE; if( m_EffectID != 0 ) { if( m_StaticRotate == TRUE ) { m_hEffect = GlobalFunc::CreateEffectBeUpToOption( m_EffectID, GetEffectPosition(), GetEffectScale(), m_EffectRotate, m_CasterObjectKey, m_TargetObjectKey ); } else { m_hEffect = GlobalFunc::CreateEffectBeUpToOption( m_EffectID, GetEffectPosition(), GetEffectScale(), GetEffectRotate(), m_CasterObjectKey, m_TargetObjectKey ); } } } } if( m_Actived == TRUE ) { if( CEffectBody* pBody = g_pEffectManager->GetEffectPtrHandle(m_hEffect) ) { WzColor Color = 0xFFFFFFFF; if( m_FadeOut == TRUE ) { nProjectileFunc::GetProjectileBlendColor( GetEffectTotalLifeTimeRate(), Color ); } pBody->SetColor( Color ); if( m_StaticRotate == TRUE ) { pBody->SetResultMatrix( GetEffectPosition(), m_EffectRotate, GetEffectScale() ); } else { pBody->SetResultMatrix( GetEffectPosition(), GetEffectRotate(), GetEffectScale() ); } } } } void cProjectileEffect::Destroy() { if( m_hEffect != INVALID_HANDLE_VALUE ) { g_pEffectManager->RemoveEffectPtr(m_hEffect); m_hEffect = INVALID_HANDLE_VALUE; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cProjectileUnitObject::cProjectileUnitObject() : m_pUnitDraw(NULL) , m_UnitColor(0xFFFFFFFF) , m_FadeOut(FALSE) , m_AlphaMode(AB_ALPHA) , m_StaticUnitRotate(FALSE) , m_UnitRotate(c_ZeroVector) , m_NextAnimationTime(0) , m_NextAnimationID(0) , m_NextAnimationLoop(FALSE) , m_CurrentTickTime(0) , m_ProjectileImageCode(eProjectile_SRC_NONE) { m_Actived = FALSE; m_ActiveDelayTime = 0; m_StartedTime = GetCurrentTime(); for (int j = 0; j < MAX_OBJECT_EFFECT; ++j) { m_UnitEffectParam[j].hEffect = INVALID_HANDLE_VALUE; m_UnitEffectParam[j].iBoneIndex = 0; m_UnitEffectParam[j].bRotateWithBone = FALSE; m_UnitEffectParam[j].bOnlyPosition = FALSE; m_UnitEffectParam[j].bRotateWithBone = FALSE; m_UnitEffectParam[j].EffectID = 0; ZeroMemory(&m_UnitEffectParam[j].quatRot, sizeof(WzQuaternion)); ZeroMemory(&m_UnitEffectParam[j].vOffset, sizeof(WzVector)); ZeroMemory(&m_UnitEffectParam[j].vScale, sizeof(WzVector)); } } void cProjectileUnitObject::Render() { if( m_pUnitDraw) { ENUM_ALPHABLEND OldAlphaMode = g_pSunRenderer->GetAlphaBlendMode(); g_pSunRenderer->SetAlphaBlendMode( m_AlphaMode, FALSE ); g_pSunRenderer->SetColor(m_UnitColor); g_pSunRenderer->RenderUnit(m_pUnitDraw); g_pSunRenderer->SetAlphaBlendMode( OldAlphaMode, FALSE ); } } void cProjectileUnitObject::Process(DWORD TickTime) { if( m_Actived == FALSE ) { if( m_StartedTime + m_ActiveDelayTime <= GetCurrentTime() ) { m_Actived = TRUE; // ù¹ø¤Š Process ¿¡¼­ UnitDraw¸¦ »ý¼ºÇÑ´Ù if( m_pUnitDraw == NULL && m_ProjectileImageCode != eProjectile_SRC_NONE ) { RESOURCECODE code = (DWORD)m_ProjectileImageCode + ENGINE_RESOURCE_ID_OFFSET; m_pUnitDraw = ResourceManager::Instance()->AllocResourceUnitDraw(code); //È­»ì if( m_pUnitDraw != NULL ) { m_pUnitDraw->SetCurrentAnimation( m_AnimationID, m_AnimationLoop ); } } } } if( m_Actived == TRUE ) { m_CurrentTickTime += TickTime; // UpdateUnitPosition if( m_pUnitDraw) { m_pUnitDraw->SetPosition( GetUnitObjectPosition(), FALSE ); m_pUnitDraw->SetRotation( m_StaticUnitRotate ? m_UnitRotate : GetUnitObjectRotate(), TRUE ); UpdateUnitAnimation( TickTime ); UpdateUnitEffectPosition( m_pUnitDraw, GetUnitObjectPosition(), m_StaticUnitRotate ? m_UnitRotate : GetUnitObjectRotate() ); if( IsUnitFadeOut() == TRUE ) { nProjectileFunc::GetProjectileBlendColor( GetUnitObjectLifeTimeRate(), m_UnitColor ); } if( m_NextAnimationTime != 0 ) { if( m_CurrentTickTime >= m_NextAnimationTime ) { m_NextAnimationTime = 0; SetUnitAnimation( m_NextAnimationID, m_NextAnimationLoop ); } } } } } void cProjectileUnitObject::SetNextUnitAnimation(DWORD ChangeTime, WzID AnimationID, BOOL Loop ) { m_NextAnimationTime = ChangeTime; m_NextAnimationID = AnimationID; m_NextAnimationLoop = Loop; } void cProjectileUnitObject::SetUnitAnimation(WzID AnimationID, BOOL Loop ) { m_AnimationID = AnimationID; m_AnimationLoop = Loop; //¿¡´Ï°¡ ¹Ù²ð°æ¿ì ÀÌÆåÆ® ÆÄ±« DestroyAllUnitEffect(); if( m_pUnitDraw != NULL ) { m_pUnitDraw->SetCurrentAnimation(AnimationID, Loop); } } void cProjectileUnitObject::Destroy() { if( m_pUnitDraw != NULL ) { int UnitEffectCount = m_pUnitDraw->GetNumUnitEffectInfo(); for( int i=0;iGetUnitEffectInfo(i); if( pUnitEffectInfo->m_hEffect != INVALID_HANDLE_VALUE ) { if( CEffectBody* pEffectInfo = g_pEffectManager->GetEffectPtrHandle( pUnitEffectInfo->m_hEffect ) ) { pEffectInfo->SetFadeOutEffect( false ); } g_pEffectManager->RemoveEffectPtr( pUnitEffectInfo->m_hEffect ); pUnitEffectInfo->m_hEffect = INVALID_HANDLE_VALUE; pUnitEffectInfo->m_iNode = 0; } } ResourceManager::Instance()->FreeResourceUnitDraw( m_pUnitDraw ); m_pUnitDraw = NULL; } DestroyAllUnitEffect(); } void cProjectileUnitObject::SetUnitCode( eProjectile_SRC ProjectileImageCode ) { m_ProjectileImageCode = ProjectileImageCode; } // //BOOL cProjectileUnitObject::CreateUnit( eProjectile_SRC ProjectileImageCode ) //{ // if( (DWORD)ProjectileImageCode == 0 ) // { // return FALSE; // } // // RESOURCECODE code = (DWORD)ProjectileImageCode + ENGINE_RESOURCE_ID_OFFSET; // m_pUnitDraw = ResourceManager::Instance()->AllocResourceUnitDraw(code); //È­»ì // // return m_pUnitDraw != NULL; //} void cProjectileUnitObject::UpdateUnitEffectPosition( CWzUnitDraw* pUnitDraw, const WzVector& Position, const WzVector& Direction ) { static const int FORCE_TRANSFROM = -2; for ( int j = 0; j < MAX_OBJECT_EFFECT; ++j ) { EFFECT_PARAM& EffectParam = m_UnitEffectParam[j]; if (EffectParam.hEffect != INVALID_HANDLE_VALUE) { if ( CEffectBody* pBody = g_pEffectManager->GetEffectPtrHandle(EffectParam.hEffect) ) { // º»Àνº°ªÀÌ °­Á¦ º¯È¯À϶§´Â °»½ÅÇÏÁö¾Ê´Â´Ù if (EffectParam.iBoneIndex == FORCE_TRANSFROM) { continue; } WzVector wvPos, wvWorldPos; WzMatrix wmPosMat, wmRotMat, wmRot, wmScale, mat; wvPos = EffectParam.vOffset; if( EffectParam.iBoneIndex == -1 ) { wvWorldPos = Position; WzVector rotation = {0.f, 0.f, Math_GetAngleFromVector(&Direction)}; MatrixRotationZYX(&wmRotMat, &rotation); // ·ÎÅ×À̼ÇÀÌ Àû¿ëµÈ Offset¸¸Å­ À̵¿ VectorTransformCoord(&rotation, &EffectParam.vOffset, &wmRotMat); wvWorldPos += rotation; } else { if( GameFunc::GetBoneMatrix( pUnitDraw, EffectParam.iBoneIndex, &mat ) == FALSE ) { continue; } VectorTransformCoord( &wvWorldPos, &wvPos, &mat ); } MatrixTranslation( &wmPosMat, wvWorldPos.x, wvWorldPos.y, wvWorldPos.z ); if(EffectParam.bOnlyPosition) { MatrixIdentity( &wmRotMat ); } else if( EffectParam.bRotateWithBone ) { QuaternionToMatrix( &wmRot, &EffectParam.quatRot ); MatrixMultiply( &wmRotMat, &wmRot, &mat ); wmRotMat._41 = 0.0f; wmRotMat._42 = 0.0f; wmRotMat._43 = 0.0f; } else { MatrixIdentity( &wmRotMat ); WzVector vPos; vPos = wvWorldPos; WzVector vDest,vTemp; vDest = vPos + Direction*10.0f; vDest = vDest - vPos; vTemp = vDest; vTemp.z = 0.0f; float fLength; if (vTemp.x == 0.0f && vTemp.y == 0.0f) { fLength = 0.0f; } else { fLength = VectorLength(&vTemp); } WzVector vRot; vRot.x = -atan2(vDest.z,fLength); vRot.z = Math_GetAngleFromVector(&vDest); vRot.y = 0.0f; MatrixRotationZYX(&wmRotMat,&vRot); } MatrixScaling( &wmScale, EffectParam.vScale.x, EffectParam.vScale.y, EffectParam.vScale.z ); pBody->SetResultMatrix( &wmPosMat, &wmRotMat, &wmScale ); } else { //ÀÚµ¿ NULL¼ÂÆÃ EffectParam.hEffect = INVALID_HANDLE_VALUE; } } } } BOOL cProjectileUnitObject::UpdateUnitAnimation( DWORD TickTime ) { if( m_pUnitDraw != NULL ) { g_pSunRenderer->AnimateUnit( m_pUnitDraw ); float fLoopCheck; fLoopCheck = 0.0f; WzEvent Event; ZeroMemory(&Event,sizeof(Event)); g_pSunRenderer->ProgressUnitFrame(m_pUnitDraw, ( float )TickTime, &Event, &fLoopCheck ); //À¯´Ö¿¡ µþ¸° ÀÌÆåÆ® »ý¼º, »èÁ¦ if (Event.m_iNumEffect > 0) { for (int a = 0; a < Event.m_iNumEffect; a++) { int iIndex = Event.m_Effect[a].m_iEffectType; assert(iIndex >= 0 && iIndex < MAX_OBJECT_EFFECT); if (iIndex < 0) { iIndex = 0; } else if (iIndex >= MAX_OBJECT_EFFECT) { iIndex = MAX_OBJECT_EFFECT - 1; } if (Event.m_Effect[a].m_byEffectFlag & EFF_DESTROY) { DestroyUnitEffect(iIndex); } else { DestroyUnitEffect(iIndex); int boneindex = Event.m_Effect[a].m_iEffectBoneIndex; WzVector vPos; GameFunc::GetBonePos( m_pUnitDraw, boneindex, &vPos); m_UnitEffectParam[iIndex].hEffect = GlobalFunc::CreateEffectBeUpToOption( Event.m_Effect[a].m_wiEffectWzID, vPos, 0, 0 ); m_UnitEffectParam[iIndex].iBoneIndex = boneindex; } } } } //if( m_StaticRotate == TRUE ) //{ // WzVector vPos = pTargetObject->GetBonePos( m_BoneIndex ); // WzMatrix wmPosMat, wmRotMat, wmScale, mat; // mat = pTargetObject->GetBoneMatrix( m_BoneIndex ); // wmRotMat = pTargetObject->GetBoneMatrix( m_BoneIndex ); // wmRotMat._41 = 0.0f; // wmRotMat._42 = 0.0f; // wmRotMat._43 = 0.0f; // MatrixIdentity( &wmPosMat ); // MatrixTranslation( &wmPosMat, vPos.x, vPos.y, vPos.z ); // MatrixIdentity( &wmPosMat ); // MatrixScaling( &wmScale,1.0f,1.0f,1.0f); // pBody->SetResultMatrix( &wmPosMat, &wmRotMat, &wmScale ); //} return TRUE; } void cProjectileUnitObject::DestroyUnitEffect(int index) { assert(index >= 0 && index < MAX_OBJECT_EFFECT); if( m_UnitEffectParam[index].hEffect != INVALID_HANDLE_VALUE) { g_pEffectManager->RemoveEffectPtr(m_UnitEffectParam[index].hEffect); m_UnitEffectParam[index].hEffect = INVALID_HANDLE_VALUE; m_UnitEffectParam[index].iBoneIndex = 0; } } void cProjectileUnitObject::DestroyAllUnitEffect() { for (int a = 0; a < MAX_OBJECT_EFFECT; a++) { DestroyUnitEffect(a); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "ObjectManager.h" #include "CloneManager.h" #include "Clone.h" cProjectileCloneObject::cProjectileCloneObject() : m_OriginalObjectKey(INVALID_OBJECT_KEY) , m_CloneObjectKey(INVALID_OBJECT_KEY) , m_pClone(NULL) , m_CloneColor(0xFFFFFFFF) , m_CloneBlendType(AB_LIGHTING) { m_Actived = FALSE; m_ActiveDelayTime = 0; m_StartedTime = GetCurrentTime(); } void cProjectileCloneObject::CreateClone( DWORD ObjectKey, WzID AnimationID ) { m_OriginalObjectKey = ObjectKey; m_AnimationID = AnimationID; } void cProjectileCloneObject::Render() { if( m_pClone != NULL ) { m_pClone->Render(); } } void cProjectileCloneObject::Process( DWORD TickTime ) { if( m_Actived == FALSE ) { if( m_StartedTime + m_ActiveDelayTime <= GetCurrentTime() ) { m_Actived = TRUE; if( Object* object = g_ObjectManager.GetObject( m_OriginalObjectKey ) ) { m_pClone = g_CloneManager.CreateNotManagedClone( object ); //m_pClone->SetPosition( GetClonePosition() ); //m_pClone->SetDirection( GetClonePosition() + GetCloneDirection() ); m_pClone->SetPlayAni(TRUE); m_pClone->SetAnimation( m_AnimationID, FALSE ); m_pClone->SetAlphaBlend(m_CloneBlendType); //WzColor color = WzColor_RGBA(255,255,255,220); //m_pClone->SetAlphaBlend(AB_LIGHTING); //m_pClone->SetColor(color); } } } if( m_pClone != NULL ) { WzColor color = m_CloneColor; if( IsCloneFadeOut() == TRUE ) { nProjectileFunc::GetProjectileBlendColor( GetCloneLifeTimeRate(), color ); } m_pClone->SetColor(color); m_pClone->SetCurPos( GetClonePosition() ); m_pClone->SetRotation( Math_GetAngleFromVector( &GetCloneDirection() ) ); //m_pClone->SetPosition( GetClonePosition() ); //m_pClone->SetDirection( GetClonePosition() + GetCloneDirection() ); m_pClone->Process( TickTime ); } } void cProjectileCloneObject::Destroy() { if( m_pClone != NULL ) { m_pClone->Destroy(); delete m_pClone; m_pClone = NULL; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cProjectileTrail::cProjectileTrail() : m_pTrailMesh(NULL) , m_TrailHeight(0.0f) , m_TrailLength(0.0f) , m_TrailColorRed(255) , m_TrailColorGreen(255) , m_TrailColorBlue(255) , m_ReadyTrail(FALSE) { } BOOL cProjectileTrail::CreateTrail( HANDLE hTailTexture, float TrailHeight, float TrailLength, BYTE ColorRed, BYTE ColorGreen, BYTE ColorBlue ) { if( TrailHeight <= 0.0f || TrailLength <= 0.0f) return FALSE; m_pTrailMesh = New_SimpleMesh(2); m_pTrailMesh->m_pUVVerts[0].u = 0.0f; m_pTrailMesh->m_pUVVerts[0].v = 1.0f; m_pTrailMesh->m_pUVVerts[1].u = 0.0f; m_pTrailMesh->m_pUVVerts[1].v = 0.0f; m_pTrailMesh->m_pUVVerts[2].u = 1.0f; m_pTrailMesh->m_pUVVerts[2].v = 1.0f; m_pTrailMesh->m_pUVVerts[3].u = 0.0f; m_pTrailMesh->m_pUVVerts[3].v = 0.0f; m_pTrailMesh->m_pUVVerts[4].u = 1.0f; m_pTrailMesh->m_pUVVerts[4].v = 0.0f; m_pTrailMesh->m_pUVVerts[5].u = 1.0f; m_pTrailMesh->m_pUVVerts[5].v = 1.0f; m_pTrailMesh->m_hTexDiffuse = hTailTexture; m_TrailHeight = TrailHeight; m_TrailLength = TrailLength; m_TrailColorRed = ColorRed; m_TrailColorGreen = ColorGreen; m_TrailColorBlue = ColorBlue; return TRUE; } void cProjectileTrail::Destroy() { if( m_pTrailMesh) { Delete_SimpleMesh(m_pTrailMesh); m_pTrailMesh = NULL; } } void cProjectileTrail::Render() { if( m_pTrailMesh ) { if( m_ReadyTrail == TRUE ) { BYTE FirstAlpha = 200; float fRate = 1.0f - (GetArrowPositionRate()); if (fRate <= 0.0f) { fRate = 0.0f; } BYTE Alpha = (BYTE)((float)FirstAlpha * fRate); g_pSunRenderer->SetColor( m_TrailColorRed, m_TrailColorGreen, m_TrailColorBlue, Alpha ); g_pSunRenderer->RealizeRenderSimpleMesh(m_pTrailMesh); } } } void cProjectileTrail::Process() { if( m_pTrailMesh == NULL ) return; St_Camera* pCameraInfo = g_pSunRenderer->GetCameraInfo(); WzVector CameraDirection = pCameraInfo->m_wvDir; float fRate = GetArrowPositionRate(); float fTrailHeadRate = 1.0f - fRate; float fTrailEndRate = fRate - m_TrailLength; if( fTrailEndRate <= 0.0f) { fTrailEndRate = 0.0f; } if( fTrailEndRate >= 1.0f) { fTrailEndRate = 1.0f; } WzVector vCurPos,vCurPos2,vDestPos,vDestPos2,vNewPos,vNewPos2,vNewEndPos,vNewEndPos2; vCurPos = vCurPos2 = GetArrowStartPosition(); vDestPos = vDestPos2 = GetArrowTargetPosition(); WzVector vDest = vDestPos - vCurPos; VectorNormalize(&vDest,&vDest); WzVector vDirection; VectorCrossProduct(&vDirection,&vDest,&CameraDirection); VectorNormalize(&vDirection,&vDirection); WzVector CamPos = pCameraInfo->m_wvFrom; WzVector BeamSrc = GetArrowStartPosition(); WzVector BeamDst = GetArrowTargetPosition(); WzVector vBeamDir = BeamDst - BeamSrc; VectorNormalize(&vBeamDir,&vBeamDir); WzVector vBeamToCam = CamPos - BeamSrc; VectorNormalize(&vBeamToCam,&vBeamToCam); WzVector vBeamUp; vBeamUp.x = 0.0f; vBeamUp.y = 0.0f; vBeamUp.z = 1.0f; WzVector vCurrDir = vBeamToCam - vBeamDir; float fAngle = acos(VectorDotProduct(&vBeamUp,&vCurrDir)); if (vCurrDir.x < 0) fAngle = fAngle; else if (vCurrDir.x > 0) fAngle = -fAngle; else fAngle = 0; WzMatrix matrix; VectorNormalize(&vCurrDir,&vCurrDir); MatrixRotation(&matrix,&vCurrDir,fAngle); WzVector vTemp; vTemp.x = 0.0f; vTemp.y = 0.0f; vTemp.z = 1.0f; float fTrailHeight = m_TrailHeight * fTrailHeadRate; vCurPos = vCurPos + vDirection * (fTrailHeight / 2.0f); vCurPos2 = vCurPos2 - vDirection * (fTrailHeight / 2.0f); vDestPos = vDestPos + vDirection * (fTrailHeight / 2.0f); vDestPos2 = vDestPos2 - vDirection * (fTrailHeight / 2.0f); vNewPos = vCurPos * (1.0f - fRate) + vDestPos * (fRate); vNewPos2 = vCurPos2 * (1.0f - fRate) + vDestPos2 * (fRate); vNewEndPos = vCurPos * (1.0f - fTrailEndRate) + vDestPos * (fTrailEndRate); vNewEndPos2 = vCurPos2 * (1.0f - fTrailEndRate) + vDestPos2 * (fTrailEndRate); // ¸Å½¬ ÁÂÇ¥¿¡ ´ëÀÔ WzVector vArrowDir = vDestPos - vCurPos; VectorNormalize(&vArrowDir,&vArrowDir); WzVector vTrailOffset = vArrowDir * -0.3f; m_pTrailMesh->m_pVertices[0] = vTrailOffset + vNewEndPos; m_pTrailMesh->m_pVertices[1] = vTrailOffset + vNewPos; m_pTrailMesh->m_pVertices[2] = vTrailOffset + vNewEndPos2; m_pTrailMesh->m_pVertices[3] = vTrailOffset + vNewPos; m_pTrailMesh->m_pVertices[4] = vTrailOffset + vNewPos2; m_pTrailMesh->m_pVertices[5] = vTrailOffset + vNewEndPos2; m_ReadyTrail = TRUE; } #include "Map.h" cProjectileSwordTrail::cProjectileSwordTrail() : m_LastTickTIme(0) , m_InitializedSwordTrail(FALSE) { } void cProjectileSwordTrail::Process( DWORD TickTime ) { WzVector CurrentPosition = GetSwordTrailPosition(); if( CEffectBody* pBody = g_pEffectManager->GetEffectPtrHandle( GetEffectHandle() ) ) { if( CEElementFlatChain* pFChain = pBody->GetFlatChainPtr() ) { if( m_InitializedSwordTrail == FALSE ) { pBody->SetRenderType(AR_REFRACTION_GLASS); pBody->SetRefractionRate(0.5f); // ±¼Àý·ü.(0¿¡ °¡±î¿ö Áú¼ö·Ï Åõ¸í) pBody->SetRefractionAlpha(1.0f); // 1.0 ¿¡ °¡±î¿öÁú¼ö·Ï º» À̹ÌÁö¿¡ °¡±î¿öÁü pFChain->SetLifeInfo(0, 3000); pFChain->SetTailNum(40); pFChain->SetSplineLength(0.1f); m_InitializedSwordTrail = TRUE; } pFChain->SetPosition( CurrentPosition + m_TrailStartOffset, CurrentPosition + m_TrailEndOffset ); } } if( m_TrailEffectDelay > 0 ) { if( GetCurrentTime() - m_LastTickTIme >= m_TrailEffectDelay ) { WzVector vResult; g_pMap->GetTerrainHeight( &CurrentPosition, &vResult); GlobalFunc::CreateEffectBeUpToOption( StrToWzID("A030"), vResult, 0, 0 ); m_LastTickTIme = GetCurrentTime(); } } } void cProjectileSwordTrail::Destroy() { } void cProjectileSwordTrail::Render() { }