// // nDmgCnt : 일반적으론 0 : 지속데미지를 사용할경우에 0이 아닌값이 들어온다. // void CSfx::DamageToTarget( int nDmgCnt, float fDmgAngle, float fDmgPower, int nMaxDmgCnt ) { CMover* pObjSrc = (CMover*)prj.GetCtrl( m_idSrc ); CCtrl* pObjDest = prj.GetCtrl( m_idDest ); if( IsInvalidObj(pObjSrc) ) return; // 지금은 걍 리턴하지만 이렇게 실패한경우는 m_idSfxHit을 Clear해주는작업이 필요하다. if( IsInvalidObj(pObjDest) ) return; if( pObjDest->GetType() == OT_MOVER ) { CMover* pMover = (CMover*) pObjDest; #ifdef __CLIENT PLAYSND( pMover->GetProp()->dwSndDmg2, &pMover->GetPos() ); // 마법류 맞을때 타격음. #endif #ifdef __CLIENT // 쏜놈이 플레이어이거나 / 쏜놈은 플레이어가 아닌데 맞은놈이 플레이어일경우 전송 if( pObjSrc->IsActiveMover() || (pObjSrc->IsPlayer() == FALSE && pObjDest->IsActiveObj()) ) { pMover->SetDmgCnt( 10 ); // 발사체 맞아도 이제 흔들린다, g_DPlay.SendSfxHit( m_idSfxHit, m_nMagicPower, m_dwSkill, pObjSrc->GetId(), nDmgCnt, fDmgAngle, fDmgPower ); if( nMaxDmgCnt == 1 ) // 한방짜리 데미지만 id를 클리어 함. m_idSfxHit = 0; // 0으로 해놔야 this가 삭제될때 SendSfxClear를 또 보내지 않는다. } #endif // __CLIENT } }
void CActionMover::ProcessFlyTracking() { CMover* pMover = m_pMover; // 자동 추적 모드. g_pPlayer만 실행된다. if( pMover->IsActiveMover() && (pMover->m_dwFlag & MVRF_TRACKING) ) { static float s_fTurnAcc = 0, s_fTurnAccH = 0; { CMover *pTarget = prj.GetMover( pMover->m_idTracking ); // 추적할 목표. if( pTarget ) { D3DXVECTOR3 vDist = pTarget->GetPos() - pMover->GetPos(); // 나를 원점으로 타겟까지의 벡터. FLOAT fAngXZ, fAngH; xGetDegree( &fAngXZ, &fAngH, vDist ); // 타겟과의 각도 구함. // 남쪽이 0도 기준. 시계방향 -180까지 시계반대방향 +180 // 3도 이하는 무시. FLOAT fMoverAng = pMover->GetAngle(); if( fMoverAng > 180.0f ) // 계산하기 좋게 좌표계를 +,- 로 바꿈. fMoverAng -= 360.0f; FLOAT fSubAng = fAngXZ - fMoverAng; if( fSubAng > 180.0f ) fSubAng -= 360.0f; else if( fSubAng < -180.0f ) fSubAng += 360.0f; #ifdef _DEBUG #ifdef __XUZHU extern float _g_fReg[]; _g_fReg[1] = fSubAng; _g_fReg[2] = fAngXZ; #endif #endif if( fSubAng < -3.0f ) // 오른쪽으로 돌아야 한다. s_fTurnAcc = -2.5f; else if( fSubAng > 3.0f ) // 왼쪽으로 돌아야 한다. s_fTurnAcc = 2.5f; else s_fTurnAcc = 0; FLOAT fMoverAngX = pMover->GetAngleX(); FLOAT fSubAngH = fAngH - fMoverAngX; if( fSubAngH > 180.0f ) fSubAngH -= 360.0f; else if( fSubAngH < -180.0f ) fSubAngH += 360.0f; if( fSubAngH < -3.0f ) s_fTurnAccH = -1.5f; else if( fSubAngH > 3.0f ) s_fTurnAccH = 1.5f; else s_fTurnAccH = 0; pMover->SetAngle( pMover->GetAngle() + s_fTurnAcc ); pMover->SetAngleX( pMover->GetAngleX() + s_fTurnAccH ); if( s_fTurnAcc || s_fTurnAccH ) // 값이 달라지면 전송함. g_DPlay.PostPlayerAngle( TRUE ); } } } }
void CActionMover::ProcessFlyMove( void ) { #ifdef __CLIENT g_nDrift = 0; // 드리프트 플랙 클리어 #endif float fLenSq = D3DXVec3LengthSq( &m_vDelta ); if( fLenSq == 0.0f && (GetStateFlag() & OBJSTAF_ACC ) == 0 ) return; // 멈춤 상태면 리턴 CMover* pMover = m_pMover; FLOAT fAccPwr = m_fAccPower; #ifdef __CLIENT ProcessFlyTracking(); #endif // client // 터보모드 처리 if( (GetStateFlag() & OBJSTAF_TURBO) && (GetStateFlag() & OBJSTAF_ACC) ) // 터보모드 & 전진중 { #ifdef __WORLDSERVER pMover->m_tmAccFuel = (int)( pMover->m_tmAccFuel - (1000.0f / (float)FRAME_PER_SEC) ); // 1/60만큼 깎음 #endif if( pMover->m_tmAccFuel <= 0 ) // 가속연료가 다 떨어지면 { pMover->m_tmAccFuel = 0; SendActMsg( OBJMSG_MODE_TURBO_OFF ); // 터보모드 중지 #ifdef __WORLDSERVER g_UserMng.AddSendActMsg( pMover, OBJMSG_MODE_TURBO_OFF ); #endif } else fAccPwr *= 1.2f; // 가속연료가 남아있다면 터보모드 } #ifdef __CLIENT ProcessFlyParticle( fLenSq ); #endif // 관성처리 if( fAccPwr > 0.0f ) { // 힘벡터 생성 FLOAT fAngX = D3DXToRadian( pMover->GetAngleX() ); FLOAT fAng = D3DXToRadian( pMover->GetAngle() ); FLOAT fDist = cosf(fAngX) * fAccPwr; D3DXVECTOR3 vAcc; vAcc.x = sinf( fAng ) * fDist; vAcc.z = -cosf( fAng ) * fDist; vAcc.y = -sinf( fAngX ) * fAccPwr; // 관성벡터와 추진력벡터가 각도가 50도 이하면 급추진 if( fLenSq > 0.01f ) { D3DXVECTOR3 vDeltaNorm, vAccNorm; D3DXVec3Normalize( &vDeltaNorm, &m_vDelta ); D3DXVec3Normalize( &vAccNorm, &vAcc ); float fDot = D3DXVec3Dot( &vDeltaNorm, &vAccNorm ); if( fDot < 0.633319f ) // 이전코드: cosf(70.0f) 값으로는 대략 50도 { vAcc *= 2.0f; m_vDelta *= 0.985f; #ifdef __CLIENT g_nDrift = 1; if( ! ( pMover->IsMode( TRANSPARENT_MODE ) ) ) // 투명상태가 아닐때만 렌더. { if( (g_nProcessCnt & 3) == 0 ) CreateSfx( g_Neuz.m_pd3dDevice, XI_NAT_DUST_RUN, pMover->GetPos() ); } #endif } } fLenSq = D3DXVec3LengthSq( &m_vDelta ); // 1/60 sec 속도 float fMaxSpeed = 0.3f; if( GetStateFlag() & OBJSTAF_TURBO ) // 터보모드에선 MAX속도가 1.1배 fMaxSpeed *= 1.1f; if( fLenSq < (fMaxSpeed * fMaxSpeed) ) // 일정이상 속도를 넘지 않게 하자. m_vDelta += vAcc; // 관성벡터 += 추진력벡터 } m_vDelta *= (1.0f - FRIC_AIR); // 마찰력에 의한 감소 // raiders - 수치적 안정성을 위해서 적은 수치가 계산되는 것을 피한다. fLenSq = D3DXVec3LengthSq( &m_vDelta ); if( m_fAccPower == 0.0f && fLenSq < 0.0002f * 0.0002f ) { fLenSq = 0; m_vDelta = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); RemoveStateFlag( OBJSTAF_ACC ); // 가속상태 해제 } #ifdef __CLIENT if( pMover->IsActiveMover() ) { g_nFlySpeed = (int)( (sqrt(fLenSq) * 60.0f) * 60.0f * 60.0f ); g_nFlySpeed = (int)( g_nFlySpeed / 200.0f ); } #endif }
void CActionMover::ProcessFlyParticle( float fLenSq ) { CMover *pMover = m_pMover; // 운영자 투명모드때는 파티클 안나옴. if( (pMover->IsMode( TRANSPARENT_MODE ) ) == 0 ) { ItemProp* pRideProp = prj.GetItemProp( m_pMover->m_dwRideItemIdx ); // 현재 타고있는 탈것의 프로퍼티. // 비행 파티클 처리. if( fLenSq > 0.01f ) { if( (pMover->IsActiveMover() && g_Neuz.m_camera.m_fZoom > 2.0f) || pMover->IsActiveMover() == FALSE ) // 일정속도 이상이 되면 꼬리에 파티클이 나오기 시작. { int nType = 0; if( pRideProp && pRideProp->dwID == II_RID_RID_BOR_RIDINGCLOUD ) nType = 1; CreateFlyParticle( pMover, pMover->GetAngleX(), nType ); } } if( fLenSq > 0.001f ) { if( (pMover->IsActiveMover() && g_Neuz.m_camera.m_fZoom > 1.0f) || pMover->IsActiveMover() == FALSE ) { if( pRideProp && pRideProp->dwItemKind3 == IK3_BOARD ) // 보드만 꼬리가 나온다. { if( m_pTail ) { if( pRideProp->dwID == II_RID_RID_BOR_RIDINGCLOUD ) // 근두운일때 { if( m_pTail->GetType() != 2 ) // 생성되었던 꼬리고 근두운용이 아니면 m_pTail->ChangeTexture( D3DDEVICE, "etc_Tail2.bmp", 2 ); } else { if( m_pTail->GetType() != 1 ) // 생성되었던 꼬리고 일반보드용이 아니면 m_pTail->ChangeTexture( D3DDEVICE, "etc_Tail1.bmp", 1 ); // 일반보드용으로 텍스쳐 교체. } } if( m_pTail == NULL ) // 아직 할당 안됐으면 할당하고. { if( pRideProp->dwID == II_RID_RID_BOR_RIDINGCLOUD ) // 근두운... { m_pTail = (CTailEffectBelt*)g_TailEffectMng.AddEffect( g_Neuz.m_pd3dDevice, "etc_Tail2.bmp", 2 ); } else { m_pTail = (CTailEffectBelt*)g_TailEffectMng.AddEffect( g_Neuz.m_pd3dDevice, "etc_Tail1.bmp", 1 ); } } D3DXVECTOR3 vPos1, vPos2; D3DXVECTOR3 vLocal; FLOAT fAngXZ = pMover->GetAngle(); FLOAT fAngH = pMover->GetAngleX(); AngleToVectorXZ( &vLocal, fAngXZ, -1.0f ); fAngXZ -= 90.0f; if( fAngXZ < 0 ) fAngXZ += 360.0f; AngleToVector( &vPos1, fAngXZ, -fAngH, 0.5f ); vPos1 += pMover->GetPos(); vPos1 += vLocal; fAngXZ = pMover->GetAngle(); fAngH = pMover->GetAngleX(); AngleToVectorXZ( &vLocal, fAngXZ, -1.0f ); fAngXZ += 90.0f; if( fAngXZ > 360.0f ) fAngXZ -= 360.0f; AngleToVector( &vPos2, fAngXZ, -fAngH, 0.5f ); vPos2 += pMover->GetPos(); vPos2 += vLocal; if( m_pTail ) m_pTail->CreateTail( vPos1, vPos2 ); } } } } // 투명모드가 아닐때 }