// // 비행중 공격 액션 처리 // void CActionMover::_ProcessStateAttack2( DWORD dwState, int nParam ) { CMover* pMover = m_pMover; CModelObject *pModel = (CModelObject *)pMover->m_pModel; switch( dwState ) { case OBJSTA_ATK1: if( pModel->IsEndFrame() ) ResetState( OBJSTA_ATK_ALL ); if( pModel->m_nPause > 0 ) { --pModel->m_nPause; } else { if( pModel->IsAttrHit() ) { CMover* pHitObj = prj.GetMover( m_objidHit ); if( IsInvalidObj( pHitObj ) || pHitObj->IsDie() ) // 타겟이 거시기하거나 죽었으면 취소 return; BOOL bSuccess = pHitObj->m_pActMover->SendDamage( AF_GENERIC, pMover->GetId() ); if( bSuccess == FALSE ) return; #ifdef __CLIENT ItemProp* pItemProp = pMover->GetActiveHandItemProp(); if( pItemProp ) { D3DXVECTOR3 v = pMover->GetPos(); PLAYSND( pItemProp->dwSndAttack1, &v ); } #endif if( GetMover()->IsPlayer() ) { pModel->m_nPause = 5; // frame 멈춤 } else { pModel->m_nPause = 0; // 몬스터는 멈추지 않음 pHitObj->m_pModel->m_nPause = 0; } } } break; } }
// // State process // 가급적 이곳에선 pMover->SetMotion을 하지 말것 // 빗자루 비행모드 // void CActionMover::ProcessState2( CMover* pMover, DWORD dwState, float fSpeed ) { int nParam = 0; float fAng = pMover->GetAngleX(); CModelObject* pModel = (CModelObject*)pMover->m_pModel; ItemProp* pItemProp = prj.GetItemProp( m_pMover->m_dwRideItemIdx ); if( !pItemProp ) { Error( "ProcessState2(): %s, m_dwRideItemIdx == %d", m_pMover->m_szName, m_pMover->m_dwRideItemIdx ); return; } switch( dwState ) { // 제자리 대기 / 정지 case OBJSTA_STAND: m_fAccPower = 0; // 대기/정지상태에선 힘을 더이상 가하지 않는다. if( GetState() & OBJSTA_ATK_ALL ) break; if( GetState() & OBJSTA_TURN_ALL ) break; if( GetState() & OBJSTA_DMG_ALL ) break; { if( pMover->SetMotion( pItemProp->dwUseMotion + MTA_FSTAND1, ANILOOP_LOOP, MOP_FIXED ) == TRUE ) // 대기상태 if( pMover->m_pRide ) pMover->m_pRide->m_fFrameCurrent = 0; } break; // 전진 case OBJSTA_FMOVE: // 무버가 타고있는 아이템의 인덱스에서 추진력을 꺼내옴. m_fAccPower = pItemProp->fFlightSpeed * 0.75f; if( GetState() & OBJSTA_ATK_ALL ) break; if( GetState() & OBJSTA_TURN_ALL ) break; { if( pMover->SetMotion( pItemProp->dwUseMotion + MTA_FRUNNING1, ANILOOP_LOOP, MOP_FIXED ) == TRUE ) // 대기상태 if( pMover->m_pRide ) pMover->m_pRide->m_fFrameCurrent = 0; } break; // 좌/우 돌기 case OBJSTA_LTURN: { float fTurnAng = m_fTurnAngle; if( (GetStateFlag() & OBJSTAF_ACC) == 0 ) // 가속상태가 아닐때는 2배로 빨리 돈다. fTurnAng *= 2.5f; pMover->AddAngle( fTurnAng ); } if( IsActAttack() ) break; pMover->SetMotion( pItemProp->dwUseMotion + MTA_FLTURN1, ANILOOP_LOOP, MOP_FIXED ); break; case OBJSTA_RTURN: { float fTurnAng = m_fTurnAngle; if( (GetStateFlag() & OBJSTAF_ACC) == 0 ) // 가속상태가 아닐때는 2배로 빨리 돈다. fTurnAng *= 2.5f; pMover->AddAngle( -fTurnAng ); } if( IsActAttack() ) break; pMover->SetMotion( pItemProp->dwUseMotion + MTA_FRTURN1, ANILOOP_LOOP, MOP_FIXED ); break; case OBJSTA_LOOKUP: if( fAng > -45.0f ) pMover->AddAngleX( -pItemProp->fFlightTBAngle ); break; case OBJSTA_LOOKDOWN: if( fAng < 45.0f ) pMover->AddAngleX( pItemProp->fFlightTBAngle ); break; //--------- 공격 --------------------------- case OBJSTA_ATK1: case OBJSTA_ATK2: case OBJSTA_ATK3: case OBJSTA_ATK4: _ProcessStateAttack2( dwState, nParam ); break; case OBJSTA_ATK_MAGIC1: // 원거리 완드 공격. ProcessStateAttackMagic( dwState, nParam ); break; //----------- 데미지 ------------------------- case OBJSTA_DMG: if( pModel->IsEndFrame() ) ResetState( OBJSTA_DMG_ALL ); break; case OBJSTA_DEAD: // 죽어 널부러진 상태 #ifdef __WORLDSERVER if( !pMover->IsPlayer() ) { m_nDeadCnt--; if( m_nDeadCnt < 0 ) { SetState( OBJSTA_DMG_ALL, OBJSTA_DISAPPEAR ); // 사라지는 상태로 전환 m_nCount = 0; } } #endif break; } }