Beispiel #1
0
void CParty::DoUsePartySkill( u_long uPartyId, u_long uLeaderid, int nSkill )
{
#ifdef __WORLDSERVER
	CUser* pMember	= NULL;
	int		i;
	
	if( IsLeader( uLeaderid ) && m_nKindTroup == 1 )
	{
		ItemProp* pItemProp =  prj.GetPartySkill( nSkill );
		if( pItemProp )
		{
#ifndef __PARTYDEBUG
			if( int( GetLevel() - pItemProp->dwReqDisLV ) >= 0 )
#endif // __PARTYDEBUG
			{
#ifndef __PARTYDEBUG
	#if __VER >= 12 // __JHMA_VER12_1	//12차 극단유료아이템
				CUser *pLeadertmp = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
				if( IsValidObj( pLeadertmp ) == FALSE )
					return;
				int nHasCashSkill = 0,nFPoint = 0;
				if( pLeadertmp->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYSKILLUP01 ) 
					|| pLeadertmp->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYSKILLUP02 )
					|| pLeadertmp->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYSKILLUP01_01 ) )
				{
					if( nSkill == ST_LINKATTACK 
						|| nSkill == ST_FORTUNECIRCLE 
						|| nSkill == ST_STRETCHING
						|| nSkill == ST_GIFTBOX )
						nHasCashSkill = 1;
				}

				DWORD dwSkillTime	= pItemProp->dwSkillTime;
				int nRemovePoint	= pItemProp->dwExp;

				nFPoint	= int( GetPoint() - pItemProp->dwExp);
#if __VER >= 12 // __LORD
				// 군주의 극단
				// 군주가 극단장 으로써 극단스킬 사용 시,
				// 지속시간 4배 증가(소모 포인트는 동일)
				if( CSLord::Instance()->IsLord( uLeaderid ) )
					dwSkillTime		*= 4;
#endif	// __LORD

				if( nFPoint >= 0 )
	#else
				if( int( GetPoint() - pItemProp->dwExp) >= 0 )
	#endif // //12차 극단유료아이템
#endif // __PARTYDEBUG
				{
					switch( nSkill )
					{
					case ST_CALL:
						{
							g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp );
							CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
							if( IsValidObj( pLeader ) == FALSE )
								break;

							// 단장 중심으로 모여달라는 표시
							for( i = 0; i < m_nSizeofMember; i ++ )		// 단장(0)에게는 보낼필요 없다.
							{
								pMember		= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
								// 단장 어라운드 지역에 있는 사람에게만 보낸다
								if( IsValidObj( (CObj*)pMember ) )
									pMember->AddPartySkillCall( pLeader->GetPos() );		// 각 멤버들에게 단장이 좌표를 전송함.
							}
						}
						break;
					case ST_BLITZ:
						{
							CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
							if( IsValidObj( pLeader ) == FALSE )
								break;

							if( pLeader->m_idSetTarget != NULL_ID )
							{
								CMover *pT = prj.GetMover( pLeader->m_idSetTarget );
								if( pT && !pT->IsPlayer() )
								{
									g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp );
									// 단장이 타겟으로 집중공격 표시
									for( i = 0; i < m_nSizeofMember; i ++ )
									{
										pMember		= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
										if( IsValidObj( (CObj*)pMember ) )
										{
											if( m_nModeTime[PARTY_GIFTBOX_MODE] || m_nModeTime[PARTY_FORTUNECIRCLE_MODE] )
											{
												pMember->AddPartySkillBlitz( pLeader->m_idSetTarget );		// 각 멤버들에게 단장타겟으로 잡은 무버의 아이디를 보냄.
											}
											else
											{
												if( pLeader->IsNearPC( pMember ) )
													pMember->AddPartySkillBlitz( pLeader->m_idSetTarget );		// 각 멤버들에게 단장타겟으로 잡은 무버의 아이디를 보냄.
											}
										}
									}
								}
								else
								{
									pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_BLITZ );
								}
							}
							else
							{
								pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_BLITZ );
								// 타겟을 안잡았다.
							}
						}
						break;
					case ST_RETREAT:
						{
							g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp );
							// 후퇴 표시
							CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
							if( IsValidObj( pLeader ) == FALSE )
								break;

							for( i = 0; i < m_nSizeofMember; i ++ )
							{
								pMember		= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
								if( IsValidObj( (CObj*)pMember ) )
								{
									if( m_nModeTime[PARTY_GIFTBOX_MODE] || m_nModeTime[PARTY_FORTUNECIRCLE_MODE] )
									{
										pMember->AddHdr( pMember->GetId(), SNAPSHOTTYPE_PARTYSKILL_RETREAT );
									}
									else
									{
										if( pLeader->IsNearPC( pMember ) )
											pMember->AddHdr( pMember->GetId(), SNAPSHOTTYPE_PARTYSKILL_RETREAT );
									}
								}
							}
						}
						break;
					case ST_SPHERECIRCLE:
						{
							// 크리티컬 확률
							CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
							if( IsValidObj( pLeader ) == FALSE )
								break;
							
							if( pLeader->m_idSetTarget != NULL_ID )
							{
								CMover * pT = prj.GetMover( pLeader->m_idSetTarget );
								if( pT && !pT->IsPlayer() )
								{
									g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp );
									for( i = 0; i < m_nSizeofMember; i ++ )
									{
										pMember		= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
										if( IsValidObj( (CObj*)pMember ) )
										{
											if( m_nModeTime[PARTY_GIFTBOX_MODE] || m_nModeTime[PARTY_FORTUNECIRCLE_MODE] )
											{
												pMember->AddHdr( pLeader->m_idSetTarget, SNAPSHOTTYPE_PARTYSKILL_SPHERECIRCLE );
												pMember->m_dwFlag |= MVRF_CRITICAL;
											}
											else
											{
												if( pLeader->IsNearPC( pMember ) )
												{
													pMember->AddHdr( pLeader->m_idSetTarget, SNAPSHOTTYPE_PARTYSKILL_SPHERECIRCLE );
													pMember->m_dwFlag |= MVRF_CRITICAL;
												}
											}
										}
									}
								}
								else
								{
									pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_SPHERECIRCLE );
									// 타겟이 몬스터가 아니다
								}
							}
							else
							{
								pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_SPHERECIRCLE );
								// 타겟을 안잡았다.
							}
//							g_DPCoreClient.SendSetPartyExp( uLeaderid, m_nPoint );
						}
						break;

#if __VER >= 12 // __JHMA_VER12_1	//12차 극단유료아이템
					case ST_LINKATTACK:
						{
							// 데미지 증가
							g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_LINKATTACK_MODE, dwSkillTime, nRemovePoint, nHasCashSkill );
						}
						break;
					case ST_FORTUNECIRCLE:
						{
							// 유니크 아이템 발생확률 증가
								g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_FORTUNECIRCLE_MODE, dwSkillTime, nRemovePoint, nHasCashSkill );
						}
						break;
					case ST_STRETCHING:
						{
							// 쉬는경우 회복속도 높여줌
							g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_STRETCHING_MODE, dwSkillTime, nRemovePoint, nHasCashSkill );
						}
						break;
					case ST_GIFTBOX:
						{
							// 아이템 양이 두배
							g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_GIFTBOX_MODE, dwSkillTime, nRemovePoint, nHasCashSkill );
						}
						break;
#else	//12차 극단유료아이템
					case ST_LINKATTACK:
						{
							// 데미지 증가
							g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_LINKATTACK_MODE, dwSkillTime, nRemovePoint );
						}
						break;
					case ST_FORTUNECIRCLE:
						{
							// 유니크 아이템 발생확률 증가
								g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_FORTUNECIRCLE_MODE, dwSkillTime, nRemovePoint );
						}
						break;
					case ST_STRETCHING:
						{
							// 쉬는경우 회복속도 높여줌
							g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_STRETCHING_MODE, dwSkillTime, nRemovePoint );
						}
						break;
					case ST_GIFTBOX:
						{
							// 아이템 양이 두배
							g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_GIFTBOX_MODE, dwSkillTime, nRemovePoint );
						}
						break;
#endif // //12차 극단유료아이템
					default:
						break;
					}
				}
#ifndef __PARTYDEBUG
				else
				{
					CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
					if( IsValidObj( pLeader ) )
					{
						pLeader->AddSendErrorParty( ERROR_NOTPARTYPOINT );
					}
					//포인트가 모자라 스킬을사용할수 없습니다.
					
				}
#endif // __PARTYDEBUG
			}
#ifndef __PARTYDEBUG
			else
			{
				CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
				if( IsValidObj( pLeader ) )
				{
					pLeader->AddSendErrorParty( ERROR_NOTPARTYSKILL );
				}
				//이 스킬은 배우지를 못했습니다.
			}
#endif // __PARTYDEBUG
		}
	}
	else
	{
		// 리더가 아니거나 순회극단이 아닌경우
	}
#endif	// __WORLDSERVER
}
// 공격 대상을 찾아서 m_idTarget에 세팅한다.
BOOL CAIMonster2::Search()
{
	CMover	*pMover = GetMover();
	CWorld	*pWorld = GetWorld();
	CModelObject *pModel = (CModelObject *)pMover->GetModel();

	FLOAT fRadius = pMover->GetRadiusXZ();		// this의 반지름
	FLOAT fRadiusSq = fRadius * fRadius;		// 반지름Sq버전.
	
	if( m_idTarget == NULL_ID &&										// 공격대상이 정해지지 않았고
		(m_vTarget.x == 0 && m_vTarget.y == 0 && m_vTarget.z == 0) )	// 공격위치도 정해지지 않았다.
	{
		// 어떤 쉐리를 공격할까....? 를 선정함.
		if( SelectTarget() == FALSE )
			return FALSE;
	}

	D3DXVECTOR3	vTarget;
	FLOAT	fDistSq = 0;					// 공격지점과 this의 거리.
	CMover *pTarget = NULL;

	if( m_idTarget != NULL_ID )					// 타겟오브젝이 있을때
	{
		pTarget = prj.GetMover( m_idTarget );
		if( IsValidObj(pTarget) )
			vTarget = pTarget->GetPos();		// 공격좌표는 타겟무버의 좌표
		else
		{
			m_idTarget = NULL_ID;
			return FALSE;						// 타겟이 거시기 하면 걍리턴.
		}
	} 
	else if( m_vTarget.x && m_vTarget.y && m_vTarget.z )		// 공격 좌표로 설정되어 있을때.
	{
		vTarget = m_vTarget;
	} 
	else
	{
		return FALSE;						// 타겟이 거시기 하면 걍리턴.
	}

	D3DXVECTOR3 vDist = vTarget - pMover->GetPos();
	fDistSq = D3DXVec3LengthSq( &vDist );		// 목표지점까지는 거리.
	m_fAttackRange = fRadius;					// 얼마나 근접해야하는가? 디폴트로 반지름 길이.

	if( fDistSq < fRadiusSq * 4.0f )			// 근거리면.
	{
		DWORD dwNum = xRandom( 100 );			// 0 ~ 99까지으 난수.
		
		if( dwNum < 85 )
		{
			if( xRandom( 2 ) )
				m_nAttackType = CAT_NORMAL;		// 앞발로 밟기.
			else
				m_nAttackType = CAT_NORMAL2;

			m_fAttackRange = 5.0f;				// 딱붙어서 밟아야 한다.	??
		}
		else
		{
			m_nAttackType = CAT_QUAKEDOUBLE;	// 두손으로 내려치기 - 스턴
		}
	} 
	else if( fDistSq < fRadiusSq * 6.0f )		// 반지름의 x배 이하는 쏘기.
	{								
		DWORD dwNum = xRandom( 100 );			// 0 ~ 99까지으 난수.
		// 반지름 3배거리 이상이면 원거리.
		if( dwNum < 60 )
		{						
			m_nAttackType = CAT_QUAKE_ONE;		// 하늘에서 돌 떨어뜨리기
			m_fAttackRange = 15.0f;				// xx미터 까지 접근하자.  ??
		}
		else
		{
			m_idTarget = NULL_ID;
			return FALSE;						
		}
	} 
	else
	{
		m_nAttackType = CAT_NORMAL;		// 앞발로 밟기.
		m_fAttackRange = fRadius;		//10.0f;
	}

	return TRUE;
}
void CWndPartyCtrl::OnDraw( C2DRender* p2DRender ) 
{
	if( NULL == g_pPlayer )
		return;

	CPoint pt( 3, 3 );

//	pt.y -= ( m_nFontHeight + 3 ) * m_wndScrollBar.GetScrollPos();

#if __VER < 11 // __CSC_VER11_4
	CWndMessenger* pWndMessenger = (CWndMessenger*)GetWndBase( APP_MESSENGER_ );
#endif //__CSC_VER11_4
	CWndWorld* pWndWorld = (CWndWorld*)g_WndMng.GetWndBase( APP_WORLD );
	
	int nMax = g_Party.m_nSizeofMember;
	// 눈에 보이는 갯수가 페이지라인수 보다 크면 보이는 갯수를 페이지라인수로 조정 
	if( nMax - m_wndScrollBar.GetScrollPos() > m_wndScrollBar.GetScrollPage() )
		nMax = m_wndScrollBar.GetScrollPage() + m_wndScrollBar.GetScrollPos();
	if( nMax < m_wndScrollBar.GetScrollPos() )
		nMax = 0;
	
	TEXTUREVERTEX2* pVertex = new TEXTUREVERTEX2[ 6 * 2 * nMax ];
	TEXTUREVERTEX2* pVertices = pVertex;
	
	for( int i = m_wndScrollBar.GetScrollPos(); i < nMax; i++ ) 
	{
		CMover* pObjMember = prj.GetUserByID( g_Party.m_aMember[i].m_uPlayerId );
		CString strMember;
#if __VER >= 11 // __SYS_PLAYER_DATA
		PlayerData* pPlayerData	= CPlayerDataCenter::GetInstance()->GetPlayerData( g_Party.m_aMember[i].m_uPlayerId );
		int nJob	= pPlayerData->data.nJob;
		int nSex	= pPlayerData->data.nSex;
#else	// __SYS_PLAYER_DATA
		int nJob	= g_Party.m_aMember[ i ].m_nJob;
		int nSex	= g_Party.m_aMember[ i ].m_nSex;
#endif	// __SYS_PLAYER_DATA
		
		// 상태에 따라 색 변경
		DWORD dwColor = 0xff000000;
		if( IsValidObj(pObjMember) )
		{
			if( pObjMember->GetHitPoint() == 0 ) 
				dwColor = 0xffff0000; // 죽은놈
			else 
				if( ((FLOAT)pObjMember->GetHitPoint()) / ((FLOAT)pObjMember->GetMaxHitPoint()) < 0.1f ) 
					dwColor = 0xffffff00; // HP 10% 이하인 놈
			strMember.Format( "%d %s", pObjMember->GetLevel(), pObjMember->GetName() );
		}
		else
		{
			dwColor = 0xff878787; // 디폴트는 주위에 없는 놈
			if( g_Party.m_aMember[ i ].m_bRemove ) 
				dwColor = 0xff000000; // 서버에 없는 놈
#if __VER >= 11 // __SYS_PLAYER_DATA
			strMember.Format( "?? %s", pPlayerData->szPlayer );
#else	// __SYS_PLAYER_DATA
			strMember.Format( "?? %s", g_Party.m_aMember[ i ].m_szName );
#endif	// __SYS_PLAYER_DATA
		}
		if( i == m_nCurSelect )
			dwColor = 0xff6060ff; 

		int x = 0, nWidth = m_rectClient.Width() - 10;// - 1;

		CRect rect( x, pt.y, x + nWidth, pt.y + m_nFontHeight );

		rect.SetRect( x + 20, pt.y + 18, x + nWidth - 10, pt.y + 30 ); 
		nWidth	= pObjMember ? pObjMember->GetHitPointPercent( rect.Width() ) : 0;
		CRect rectTemp = rect; 
		rectTemp.right = rectTemp.left + nWidth;
		if( rect.right < rectTemp.right )
			rectTemp.right = rect.right;

		m_pTheme->RenderGauge( p2DRender, &rect, 0xffffffff, m_pVBGauge, &m_texGauEmptyNormal );
		m_pTheme->RenderGauge( p2DRender, &rectTemp, 0x64ff0000, m_pVBGauge, &m_texGauFillNormal );

		rect.SetRect( x + 3, pt.y, x + 3 + 32, pt.y + 6 + 32 ); 

		p2DRender->TextOut( x + 20, pt.y + 3, strMember, dwColor ); 

		if( MAX_EXPERT <= nJob )
		{
#if __VER >= 10 // __LEGEND
			if( MAX_PROFESSIONAL <= nJob && nJob < MAX_MASTER )
				pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  ( 70 + nJob - 16 ) + ( 8 * nSex ), &pVertices, 0xffffffff );
			else if( MAX_MASTER <= nJob )
				pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  ( 70 + nJob - 24 ) + ( 8 * nSex ), &pVertices, 0xffffffff );
			else
#endif //__LEGEND
			pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  ( 70 + nJob - 6 ) + ( 8 * nSex ), &pVertices, 0xffffffff );
		}
		else
		{
			pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  12 + nJob + ( 6 * nSex ), &pVertices, 0xffffffff );
		}

		pt.y += m_nFontHeight + 3;
	}
	pWndWorld->m_texMsgIcon.Render( m_pApp->m_pd3dDevice, pVertex, ( (int) pVertices - (int) pVertex ) / sizeof( TEXTUREVERTEX2 ) );
	safe_delete_array( pVertex );
}
BOOL CAIMonster2::SelectTarget()
{
	CMover	*pMover = GetMover();
	CWorld	*pWorld = GetWorld();
	int		nAttackFirstRange = pMover->GetProp()->m_nAttackFirstRange;

	FLOAT fRadius = pMover->GetRadiusXZ();		// this의 반지름
	FLOAT fRadiusSq = fRadius * fRadius;		// 반지름Sq버전.
	
	CMover *pLastAttacker = prj.GetMover( m_idLastAttacker );
	if( IsValidObj( pLastAttacker ) && pLastAttacker->IsDie() )
	{
		m_idLastAttacker = NULL_ID;
		pLastAttacker = NULL;
	}
	
	if( pLastAttacker == NULL )			// LastAttacker가 없어졌으면 타겟 다시 잡을 수 있도록 하자.
	{
		m_idLastAttacker = NULL_ID;
	} 
	else
	{		
		D3DXVECTOR3 vDist = pLastAttacker->GetPos() - pMover->GetPos();
		FLOAT fDistSq = D3DXVec3LengthSq( &vDist );		// 목표지점까지의 거리.
		if( fDistSq >= fRadiusSq * 10.0f )				// 라스트어태커가 내 반지름의 10배이상 떨어져있으면
		{
			// 타겟 포기
			m_idLastAttacker = NULL_ID;
			pLastAttacker = NULL;
		}
	}

	m_idTarget = NULL_ID;
	m_vTarget.x = m_vTarget.y = m_vTarget.z = 0;	// 일단 이건 안쓰는걸로 하자.

	if( m_idLastAttacker == NULL_ID )		// 아직 날 때린쉐리가 없다.
	{
		CMover* pTarget = NULL;
		pTarget = ScanTarget( pMover, nAttackFirstRange, JOB_ALL );		
		if( pTarget )
		{
			if( pMover->IsFlyingNPC() == pTarget->m_pActMover->IsFly() )	// 위상이 같으면 OK
				m_idTarget = pTarget->GetId();
			else
				return FALSE;		
		} 
		else
			return FALSE;
	} 
	else
	{
		// 날 때린 쉐리가 있다.
		DWORD dwNum = xRandom( 100 );		// 0 ~ 99까지으 난수.
		DWORD dwAggroRate = 50;
		
		if( IsValidObj( pLastAttacker ) )
		{
			if( pLastAttacker->GetJob() == JOB_MERCENARY )		// 마지막으로 날때린 쉐리가 머서면 어그로 좀더 주자.
				dwAggroRate = 70;
		}

		if( dwNum < dwAggroRate )		
		{
			// dwAggroRate% 확률로 마지막으로 날 때린넘 공격.
			m_idTarget = m_idLastAttacker;		// 날 공격한 쉐리를 타겟으로 지정하자.
		} 
		else if( dwNum < 75 )
		{
			// 50미터 반경내에서 가장 쎈넘을 잡자.
			CMover *pTarget = ScanTargetStrong( pMover, (float)( nAttackFirstRange ) );
			if( pTarget )
			{
				// this가 비행형 몬스터거나 || 타겟이 비행중이 아닐때만 공격.
				if( pMover->IsFlyingNPC() == pTarget->m_pActMover->IsFly() )	
					m_idTarget = pTarget->GetId();
				else
					m_idTarget = m_idLastAttacker;		// 타겟이 공격하기가 여의치 않으면 마지막으로 때린쉐리 공격하자.
			} 
			else
				m_idTarget = m_idLastAttacker;		// 타겟이 공격하기가 여의치 않으면 마지막으로 때린쉐리 공격하자.
		} 
		else if( dwNum < 100 )
		{
			// 오버힐하는 어시를 죽이자.
			CMover *pTarget = ScanTargetOverHealer( pMover, (float)( nAttackFirstRange ) );
			if( pTarget )
			{
				// this가 비행형 몬스터거나 || 타겟이 비행중이 아닐때만 공격.
				if( pMover->IsFlyingNPC() == pTarget->m_pActMover->IsFly() )	
					m_idTarget = pTarget->GetId();
				else
					m_idTarget = m_idLastAttacker;		// 타겟이 공격하기가 여의치 않으면 마지막으로 때린쉐리 공격하자.
			} 
			else
				m_idTarget = m_idLastAttacker;		// 타겟이 공격하기가 여의치 않으면 마지막으로 때린쉐리 공격하자.
		}
	}

	return TRUE;
}
Beispiel #5
0
//
//	Action Message Process
//	액션 메시지를 받아 처리한다.
//	어떤 행위가 발생하는 시점에 대한 처리를 담당.
//	최적화를 위해서 이미 설정되어 있는 상태면 중복 처리 하지 않음
//
int		CActionMover::ProcessActMsg1( CMover* pMover,  OBJMSG dwMsg, int nParam1, int nParam2, int nParam3, int nParam4, int nParam5 )
{
	CModelObject* pModel = (CModelObject*)pMover->m_pModel;

	switch( dwMsg )
	{
	// 평화모드 제자리에 서있어라!
	case OBJMSG_STAND:
#ifdef __Y_INTERFACE_VER3
		if( (GetMoveState() == OBJSTA_FMOVE) || (GetMoveState() == OBJSTA_BMOVE) || (GetMoveState() == OBJSTA_LMOVE) || (GetMoveState() == OBJSTA_RMOVE) )	// 전/후진중일때 제자리에 세운다.
#else //__Y_INTERFACE_VER3
		if( (GetMoveState() == OBJSTA_FMOVE) || (GetMoveState() == OBJSTA_BMOVE) )	// 전/후진중일때 제자리에 세운다.
#endif //__Y_INTERFACE_VER3
		{
			ResetState( OBJSTA_MOVE_ALL );		
			m_vDelta.x = m_vDelta.z = 0;
			if( pMover->IsFlyingNPC() )
			{
				m_vDelta.y = 0;
				pMover->SetAngleX(0);
			}
		}

		if( GetMoveState() == OBJSTA_STAND )	return 0;
		if( GetMoveState() == OBJSTA_PICKUP )	return 0;
		if( IsActJump() )		return -1;
		if( IsActAttack() )		return -2;
		if( IsActDamage() )		return -3;
		if( IsDie() )			return -4;
		if( IsAction() )		return 0;
		SetMoveState( OBJSTA_STAND );
		pMover->SetMotion( MTI_STAND );
		RemoveStateFlag( OBJSTAF_ETC );
		break;
	case OBJMSG_STOP:		
	case OBJMSG_ASTOP:
	#ifdef __Y_INTERFACE_VER3
		if( (GetMoveState() == OBJSTA_FMOVE) || (GetMoveState() == OBJSTA_BMOVE) || (GetMoveState() == OBJSTA_LMOVE) || (GetMoveState() == OBJSTA_RMOVE) )	// 전/후진중일때 제자리에 세운다.
	#else //__Y_INTERFACE_VER3
		if( (GetMoveState() == OBJSTA_FMOVE) || (GetMoveState() == OBJSTA_BMOVE) )	// 전/후진중일때 제자리에 세운다.
	#endif //__Y_INTERFACE_VER3
		{
			ResetState( OBJSTA_MOVE_ALL );		
			m_vDelta.x = m_vDelta.z = 0;
			if( pMover->IsFlyingNPC() )
			{
				m_vDelta.y = 0;
				pMover->SetAngleX(0);
			}
		}
		pMover->ClearDest();
		return 0;	// ControlGround에서 키입력없을때 STOP을 부르는데 거기서 리턴값을 맞추기 위해 이렇게 했음. 
		break;
	case OBJMSG_SITDOWN:
		if( GetStateFlag() & OBJSTAF_SIT )	return 0;		// 이미 앉은모드면 리턴 - 플래그로 검사하지 말고 state로 직접검사하자.

		if( nParam3 == 0 )
		{
			if( IsActJump() )	return 0;
			if( IsActAttack() )	return 0;
			if( IsActDamage() )	return 0;
			if( IsAction() )	return 0;
		#ifdef __CLIENT
			if( pMover->IsActiveMover() && (pMover->m_dwReqFlag & REQ_USESKILL) )	return 0;		// 서버로부터 useskill응답이 오기전까진 액션해선 안됨.
		#endif	// __CLIENT
		}
		AddStateFlag( OBJSTAF_SIT );		
		SendActMsg( OBJMSG_STOP );
		pMover->SetMotion( MTI_SIT, ANILOOP_CONT );		// 앉기 모션시작
		SetMoveState( OBJSTA_SIT );
		break;
	case OBJMSG_STANDUP:
		if( (GetStateFlag() & OBJSTAF_SIT) == 0 )	return 0;	

		if( nParam3 == 0 )
		{
			if( IsActJump() )	return 0;
			if( IsActAttack() )	return 0;
			if( IsActDamage() )	return 0;
			if( IsAction() )	return 0;
#ifdef __CLIENT
			if( pMover->IsActiveMover() && (pMover->m_dwReqFlag & REQ_USESKILL) )	return 0;		// 서버로부터 useskill응답이 오기전까진 액션해선 안됨.
#endif	// __CLIENT
		}
		SetMoveState( OBJSTA_SIT );
		AddStateFlag( OBJSTAF_SIT );		 
		pMover->SetMotion( MTI_GETUP, ANILOOP_CONT );
		break;
	case OBJMSG_PICKUP:
		if( IsSit() )	return 0;
		if( IsAction() )	return 0;
		if( IsActJump() )	return 0;
		if( IsActAttack() )	return 0;
		if( IsActDamage() )	return 0;
#ifdef __CLIENT
		if( pMover->IsActiveMover() )
		{
			if( pMover->m_dwReqFlag & REQ_USESKILL )	return 0;		// 서버로부터 useskill응답이 오기전까진 액션해선 안됨.
			if( pMover->m_dwReqFlag & REQ_MOTION )		return 0;	// 서버로부터 모션 응답이 오기전까지 액션 금지.
		}
#endif	// __CLIENT
		if( GetMoveState() == OBJSTA_PICKUP )	return 0;	// 이미 집고 있으면 추가로 실행되지 않게 .
		SetMoveState( OBJSTA_PICKUP );
		pMover->SetMotion( MTI_PICKUP, ANILOOP_1PLAY, MOP_FIXED );
		break;

	case OBJMSG_COLLECT:
		
		//if( IsSit() )		return 0;
		//if( IsAction() )	return 0;
		//if( IsActJump() )	return 0;
		//if( IsActAttack() )	return 0;
		//if( IsActDamage() )	return 0;
		//SetState( OBJSTA_ACTION_ALL, OBJSTA_COLLECT );
		//pMover->SetMotion( MTI_COLLECT, ANILOOP_LOOP, MOP_FIXED );
		//pMover->RemoveInvisible();
		
		// 康	// 채집
		ClearState();
		ResetState( OBJSTA_ACTION_ALL );
		SetState( OBJSTA_ACTION_ALL, OBJSTA_COLLECT );
		//pMover->m_dwFlag |= MVRF_NOACTION;
		pMover->SetMotion( MTI_COLLECT, ANILOOP_LOOP, MOP_FIXED );
		pMover->RemoveInvisible();
		break;

	case OBJMSG_STUN:
		SetState( OBJSTA_ACTION_ALL, OBJSTA_STUN );		// 스턴은 어떤 상태에서도 걸릴 수 있으니 상태는 무조것 세팅하자.
		pMover->m_dwFlag |= MVRF_NOACTION;				// 액션 금지 상태로 전환.
		pMover->m_wStunCnt = (short)nParam1;			// 얼마동안이나 스턴상태가 되느냐.

		if( GetState() == OBJSTA_STAND )
			pMover->SetMotion( MTI_GROGGY, ANILOOP_LOOP, MOP_FIXED );		// 아무것도 안하는 스탠딩 상태면 스턴 모션 내자.
		break;
		
	case OBJMSG_FALL:
		if( IsActJump() )	return 0;

		// 무적이면 여기서 리턴.
		if( pMover->m_dwMode & MATCHLESS_MODE )		
			return 0;
		
		pMover->m_dwFlag |= MVRF_NOACTION;				// 액션 금지 상태로 전환.
		
		if( GetState() != OBJSTA_DMG_FLY )
		{
			SetState( OBJSTA_DMG_ALL, OBJSTA_DMG_FLY );	
			pMover->SetMotion( MTI_DMGFLY, ANILOOP_LOOP, MOP_FIXED );
		}
		break;
		
	// 전진해라!
	case OBJMSG_TURNMOVE:
		if( GetMoveState() == OBJSTA_FMOVE && (int)pMover->GetAngle() == nParam1 )	return 0;	// 전진 상태이며 각도가 같으면 메시지 무효 
		if( pMover->m_dwFlag & MVRF_NOMOVE )	
			return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans
		
		if( GetState() & OBJSTA_DMG_FLY_ALL )	// 날라가는 동작중이면 취소
			return 0;
		
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
			return -3;
		pMover->SetAngle( (float)nParam1 );
		if( pMover->IsFlyingNPC() )
			pMover->SetAngleX( (float)nParam2 );
		SendActMsg( OBJMSG_STOP_TURN );
		SendActMsg( OBJMSG_FORWARD );
		break;
	case OBJMSG_TURNMOVE2:
		if( GetMoveState() == OBJSTA_FMOVE && (int)pMover->GetAngle() == nParam1 )	return 0;	// 전진 상태이며 각도가 같으면 메시지 무효 
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		if( IsAction() )	return 0;

		if( GetState() & OBJSTA_DMG_FLY_ALL )	// 날라가는 동작중이면 취소
			return 0;

		if( IsActJump() )	return -1;	// 점프거나 공격 상태면 메시지 무효 처리
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
			return -3;
		pMover->SetAngle( (float)nParam1 );
		if( pMover->IsFlyingNPC() )
			pMover->SetAngleX( (float)nParam2 );
		SendActMsg( OBJMSG_STOP_TURN );
		SendActMsg( OBJMSG_BACKWARD );
		break;

#ifdef __Y_INTERFACE_VER3
	case OBJMSG_LFORWARD:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else
			if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -3;
		if( GetMoveState() == OBJSTA_LMOVE )	return 0;	// 이미 전진상태면 추가로 처리 하지 않음
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetMoveState( OBJSTA_LMOVE );
		if( IsStateFlag( OBJSTAF_WALK ) )	// 걷는모드
		{
			pMover->SetMotion( MTI_WALK );		// 전투모드로 걷기
		} 
		else
		{
			if( pMover->SetMotion( MTI_RUN ) )
				pModel->SetMotionBlending( TRUE );
		}
		break;
	case OBJMSG_RFORWARD:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else
			if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -3;
		if( GetMoveState() == OBJSTA_RMOVE )	return 0;	// 이미 전진상태면 추가로 처리 하지 않음
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetMoveState( OBJSTA_RMOVE );
		if( IsStateFlag( OBJSTAF_WALK ) )	// 걷는모드
		{
			pMover->SetMotion( MTI_WALK );		// 전투모드로 걷기
		} 
		else
		{
			if( pMover->SetMotion( MTI_RUN ) )
				pModel->SetMotionBlending( TRUE );
		}
		break;
#endif //__Y_INTERFACE_VER3

	case OBJMSG_FORWARD:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -3;
		if( GetMoveState() == OBJSTA_FMOVE )	return 0;	// 이미 전진상태면 추가로 처리 하지 않음
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetMoveState( OBJSTA_FMOVE );
		if( IsStateFlag( OBJSTAF_WALK ) )	// 걷는모드
		{
			pMover->SetMotion( MTI_WALK );	
		} 
		else
		{
			if( pMover->SetMotion( MTI_RUN ) )
				pModel->SetMotionBlending( TRUE );
		}
		pMover->OnActFMove();
		break;
		
	case OBJMSG_STOP_RUN:
	#ifdef __CLIENT
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
			return -3;
		if( GetMoveState() == OBJSTA_STOP_RUN )	return 0;	// 이미 전진상태면 추가로 처리 하지 않음
		if( IsSit() )		return 0;						// 리턴 0으로 해도 되나?.
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;	// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetMoveState( OBJSTA_STOP_RUN );
	#endif
		break;

	
	// 후진해라!
	case OBJMSG_BACKWARD:
		if( IsActJump() )	return -1;	// if jump, x
		if( IsActAttack() )		return -2;	// 공격동작중이면 취소됨.
		if( IsActDamage() )		return -3;
		if( GetMoveState() == OBJSTA_BMOVE )	return 0;
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( IsAction() )	return 0;
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetMoveState( OBJSTA_BMOVE );
		pMover->SetMotion( MTI_WALK );		
		break;
	// 좌/우 턴 해라!
	case OBJMSG_LTURN:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -3;
		if( GetTurnState() == OBJSTA_LTURN )	return 0;
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( IsAction() )	return 0;
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetTurnState( OBJSTA_LTURN );
		break;
	case OBJMSG_RTURN:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
			return -3;
		if( GetTurnState() == OBJSTA_RTURN )	return 0;
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( IsAction() )	return 0;
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetTurnState( OBJSTA_RTURN );
		break;
	case OBJMSG_STOP_TURN:
		if( GetTurnState() == 0 )		return 0;		// 이미 턴 상태가 없다면 처리 안함
		SetTurnState( 0 );		// 턴을 중지
		break;

	// 피치를 들어올림. 비행몹의 경우만 사용.
	case OBJMSG_LOOKUP:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
			return -3;
		if( GetTurnState() == OBJSTA_LOOKUP )	return 0;
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( IsAction() )	return 0;
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetLookState( OBJSTA_LOOKUP );
		break;
	case OBJMSG_LOOKDOWN:
		if( IsActJump() )	return -1;
		if( IsActAttack() )		return -2;
		if( GetDmgState() == OBJSTA_DMG )	// 피격 중 명령이면 피격 상태를 클리어 시킨다.
			ResetState( OBJSTA_DMG_ALL );
		else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
			return -3;
		if( GetTurnState() == OBJSTA_LOOKDOWN )	return 0;
		if( IsSit() )		return 0;		// 리턴 0으로 해도 되나?.
		if( IsAction() )	return 0;
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

		SetLookState( OBJSTA_LOOKDOWN );
		break;
	case OBJMSG_STOP_LOOK:
		if( GetLookState() == 0 )		return 0;
		SetLookState( 0 );		// 룩 중지
		break;
		// 점프
	case OBJMSG_JUMP:
		if( IsActJump() )		return 0;
		if( IsActAttack() )		return -2;
		if( IsActDamage() )		return -3;
		if( IsSit() )			return 0;		// 리턴 0으로 해도 되나?.
		if( IsAction() )		return 0;
		if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

#ifdef __CLIENT
		if( pMover->IsActiveMover() )
		{
			if( pMover->m_dwReqFlag & REQ_USESKILL )	return 0;	// 서버로부터 useskill응답이 오기전까진 점프해선 안됨.
			if( pMover->m_dwReqFlag & REQ_MOTION )		return 0;	// 서버로부터 모션 응답이 오기전까지 점프 금지.
		}
#endif	// __CLIENT
		SendActMsg( OBJMSG_STOP_TURN );
		SetJumpState( OBJSTA_SJUMP1 );
		if( (GetState() & OBJSTA_COLLECT)== 0 ) pMover->SetMotion( MTI_JUMP1, ANILOOP_1PLAY );
		pModel->SetMotionBlending( FALSE );
		break;
	// 완드공격
	case OBJMSG_ATK_MAGIC1:	// 공격 1
		{
			if( IsAction() )	return 0;
			if( IsSit() )		// 앉아있는상태였으면 해제
				ResetState( OBJSTA_MOVE_ALL );
			if( GetState() & OBJSTA_ATK_ALL )	return 0;		// 이미 공격동작을 하고 있으면 취소.
			if( pMover->m_dwFlag & MVRF_NOATTACK )	return -1;		// 공격금지 상태면 걍 리턴.
			if( pMover->IsMode( NO_ATTACK_MODE ) ) return -1;
			CMover* pHitObj		= prj.GetMover( nParam1 );
			if( IsInvalidObj( pHitObj ) )	return -1;
			if( pHitObj->IsDie() )	return -1;
#ifdef __WORLDSERVER
			if( !g_eLocal.GetState( EVE_STEAL ) )
			{
				if( pMover->IsSteal( pHitObj ) )	// pHitObj를 스틸하려하면 이공격은 무시.
					return -1;
			}
#endif
			if( IsActDamage() )
				ResetState( OBJSTA_DMG_ALL );
			if( IsStateFlag( OBJSTAF_COMBAT ) == FALSE )
				SendActMsg( OBJMSG_MODE_COMBAT );
		
			SendActMsg( OBJMSG_STOP_TURN );
			SendActMsg( OBJMSG_STAND );
			SetState( OBJSTA_ATK_ALL, OBJSTA_ATK_MAGIC1 );
			pMover->SetMotion( MTI_ATK1, ANILOOP_1PLAY );		// 완드동작이 없으므로 공격동작으로 대신함.
			pHitObj->SetJJim( pMover );
			pMover->m_nAtkCnt = 1;		// 카운트 시작.
			pMover->OnAttackStart( pHitObj, dwMsg );			// 공격시작 핸들러.
		}
		break;
		// 레인지공격
	case OBJMSG_ATK_RANGE1:	// 공격 1
		{
			if( IsAction() )	return 0;
			if( pMover->m_dwFlag & MVRF_NOATTACK )	return -1;		// 공격금지 상태면 걍 리턴.
			if( pMover->IsMode( NO_ATTACK_MODE ) ) return -1;
			if( IsSit() )		// 앉아있는상태였으면 해제
				ResetState( OBJSTA_MOVE_ALL );
			if( GetState() & OBJSTA_ATK_ALL )	return 0;		// 이미 공격동작을 하고 있으면 취소.
			CMover* pHitObj		= prj.GetMover( nParam1 );
			if( IsValidObj( (CObj*)pHitObj ) == FALSE )	
				return -1;
			if( pHitObj->IsDie() )
				return -1;

			m_idTarget = (DWORD)nParam1;		// 공격 타겟.

#ifdef __WORLDSERVER
			if( !g_eLocal.GetState( EVE_STEAL ) )
			{
				if( pMover->IsSteal( pHitObj ) )	// pHitObj를 스틸하려하면 이공격은 무시.
					return -1;
			}
#endif
			if( GetDmgState() == OBJSTA_DMG )	// 피격 중 공격명령이면 피격 상태를 클리어 시킨다.
				ResetState( OBJSTA_DMG_ALL );
			else if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -1;
			if( IsStateFlag( OBJSTAF_COMBAT ) == FALSE )
				SendActMsg( OBJMSG_MODE_COMBAT );
			
			int nUseMotion = nParam2;
//			SendActMsg( OBJMSG_STOP_TURN );
//			SendActMsg( OBJMSG_STAND );
			SetState( OBJSTA_ATK_ALL, OBJSTA_ATK_RANGE1 );
			pMover->SetMotion( nUseMotion, ANILOOP_1PLAY );		// 완드동작이 없으므로 공격동작으로 대신함.
			pHitObj->SetJJim( pMover );			// 공격이 시작되면 타겟에다가 내가 찜했다는걸 표시.
			pMover->OnAttackStart( pHitObj, dwMsg );			// 공격시작 핸들러.
			pMover->m_nAtkCnt = 1;		// 카운트 시작.
		}
		break;
		// 공격 - 리턴값 -2는 클라로 부터 받은 명령을 완전 무시한다.
	case OBJMSG_ATK1:	// 공격 1
	case OBJMSG_ATK2:	// 공격 2
	case OBJMSG_ATK3:	// 공격 3	
	case OBJMSG_ATK4:	// 공격 4
		{
			if( IsAction() )
				return 0;
			if( pMover->m_dwFlag & MVRF_NOATTACK )
				return -2;		// 공격금지 상태면 걍 리턴.
			if( pMover->IsMode( NO_ATTACK_MODE ) )
				return -2;

#ifdef __CLIENT
			if( pMover->IsActiveMover() )
#endif
			{
				// 기본은 오른손 검사( 완드용 )
				CItemElem* pItemElem = pMover->GetWeaponItem();
				if( pItemElem && (pItemElem->GetProp()->dwItemKind3 == IK3_WAND || pItemElem->GetProp()->dwItemKind3 == IK3_BOW ) )
					return -2;
			}
				
			CMover* pHitObj		= prj.GetMover( nParam1 );
			if( IsValidObj( (CObj*)pHitObj ) == FALSE )
				return( -1 );

#ifdef __XUZHU
			if( pMover->IsPlayer() )
			{
				int a = 0;
			}
#endif // xuzhu
			m_idTarget = (DWORD)nParam1;		// 공격 타겟.
#ifdef __WORLDSERVER
			if( !g_eLocal.GetState( EVE_STEAL ) )
			{
				if( pMover->IsSteal( pHitObj ) )	// pHitObj를 스틸하려하면 이공격은 무시.
					return -2;
			}
#endif
			if( pHitObj->m_pActMover->IsDie() )	return( -1 );
			if( GetState() & OBJSTA_ATK_ALL )	return( 0 );	// 이미 공격중이면 리턴
			if( IsSit() )		// 앉아있는상태였으면 해제
				ResetState( OBJSTA_MOVE_ALL );
			if( GetDmgState() == OBJSTA_DMG )	// 피격 중 공격명령이면 피격 상태를 클리어 시킨다.
				ResetState( OBJSTA_DMG_ALL );
			else
			if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -3;
			if( IsStateFlag( OBJSTAF_COMBAT ) == FALSE )
				SendActMsg( OBJMSG_MODE_COMBAT );
			SendActMsg( OBJMSG_STOP_TURN );	// 공격할땐 턴을 정지시킴
			SendActMsg( OBJMSG_STAND );
			

			DWORD dwOption = MOP_SWDFORCE | MOP_NO_TRANS;
			
#ifdef __XSLOW1018
			int nMin, nTemp;
			pMover->GetHitMinMax( &nMin, &nTemp );
			if( dwMsg == OBJMSG_ATK3 || dwMsg == OBJMSG_ATK4 )
				if( pMover->GetLevel() >= 12 && pHitObj->GetHitPoint() < (int)(nMin * 1.5f) )
					dwOption |= MOP_HITSLOW;
#endif // xSlow1018
			if( pMover->IsPlayer() )
				pMover->m_fAniSpeed = pMover->GetAttackSpeed();
			
			switch( dwMsg )
			{
				case OBJMSG_ATK1:
					SetState( OBJSTA_ATK_ALL, OBJSTA_ATK1 );
					pMover->SetMotion( MTI_ATK1, ANILOOP_1PLAY, dwOption );		// 최초 메시지 입력시 동작 설정
					break;
				case OBJMSG_ATK2:	
					SetState( OBJSTA_ATK_ALL, OBJSTA_ATK2 );
					pMover->SetMotion( MTI_ATK2, ANILOOP_1PLAY, dwOption );		// 최초 메시지 입력시 동작 설정
					break;
				case OBJMSG_ATK3:	
					SetState( OBJSTA_ATK_ALL, OBJSTA_ATK3 );
					pMover->SetMotion( MTI_ATK3, ANILOOP_1PLAY, dwOption );		// 최초 메시지 입력시 동작 설정
					break;
				case OBJMSG_ATK4:	
					SetState( OBJSTA_ATK_ALL, OBJSTA_ATK4 );
					pMover->SetMotion( MTI_ATK4, ANILOOP_1PLAY, dwOption );		// 최초 메시지 입력시 동작 설정
					break;
			}
			pMover->SetAngle( GetDegree( pHitObj->GetPos(), m_pMover->GetPos() ) );
			pHitObj->SetJJim( pMover );

			pMover->m_nAtkCnt = 1;		// 카운트 시작.
			pMover->OnAttackStart( pHitObj, dwMsg );			// 공격시작 핸들러.
			m_objidHit	= (OBJID)nParam1;	// 타겟의 아이디.	

			m_dwAtkFlags	= (DWORD)LOWORD( (DWORD)nParam3 );
#ifdef __WORLDSERVER
			if( m_dwAtkFlags == 0 ) 
			{
				if( pMover->GetAttackResult( pHitObj, dwOption ) )		// 공격 성공률을 얻는다.
					m_dwAtkFlags = AF_GENERIC;
				else
					m_dwAtkFlags = AF_MISS;
			}
#else
			m_dwAtkFlags = AF_GENERIC;		// 구조가 좀 이상한데. 클라에서는 명중판정을 하지 않으므로 무조건 평타명중으로 인정.
#endif
			
			return( (int)m_dwAtkFlags );
			break;
		}	
	// 몬스터들의 특수공격.
	case OBJMSG_SP_ATK1:
	case OBJMSG_SP_ATK2:
		{
			CMover* pHitObj		= prj.GetMover( nParam1 );
			//nParam2;		// 특수공격에 사용할 무기. 보통은 몬스터이므로 가상아이템이 들어온다.
			int		nUseMotion	= nParam3;		// 사용할 모션.
			if( IsValidObj( (CObj*)pHitObj ) == FALSE )	return( -1 );
			if( pHitObj->m_pActMover->IsDie() )	return( -1 );
			if( GetState() & OBJSTA_ATK_ALL )	return( 0 );	// 이미 공격중이면 리턴
			if( pMover->m_dwFlag & MVRF_NOATTACK )	return 0;		// 공격금지 상태면 걍 리턴.
			if( GetDmgState() == OBJSTA_DMG )	// 피격 중 공격명령이면 피격 상태를 클리어 시킨다.
				ResetState( OBJSTA_DMG_ALL );
			else
			if( GetState() & OBJSTA_DMG_ALL )	// 그외 피격동작은 다 취소
				return -3;
			if( IsStateFlag( OBJSTAF_COMBAT ) == FALSE )
				SendActMsg( OBJMSG_MODE_COMBAT );
			SendActMsg( OBJMSG_STOP_TURN );	// 공격할땐 턴을 정지시킴
			SendActMsg( OBJMSG_STAND );

			DWORD dwOption = MOP_SWDFORCE /*| MOP_NO_TRANS*/;	// 몬스터니까 공격동작도 모션트랜지션 되게 해봤다.
			SetState( OBJSTA_ATK_ALL, OBJSTA_SP_ATK1 );
			pMover->SetMotion( nUseMotion, ANILOOP_1PLAY, dwOption );		// 최초 메시지 입력시 동작 설정
			pMover->SetAngle( GetDegree( pHitObj->GetPos(), m_pMover->GetPos() ) );
			pMover->OnAttackStart( pHitObj, dwMsg );			// 공격시작 핸들러.
			return 1;
		}
		break;

	// 전사들의 근접 전투스킬류
	case OBJMSG_MELEESKILL:
		{
			if( IsAction() )	return -2;	
			if( pMover->m_dwFlag & MVRF_NOATTACK )	return -2;		// 공격금지 상태면 걍 리턴.
			CMover* pHitObj		= prj.GetMover( nParam2 );
			if( IsValidObj( pHitObj ) == FALSE )	return -2;
#ifdef __WORLDSERVER
			if( GetState() & OBJSTA_ATK_RANGE1 )
				ResetState( OBJSTA_ATK_RANGE1 );
			if( GetState() & OBJSTA_ATK_ALL )	return -2;	// 이미 공격중이면 리턴. 서버에선 씹히지 않게 하자.
			pMover->m_dwMotion = -1;	// 나머지 경우는 간단하게 생각하기 위해 모두 클리어 시키고 스킬만 실행하자.
			ClearState();				// 상태 클리어하고 다시 맞춤,.
#else
			// 이리저리 해보니 액티브 무버건 아니건 서버에서 신호오면 바로 시작하는게 좋을거 같애서 이렇게 함.
			pMover->m_dwMotion = -1;	
			ClearState();				// 상태 클리어하고 다시 맞춤,.
#endif
			SetState( OBJSTA_ATK_ALL, OBJSTA_ATK_MELEESKILL );			// 근접전투스킬상태 설정.
			DWORD dwMotion = (DWORD)nParam1;
			int	nLoop = ANILOOP_1PLAY;

			int	nSkill = pMover->GetActParam( 0 );
			if( nSkill == SI_BLD_DOUBLESW_SILENTSTRIKE || nSkill == SI_ACR_YOYO_COUNTER )
				nLoop = ANILOOP_CONT;

#ifdef __CLIENT			
			if( pMover->HasBuffByIk3( IK3_TEXT_DISGUISE ) )
				dwMotion = MTI_ATK1;
#endif

			pMover->SetMotion( dwMotion, nLoop, MOP_SWDFORCE | MOP_NO_TRANS | MOP_FIXED );		// 해당 동작애니 시작.
			pMover->OnAttackStart( pHitObj, dwMsg );			// 공격시작 핸들러.
			
			m_nMotionHitCount = 0;
			
			break;
		}
	// 마법사들의 마법스킬류.
	case OBJMSG_MAGICSKILL:
	case OBJMSG_MAGICCASTING:
		{
			if( IsAction() )	return -2;
			if( pMover->m_dwFlag & MVRF_NOATTACK )	return -2;		// 공격금지 상태면 걍 리턴.
			CMover* pHitObj		= prj.GetMover( nParam2 );
			if( IsValidObj( pHitObj ) == FALSE )	return -2;
		#ifdef __WORLDSERVER
			if( GetState() & OBJSTA_ATK_ALL )	return -2;	// 이미 공격중이면 리턴
		#endif  

			pMover->m_dwMotion = -1;	
			ClearState();				// 상태 클리어하고 다시 맞춤.

			m_nCastingTime	= nParam3 * 4;	// ProcessAction은 서버/클라 호출 회수 동일하므로, SEC1 사용이 적당하지 않다.

#if __VER >= 10 // __LEGEND	//	9차 전승시스템	Neuz, World, Trans
			m_dwCastingEndTick = (DWORD)( GetTickCount() + nParam3 * 66.66F );
			m_nCastingTick	= (int)( nParam3 * 66.66F );
			m_nCastingSKillID = nParam4;
#endif	//__LEGEND	//	9차 전승시스템	Neuz, World, Trans
			if( m_nCastingTime > 0 )	// 캐스팅 타임이 있을때만...
			{
				m_nCount	= 0;	// 전체 캐스팅 타임은 동작1+동작2의 합이어야 하므로 여기서 카운터를 초기화 한다.
				SetState( OBJSTA_ATK_ALL, OBJSTA_ATK_CASTING1 );			// 캐스팅부터 시작 -> 발사모션.
			}
			else
				SetState( OBJSTA_ATK_ALL, OBJSTA_ATK_MAGICSKILL );			// 발사모션만.

		#ifdef __CLIENT
			if( dwMsg == OBJMSG_MAGICSKILL && pMover->HasBuffByIk3( IK3_TEXT_DISGUISE ) )
				nParam1 = MTI_ATK1;
		#endif

			pMover->SetMotion( nParam1, ANILOOP_1PLAY, MOP_SWDFORCE | MOP_NO_TRANS | MOP_FIXED );		// 해당 동작애니 시작.
			pMover->OnAttackStart( pHitObj, dwMsg );			// 공격시작 핸들러.
			m_nMotionHitCount = 0;
			break;
		}
			

	//-------------------- 맞았다.
	case OBJMSG_DAMAGE:
	case OBJMSG_DAMAGE_FORCE:	// 강공격에 맞았다. 날아감.
		{
			CMover* pAttacker = PreProcessDamage( pMover, (OBJID)nParam2, nParam4, nParam5 );
			if( pAttacker == NULL )
				return 0;

			if( dwMsg == OBJMSG_DAMAGE_FORCE )			// 강공격으로 들어왔을때
				if( pMover->CanFlyByAttack() == FALSE )	// 날아가지 못하는 상태면.
					dwMsg = OBJMSG_DAMAGE;				// 일반 데미지로 바꿈.

			// 실제 가격한 데미지를 리턴함.
			int nDamage = _ProcessMsgDmg( dwMsg, pAttacker, (DWORD)nParam1, nParam3, nParam4, nParam5 );	
#if __VER >= 10	// __METEONYKER_0608
#ifdef __WORLDSERVER
#if __VER >= 12 // __NEW_ITEMCREATEMON_SERVER
			if( pAttacker->IsPlayer() && CCreateMonster::GetInstance()->IsAttackAble( static_cast<CUser*>(pAttacker), pMover ) )
#endif // __NEW_ITEMCREATEMON_SERVER
#endif // __WORLDSERVER
				pMover->PostAIMsg( AIMSG_DAMAGE, pAttacker->GetId(), nDamage );
#endif	// __METEONYKER_0608
			return nDamage;
		}
		break;

	// HP가 0이 된 순간 호출
	case OBJMSG_DIE:
	{
		if( IsSit() )						// 앉아있는상태였으면 해제
			ResetState( OBJSTA_MOVE_ALL );
		
		ClearState();						// 죽을땐 다른 동작 하고 있던거 다 클리어 시켜버리자.
		m_vDelta.x = m_vDelta.z = 0;		// 죽었으면 델타값 클리어.

		pMover->RemoveInvisible();
#ifdef __WORLDSERVER
		pMover->PostAIMsg( AIMSG_DIE, nParam2 );
#endif
		CMover *pAttacker = (CMover *)nParam2;	
		if( pAttacker )
		{
			if( pMover->IsPlayer() && pAttacker->IsPlayer() )	// 죽은놈과 죽인놈이 플레이어고
			{
#ifdef __WORLDSERVER
				if( pMover->m_nDuel == 1 && pMover->m_idDuelOther == pAttacker->GetId() )	// 둘이 듀얼중이었으면
				{
					pMover->ClearDuel();
					pAttacker->ClearDuel();
					((CUser*)pMover)->AddSetDuel( pMover );
					((CUser*)pAttacker)->AddSetDuel( pAttacker );
				}
				else if( pMover->m_nDuel == 2 && pMover->m_idDuelParty == pAttacker->m_idparty )
				{
					pMover->m_nDuelState	= 300;		
					CMover *pMember;
					CParty* pParty	= g_PartyMng.GetParty( pMover->m_idparty );

					if( pParty )
					{
						int i; for( i = 0; i < pParty->m_nSizeofMember; i ++ )
						{
							pMember = (CMover *)g_UserMng.GetUserByPlayerID( pParty->m_aMember[i].m_uPlayerId );
							if( IsValidObj( pMember ) )
								((CUser*)pMember)->AddSetDuel( pMover );
						}
					}

					CParty* pParty2		= g_PartyMng.GetParty( pMover->m_idDuelParty );
					if( pParty2 )
					{
						int i; for( i = 0; i < pParty2->m_nSizeofMember; i ++ )
						{
							pMember = (CMover *)g_UserMng.GetUserByPlayerID( pParty2->m_aMember[i].m_uPlayerId );
							if( IsValidObj( pMember ) )
								((CUser*)pMember)->AddSetDuel( pMover );
						}
					}
				}
#endif	// __WORLDSERVER
			}

			if( pAttacker->IsNPC() )	// 공격자가 몹.
			{	// 날때린몹의 어태커가 나일경우는 죽기전에 클리어시켜준다.
				if( pAttacker->m_idAttacker == pMover->GetId() )	// 공격한몹을 친사람이 나일경우는 스틸체크 해제.
				{
					pAttacker->m_idAttacker = NULL_ID;
					pAttacker->m_idTargeter = NULL_ID;
				}
			}
		}
		
		switch( nParam1 )
		{
#ifdef __BS_DEATH_ACTION
		case OBJMSG_DAMAGE:
		case OBJMSG_DAMAGE_FORCE:
		{
			int rAngle = 0;
			int rPower = 0;
			int nCase = rand() % 6;
			if( nCase < 3 )
			{
				rAngle = -2;
				rPower = 10 + rand() % 50;
			}
			else if( nCase < 4 )
			{
				rAngle = 10;
				rPower = 10 + rand() % 50;
			}
			else if( nCase < 5 )
			{
				rAngle = 50;
				rPower = 10 + rand() % 50;
			}
			else
			{
				rAngle = rand() % 30;
				rPower = rand() % 200;
			}
			
			if( OBJMSG_DAMAGE_FORCE == nParam1 )
				rPower += 50;
		
			CMover *pAttacker = (CMover *)nParam2;
			SetState( OBJSTA_DMG_ALL, OBJSTA_DMG_FLY );
			pMover->SetMotion( MTI_DMGFLY, ANILOOP_CONT );
			if( pAttacker )
			{
				float faddPower = rPower * 0.01f;
				float faddAngle = (float)( rAngle );

				DoDamageFly( pAttacker->GetAngle(), 100.0f + faddAngle, 0.05f + faddPower );	// 어태커가 보는쪽으로 날려보냄.
			}
		}
		break;
#else
		case OBJMSG_DAMAGE_FORCE:	// 강 공격으로 죽었다면 날아가서 죽기
			{
			CMover *pAttacker = (CMover *)nParam2;
			SetState( OBJSTA_DMG_ALL, OBJSTA_DMG_FLY );
			pMover->SetMotion( MTI_DMGFLY, ANILOOP_CONT );
			if( pAttacker )
				DoDamageFly( pAttacker->GetAngle(), 145.0f, 0.25f );	// 어태커가 보는쪽으로 날려보냄.
			}
			break;
		case OBJMSG_DAMAGE:		// 걍 일반 데미지로 죽었다면 그냥 쓰러져 죽기
#endif
		default:	
			SetState( OBJSTA_DMG_ALL, OBJSTA_DEAD );
			pMover->SetMotion( MTI_DIE1, ANILOOP_CONT );
			break;

		}

		if( !pMover->IsPlayer() )	// 몬스터일 경우.
		{
		#ifdef __WORLDSERVER			
			m_nDeadCnt	= 60*3;	// 디폴트 - 3초 후에 없어짐.
			MoverProp *pProp = pMover->GetProp();
			if( pProp )
			{
				
				if( pProp->dwSourceMaterial != NULL_ID || pProp->dwClass == RANK_MATERIAL )	// 자원 몹이면..
				{
					if( pProp->dwHoldingTime == NULL_ID )
						Error( "%s 의 MoverProp::dwHoldingTime 값이 -1", pMover->GetName() );
					m_nDeadCnt = (int)(60.0f * (pProp->dwHoldingTime / 1000.0f));
					if( pProp->dwHoldingTime < 10000 )		// 10초 이하일때
						Error( "dwHoldingTime : %d %s", pProp->dwHoldingTime, pMover->GetName() );
					pMover->m_nCollectOwnCnt = PROCESS_COUNT * 40;
					CMover *pAttacker = (CMover *)nParam2;	
					if( pAttacker )
						pMover->m_idCollecter = pAttacker->GetId();		// 공격자가 소유자가 된다.
					
				}
				{
					if( pProp->dwSourceMaterial == NULL_ID && pProp->dwClass == RANK_MATERIAL )	// 자원몹인데 자원값이 없는경우
						Error( "OBJMSG_DIE : %s %d", pMover->GetName(), pProp->dwSourceMaterial );
					if( pProp->dwSourceMaterial != NULL_ID && pProp->dwClass != RANK_MATERIAL )	// 자원몹이 아닌데 자원값이 있는경우.
						Error( "OBJMSG_DIE 2 : %s %d", pMover->GetName(), pProp->dwSourceMaterial );
				}
				
			}
		#endif // WorldServer
		}
		break;
	}
		
	case OBJMSG_APPEAR:
		SetState( OBJSTA_ACTION_ALL, OBJSTA_APPEAR );
		pMover->SetMotion( MTI_APPEAR2, ANILOOP_1PLAY, MOP_FIXED | MOP_NO_TRANS );
		break;
	//---- 모드전환 ------------------------
	case OBJMSG_MODE_COMBAT:
		if( GetStateFlag() & OBJSTAF_COMBAT )	return 0;		// 이미 전투모드면 리턴
		if( IsActJump() )	return 0;
		if( IsActAttack() )	return 0;
		if( IsActDamage() )	return 0;
		if( IsSit() )		return 0;
		if( IsAction() )	return 0;
		AddStateFlag( OBJSTAF_COMBAT );	// 전투모드로 서라가 아니고 전투모드로 바꿔라기땜에 서다 명령은 발생시키지 않는다.
		pMover->m_dwMotion = -1;	// 같은 모션을 하라고 한거라 모션이 안바뀌므로 이렇게...
		pMover->SetMotion( MTI_STAND );
		break;
	case OBJMSG_MODE_PEACE:
		if( (GetStateFlag() & OBJSTAF_COMBAT) == 0 )	return 0;
		if( IsActJump() )	return 0;
		if( IsActAttack() )	return 0;
		if( IsActDamage() )	return 0;
		if( IsSit() )		return 0;
		if( IsAction() )	return 0;
		RemoveStateFlag( OBJSTAF_COMBAT );
		pMover->m_dwMotion = -1;
		pMover->SetMotion( MTI_STAND );
		break;
	case OBJMSG_MODE_WALK:
		if( IsSit() )		return 0;
		if( IsAction() )	return 0;
		if( GetStateFlag() & OBJSTAF_WALK )	return 0;		// 이미 걷기모드면 리턴
		AddStateFlag( OBJSTAF_WALK );
		break;
	case OBJMSG_MODE_RUN:
		if( IsSit() )		return 0;
		if( IsAction() )	return 0;
		if( (GetStateFlag() & OBJSTAF_WALK) == 0 )	return 0;		// 
		RemoveStateFlag( OBJSTAF_WALK );
		break;
	case OBJMSG_MODE_FLY:
	{
		if( nParam3 == 0 )
		{
			if( IsSit() )		return 0;
			if( IsAction() )	return 0;
			if( IsActAttack() )	return 0;
			if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
			if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

			{
				CWorld* pWorld	= pMover->GetWorld();
				if( pWorld )
				{
					int nAttr = pMover->GetWorld()->GetHeightAttribute( pMover->GetPos().x, pMover->GetPos().z );		// 이동할 위치의 속성 읽음.
					if( nAttr == HATTR_NOFLY )		// 비행 금지 지역에서 타려고 하면 못탄다.
						return 0;
				}
			}
		}
		AddStateFlag( OBJSTAF_FLY );
		ItemProp *pItemProp = prj.GetItemProp( nParam1 );	// 빗자루 프로퍼티.
		if( pItemProp )
		{
			if( pMover->m_nFuel == -1 )		// 초기값이면
				pMover->m_nFuel = (int)pItemProp->dwFFuelReMax;	// 빗자루 최대 연료량을 세팅.
			// -1일때만 세팅해야지 연료를 반쯤 쓰다가 빗자루를 바꿔도 새로 세팅 되지 않는다.
		}
#ifndef __JEFF_9_20
#ifdef __WORLDSERVER
		if( pMover->IsPlayer() )
		{
			((CUser*)pMover)->SetFlyTimeOn();
		}
#endif // __WORLDSERVER
#endif	// __JEFF_9_20
		ClearState();
#ifdef __CLIENT
		if( m_pMover == CMover::GetActiveMover() )
		{
			m_pMover->GetWorld()->SetObjFocus( NULL );	// 비행직전에 기존타겟팅을 클리어해준다.
			g_Neuz.m_camera.Unlock();
			g_WndMng.m_pWndTaskBar->OnCancelSkill();	// 비행직전엔 스킬바 사용 취소.
		}
#endif

		CModel* pModel = prj.m_modelMng.LoadModel( D3DDEVICE, OT_ITEM, (DWORD) nParam1 );
#if __VER >= 14 // __WING_ITEM
		CModelObject* pModelObject = (CModelObject*)pModel;
		if( pModelObject->m_pBone )
		{
			CString strMotion = pModelObject->GetMotionFileName( _T("stand") );
			assert( strMotion != _T("") );
			pModelObject->LoadMotion( strMotion );
		}
#endif // __WING_ITEM
		m_pMover->SetRide( pModel, (DWORD) nParam1 );
		break;
	}
	case OBJMSG_MOTION:		// 단순 모션 플레이
		{
			if( IsSit() )		return 0;
			if( IsAction() )	return 0;
			if( IsActJump() )	return 0;
			if( IsActAttack() )	return 0;
			if( IsActDamage() )	return 0;
			if( pMover->m_dwFlag & MVRF_NOMOVE )	return 0;		// 이동금지 상태면 걍 리턴.
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
		if( pMover->GetAdjParam( DST_CHRSTATE ) & CHS_LOOT)			return 0;
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans

			AddStateFlag( OBJSTAF_ETC );		// 단순 모션 플레이 상태
			m_nMotionEx = nParam1;				// 모션 인덱스
			int nPlayMode = nParam2;			// 루핑 모드.
			if( m_nMotionEx != -1 )
				pMover->SetMotion( m_nMotionEx, nPlayMode, MOP_FIXED/* | MOP_SWDFORCE*/ );

			pMover->RemoveInvisible();
		}
		break;
	// 일반 액션.
	case OBJMSG_RESURRECTION:		// 부활.
		ClearState();
		SetState( OBJSTA_DMG_ALL, OBJSTA_RESURRECTION );
		pMover->SetMotion( MTI_ASS_RESURRECTION, ANILOOP_1PLAY, MOP_FIXED );
		break;


#if	defined(_DEBUG) && defined(__CLIENT)
	case OBJMSG_TEMP:
		{
			for( int i=0; i < 1; i ++ )
			{

				CMover* pObj = new CMover;
				D3DXVECTOR3 vPos = pMover->GetPos();
				pObj->SetPos( vPos );
				pObj->SetIndex( g_Neuz.m_pd3dDevice, MI_AIBATT1, TRUE );
				pObj->SetMotion( 0 );
				g_WorldMng.Get()->AddObj( pObj, TRUE ); 
			}
		}
		break;
		
	case OBJMSG_TEMP2:	// 디버깅용 공격동작만 볼때.
		if( CMover::GetActiveMover()->IsAuthHigher( AUTH_GAMEMASTER ) )	// 영자 계정일때
		{
			CObj *pObj = pMover->GetWorld()->GetObjFocus();
			g_DPlay.SendCorrReq( pObj );
			g_DPlay.SendError( FE_GENERAL, 0 );
		}
		break;
	
	case OBJMSG_TEMP3:
		{
		#ifdef __XUZHU			
			g_DPlay.SendError( 0, 0 );
		#endif
		}
		break;
#endif // defined(_DEBUG) && defined(__CLIENT)
		
	}
	return 1;
}
Beispiel #6
0
// 참가자 구성
void	CGuildCombat1to1Mng::SetMemberLineUp( CUser* pUser, vector<u_long>& vecMemberId )
{
	if( m_nState != GC1TO1_OPEN )	// 참가자 구성 시간이 아니다.
	{
		pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_NOLINEUP );
		return;
	}

	int nIndex = GetTenderGuildIndexByUser( pUser );
	if( nIndex == NULL_ID )	// 입찰되지 않았거나 순위에서 밀린 길드
	{
		pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_CANNOT_MAKEUP );
		return;
	}

	if( (int)( vecMemberId.size() ) < m_nMinJoinPlayer )	// 최소 참가자 수보다 적다.
	{
		pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_LOWMINPLAYER, "%d", m_nMinJoinPlayer );
		return;
	}

	if( (int)( vecMemberId.size() ) > m_nMaxJoinPlayer )
	{
		pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_OVERMAXPLAYER, "%d", m_nMaxJoinPlayer );
		return;
	}

	// 길드마스터 또는 킹핀급만 가능
	CGuild* pGuild = pUser->GetGuild();
	if( pGuild )
	{
		CGuildMember* pGuildMember = pGuild->GetMember( pUser->m_idPlayer );
		if( pGuildMember )
		{
			if( pGuildMember->m_nMemberLv != GUD_MASTER && pGuildMember->m_nMemberLv != GUD_KINGPIN )
			{
				pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_NOLINEUPAUTH );
				return;
			}
		}
	}
			
	BOOL bMasterOrKingpin = FALSE;
	// 최소 참가 레벨 검사
	for( int i=0; i<(int)( vecMemberId.size() ); i++ )
	{
		CUser* pUserTemp = (CUser*)prj.GetUserByID( vecMemberId[i] );
		if( IsValidObj( pUserTemp ) && pUserTemp->GetLevel() < m_nMinJoinPlayerLevel )
		{
			pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_LIMIT_LEVEL_NOTICE );
			return;
		}
		if( IsValidObj( pUserTemp ) && !bMasterOrKingpin )
		{
			CGuildMember* pGuildMember = pGuild->GetMember( pUserTemp->m_idPlayer );
			if( pGuildMember )
				if( pGuildMember->m_nMemberLv == GUD_MASTER || pGuildMember->m_nMemberLv == GUD_KINGPIN )
					bMasterOrKingpin = TRUE;	
		}
	}
	if( !bMasterOrKingpin )
	{
		pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_HAVENOT_MASTER );
		return;
	}
			
	m_vecTenderGuild[nIndex].vecMemberId.clear();
	m_vecTenderGuild[nIndex].vecMemberId = vecMemberId;
	pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_LINEUPCOMPLETE );
	g_dpDBClient.SendGC1to1LineUp( m_vecTenderGuild[nIndex].ulGuildId, vecMemberId );
}
Beispiel #7
0
// 1대1 길드대전 오픈
void	CGuildCombat1to1Mng::GuildCombat1to1Open( BOOL bGMText )
{
	if( !g_eLocal.GetState( EVE_GUILDCOMBAT1TO1 ) )
		return;
	
	vector<__GC1TO1TENDER>::iterator it;
	if( !bGMText )
	{
		for( it=m_vecTenderFailGuild.begin(); it!=m_vecTenderFailGuild.end(); it++ )
		{
			// 이전 1:1길드대전에 입찰 실패 길드가 신청금을 수령하지 않았을 경우
			g_dpDBClient.SendGC1to1Tender( 'U', (*it).ulGuildId, (*it).nPenya, 'N' );
		}
		m_vecTenderFailGuild.clear();
	}
	
	// 신청한  길드수가 최소 참여 길드수보다 적을 때
	if( (int)( m_vecTenderGuild.size() ) < m_nMinJoinGuild )
	{
		// 1대1 길드대전 취소 및 연장 처리
		CString strTemp;
		strTemp.Format( prj.GetText( TID_GAME_GUILDCOMBAT1TO1_NOGAME ), m_nMinJoinGuild );
		g_DPCoreClient.SendCaption( strTemp );	
		ClearTime();
		m_nState = GC1TO1_CLOSE;
		return;
	}
	
	// 1:1길드대전 오픈 메세지..
	g_DPCoreClient.SendCaption( prj.GetText( TID_GAME_GUILDCOMBAT1TO1_OPEN ) );
	g_DPCoreClient.SendCaption( prj.GetText( TID_GAME_GUILDCOMBAT1TO1_LINEUP ) );
	
	// 참가자 구성 시간 설정
	m_nState = GC1TO1_OPEN;
	m_nWaitTime = (int)m_Lua.GetGlobalNumber( "MemberLineUpTime" );
	m_dwTime = GetTickCount();	

	// 입찰 순위에 들지 못한 길드 제거
	int nCount = 0;
	for( it=m_vecTenderGuild.begin(); it!=m_vecTenderGuild.end(); )
	{
		nCount++;
		if( nCount <= m_nMaxJoinGuild )
			it++;
		else // 입찰 순위에서 밀려난 경우
		{
			CGuild* pGuild = g_GuildMng.GetGuild( (*it).ulGuildId );
			if( pGuild )
			{
				CUser* pUser = (CUser*)prj.GetUserByID( pGuild->m_idMaster );
				if( IsValidObj( pUser ) )
					pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_FAILTENDER );
			}
			
			g_dpDBClient.SendGC1to1Tender( 'U', (*it).ulGuildId, (*it).nPenya, 'F' );
			m_vecTenderFailGuild.push_back( (*it) );
			it = m_vecTenderGuild.erase( it );
		}
	}		

	// 입찰 순위에는 들어갔지만 상대 길드가 없는 경우(홀수)
	if( m_vecTenderGuild.size() % 2 != 0 )
	{
		it = m_vecTenderGuild.end(); it--;	// 마지막 순위		// 노트 :  rbegin()을 사용하시오.
		CGuild* pGuild = g_GuildMng.GetGuild( (*it).ulGuildId );
		if( pGuild )
		{
			CUser* pUser = (CUser*)prj.GetUserByID( pGuild->m_idMaster );
			if( IsValidObj( pUser ) )
				pUser->AddDefinedText( TID_GAME_GUILDCOMBAT1TO1_FAILTENDER );
		}

		g_dpDBClient.SendGC1to1Tender( 'U', (*it).ulGuildId, (*it).nPenya, 'F' );
		m_vecTenderFailGuild.push_back( (*it) );
		m_vecTenderGuild.erase( it );
	}

	// 출전 가능한 길드의 모든 길드원에게 OPEN STATE 알림(길드 마스터는 참가자 구성 시간 출력)
	for( it=m_vecTenderGuild.begin(); it!=m_vecTenderGuild.end(); it++ )
	{
		CGuild* pGuild = g_GuildMng.GetGuild( (*it).ulGuildId );
		if( pGuild )
		{
			for( map<u_long, CGuildMember*>::iterator it2=pGuild->m_mapPMember.begin(); it2!=pGuild->m_mapPMember.end(); it2++ )
			{
				CUser* pUser = (CUser*)prj.GetUserByID( it2->first );
				if( IsValidObj( pUser ) )
					SendNowState( pUser );
			}
		}
	}

	g_dpDBClient.SendGC1to1StateToDBSrvr();	// 1:1길드대전이 오픈되었다고 DBServer에 알림
}
Beispiel #8
0
//
// 외부에서 UseSkill을 명령할땐 이것으로 호출하자.
// sutType : 스킬을 사용할때 스킬큐에서 연타로 사용한건가 일반적인 사용을 한건가.c
//
int	CMover::CMD_SetUseSkill( OBJID idTarget, int nSkillIdx, SKILLUSETYPE sutType )
{
	m_oaCmd = OBJACT_NONE;
	TRACE( "CMD_SetUseSkill( " );
	if( m_pActMover->IsFly() )	return 0;				// 비행중엔 스킬사용 금지.
	if( m_pActMover->IsActAttack() )	return 0;
	if( m_pActMover->IsActJump() )	return 0;			// 점프중엔 사용금지.
	if( m_pActMover->GetState() & OBJSTA_DMG_FLY_ALL )		return 0;	// 데미지 플라이중엔 스킬사용금지.
	if( IsDie() )	return 0;		// 죽었을때 사용금지.

	LPSKILL pSkill	= GetSkill( 0, nSkillIdx );		// this가 가진 스킬중 nIdx에 해당하는 스킬을 꺼낸다.
	if( pSkill == NULL )
	{
		Error( "CMD_SetUseSkill : %s skill(%d) not found", m_szName, nSkillIdx );
		return 0;	// 
	}

	ItemProp* pSkillProp = pSkill->GetProp();
	if( pSkillProp == NULL )		// JobSkill 리스트에서 꺼낸 스킬의 프로퍼티를 꺼냄.
	{
		Error( "CMD_SetUseSkill : %s. skill(%d) property not found", m_szName, pSkill->dwSkill );
		return 0;	// 
	}
	
	if( IsPlayer() && IsStateMode( STATE_BASEMOTION_MODE ) )	// 시전중(준비시간)일땐 사용금지.
	{
	#ifdef __CLIENT
		g_DPlay.SendStateModeCancel( STATE_BASEMOTION_MODE, STATEMODE_BASEMOTION_CANCEL );
	#endif 
		return 0;		
	}

	// 도달범위 - 얼마나 가까이 근접해야하는가. 미터단위
	float	fArrivalRange = 0.0f;		
	fArrivalRange = GetAttackRange( pSkillProp->dwAttackRange );
	
	switch( pSkillProp->dwUseChance )
	{
	case WUI_NOW:	// 타겟팅과 상관없이 자기자신에게 쓰는 방식.
		idTarget = GetId();
		break;
	case WUI_TARGETINGOBJ:	// 셀렉트 되어 있는 타겟에게 사용.
		{
#ifdef __CLIENT
		CObj *pFocusObj = GetWorld()->GetObjFocus();
		if( pFocusObj && pFocusObj->GetType() == OT_MOVER )
			idTarget = ((CMover*)pFocusObj)->GetId();
#else
		if( IsPlayer() )
			idTarget = ((CUser *)this)->m_idSetTarget;
#endif // __CLIENT
		}

		break;
#ifdef __CLIENT
	case WUI_TARGETCURSORPTZ:
		{
			idTarget = GetId();
			
			CRect rect;
			D3DXVECTOR3 vPos;
			CWndWorld* pWndWorld;
			
			pWndWorld = (CWndWorld*)g_WndMng.GetWndBase( APP_WORLD );

			rect = pWndWorld->GetClientRect();

			if( GetWorld()->ClientPointToVector( NULL, rect, pWndWorld->GetMousePoint(), &GetWorld()->m_matProj, &GetWorld()->GetCamera()->m_matView, &vPos, TRUE ) )
			{
#ifdef __SKILL0517
				AddSkillProp* pAddSkillProp = prj.GetAddSkillProp( pSkillProp->dwSubDefine, GetSkillLevel( pSkill ) );		// UseSkill에서 사용한 스킬의 프로퍼티 꺼냄
#else	// __SKILL0517
				AddSkillProp* pAddSkillProp = prj.GetAddSkillProp( pSkillProp->dwSubDefine, pSkill->dwLevel );		// UseSkill에서 사용한 스킬의 프로퍼티 꺼냄
#endif	// __SKILL0517
				if( pAddSkillProp == NULL )
				{
					Error( "CMover::OnMagicSkill : %s. add스킬(%d)의 프로퍼티가 없다.", m_szName, nSkillIdx );
					return 0;	// property not found
				}
				
				FLOAT	fDist;
				FLOAT	fMaxDistSq;
				D3DXVECTOR3	vDist;
				fMaxDistSq  = (float)pAddSkillProp->dwSkillRange;
				fMaxDistSq *= fMaxDistSq;
				vDist = vPos - GetPos();
				fDist = D3DXVec3LengthSq( &vDist );	

				SetAngle( GetDegree(vPos, GetPos()) );		// 목표쪽으로 몸을 돌림.
				
				// 텔레포트 할 위치가 멀경우 현제 스킬에 해당하는 거리로 바꿔준다
				if( fDist > fMaxDistSq )
				{
					FLOAT fLength;
					D3DXVECTOR3 vDirNor;
					D3DXVec3Normalize( &vDirNor, &vDist );
					fLength = (float)pAddSkillProp->dwSkillRange;
					float y = vPos.y;
					vPos = GetPos() + (vDirNor * fLength);
					vPos.y	= y;

					// 스킬에 해당하는 거리로 바꾼곳이 못가는 지역이라면 갈수 있는 지역을 검사한다.
					int nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

					if( nAttr != HATTR_NONE ) 
					{
						while( nAttr != HATTR_NONE )
						{
							if( nAttr == HATTR_NOFLY )
								break;
							
							fLength -= 1.0f; // 1미터씩 줄여가며 계산한다.
							vPos  = GetPos() + (vDirNor * fLength);
							nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

							// 캐릭터의 앞 뒤로 이동불가 일 경우 뒷쪽이 이동불가 해제 될때 까지 계속 계산하여 이동시킴
							// 그러므로 텔레포트 스킬 범위를 넘어설 경우 원래 자리로 텔레포트 하도록 처리
							D3DXVECTOR3 vTemp = vPos - GetPos();
							float fTemp = D3DXVec3LengthSq( &vTemp );
							if(fTemp > fMaxDistSq)
							{
								vPos = GetPos();
								break;
							}
						}
						
						// 한번더 줄여줌
						fLength -= 1.0f; 
						vPos = GetPos() + (vDirNor * fLength);

						// 줄인 곳이 이동불가 지역일 수 있다.
						nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );
						if( nAttr != HATTR_NONE )
						{
							vPos = GetPos();
						}
					}
				}
				else // 텔레포트 할 위치가 해당스킬 거리보다 작을경우
				{
					int nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

					FLOAT fLength;
					D3DXVECTOR3 vDirNor;
					D3DXVec3Normalize( &vDirNor, &vDist );
					fLength = 0.0f;

					while( nAttr != HATTR_NONE )
					{
						if( nAttr == HATTR_NOFLY )
							break;

						fLength -= 1.0f;
						vPos = GetPos() + (vDirNor * fLength);
						
						nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

						// 캐릭터의 앞 뒤로 이동불가 일 경우 뒷쪽이 이동불가 해제 될때 까지 계속 계산하여 이동시킴
						// 그러므로 텔레포트 스킬 범위를 넘어설 경우 원래 자리로 텔레포트 하도록 처리
						D3DXVECTOR3 vTemp = vPos - GetPos();
						float fTemp = D3DXVec3LengthSq( &vTemp );
						if(fTemp > fMaxDistSq)
						{
							vPos = GetPos();
							break;
						}
					}
				}

				if( IsActiveMover() && g_eLocal.GetState( EVE_SCHOOL ) )	// 학교이벤섭이면.
				{
					D3DXVECTOR3 v1, v2;
					v1 = GetPos();	v1.y += 0.1f;
					v2 = vPos;		v2.y += 0.1f;
					if( GetWorld()->IntersectObjLine( NULL, v1, v2, FALSE, FALSE ) )	// 텔레포트는 라인체크함.
					{
						g_WndMng.PutString( prj.GetText(TID_GAME_NOMOVING), NULL, prj.GetTextColor(TID_GAME_NOMOVING) );
						g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE );
						return 0;
					}
				}

				pWndWorld->m_vTelePos = vPos;
			}
			else
			{
				g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE );
				g_WndMng.PutString( prj.GetText(TID_GAME_NOMOVING), NULL, prj.GetTextColor(TID_GAME_NOMOVING) );
				return 0;
			}
		}
		break;
#endif // __CLIENT
	}

	// 타인에게 쓰는경우에만 검사...
	if( idTarget != GetId() )		
	{
		CMover *pTarget = prj.GetMover( idTarget );
		if( IsValidObj(pTarget) )
		{
			if( pSkillProp->nEvildoing < 0 )	// 나쁜 스킬은 
				if( IsAttackAble(pTarget) == FALSE )	// 공격허용이 되지 않으면 사용할 수 없음.
					return 0;
				
			if( pSkill->dwSkill == SI_ASS_HEAL_RESURRECTION )	// 부활을 사용했을때
			{
				if( pTarget->IsNPC() || pTarget->IsDie() == FALSE )		// 상대가 NPC거나 상대가 죽어있지 않다면 취소
					return 0;
			} else
			{
				if( pTarget->IsDie() )		// 부활이 아닌 스킬을 사용했을때 상대가 죽어있으면 사용안됨.
					return 0;
			}
		}
	}

	// 타겟 근접 방식.
	switch( pSkillProp->dwExeTarget )
	{
	case EXT_SELFCHGPARAMET:	// 시전자 자신에게 사용하는 종류
		idTarget = GetId();		// 타겟을 자기자신으로 설정.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정. << 이게 왜 필요하지? ㅡ.ㅡ?
		break;
	case EXT_MAGICATKSHOT:
	case EXT_MAGICATK:			// 원거리에서 마법으로 타겟을 공격
	case EXT_MAGICSHOT:
		if( idTarget == NULL_ID )	return 0;			// 타겟이 없거나 유효하지 않으면 실패.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정. 다가가는 범위는 fArrivalRange값으로..
		break;
	case EXT_ANOTHERWITH:		// 나 혹은 다른사람에게 시전
		if( idTarget == NULL_ID )	// 타겟이 잡혀있지 않으면
			idTarget = GetId();		// 자신을 타겟으로 잡음
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정.
		break;
	case EXT_AROUNDATK:			// 내 주위적들을 대상.
		idTarget = GetId();		// 타겟을 자기자신으로 설정.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정.
		break;
	case EXT_OBJCHGPARAMET:		// 타인에게 사용
	default:	// 그외는 모두 근접하자.
		if( idTarget == NULL_ID )	return 0;			// 타겟이 없거나 유효하지 않으면 실패.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정.
		break;
	}
	
	ClearActParam();
	SetCmd( OBJACT_USESKILL, nSkillIdx, idTarget, sutType );		// 사정거리가 되었을때 실행할 명령 셋팅.
	TRACE( "\n)CMD_SetUseSkill\n" );

	return 1;
}