Ejemplo n.º 1
0
void CGuildWar::Process( CTime & time )
{
	if( m_nFlag == WF_WARTIME )
	{
		if( GetEndTime() < time )
		{
			m_nFlag	= WF_END;
			g_DPCoreClient.SendWarTimeout( m_idWar );
			TRACE( "SendWarTimeout, %d\n", m_idWar );
		}
		else
		{
			CGuild* pDecl	= g_GuildMng.GetGuild( m_Decl.idGuild );
			CGuild* pAcpt	= g_GuildMng.GetGuild( m_Acpt.idGuild );
			if( pDecl && pAcpt )
			{
				CUser* pMaster	= g_UserMng.GetUserByPlayerID( pDecl->m_idMaster );
				if( IsInvalidObj( pMaster ) )
					g_DPCoreClient.SendWarMasterAbsent( m_idWar, TRUE );
				pMaster	= g_UserMng.GetUserByPlayerID( pAcpt->m_idMaster );
				if( IsInvalidObj( pMaster ) )
					g_DPCoreClient.SendWarMasterAbsent( m_idWar, FALSE );
			}
		}
	}
}
Ejemplo n.º 2
0
void CParty::DoDuelPartyStart( CParty *pDst )
{
	int		i, j;
	OBJID	pDstMember[ MAX_PTMEMBER_SIZE ];
	memset( pDstMember, 0xff, sizeof(pDstMember) );
	
	m_idDuelParty = pDst->m_uPartyId;		// this파티의 상대
	
	CMover *pMember, *pMember2;

	LPCSTR pszLeader;
	if( pDst->m_nKindTroup )	// 순회극단 극단 이름 보냄
	{
		pszLeader = pDst->m_sParty;
	}
	else	// 단막극단 일때는 리더이름을 보냄
	{
#if __VER >= 11 // __SYS_PLAYER_DATA
		pszLeader	= CPlayerDataCenter::GetInstance()->GetPlayerString( pDst->GetPlayerId( 0 ) );
#else	// __SYS_PLAYER_DATA
		pszLeader	= prj.GetPlayerString( pDst->GetPlayerId( 0 ) );
#endif	//__SYS_PLAYER_DATA
	}
	
	if( !pszLeader )
	{
		Error( "Error Party PVP 1" );
		return;
	}

	for( i = 0; i < m_nSizeofMember; i ++ )		// 극단원들 루프.
	{
		pMember	= (CMover *)g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
		if( IsValidObj( pMember ) )
		{
			pMember->m_nDuel = 2;		// 2는 파티듀얼중.
			pMember->m_idDuelParty = m_idDuelParty;
			pMember->m_nDuelState = 104;
			// 상대방 파티의 멤버아이디를 다 꺼냄.
			for( j = 0; j < pDst->m_nSizeofMember; j ++ )
			{
				pMember2 = (CMover *)g_UserMng.GetUserByPlayerID( pDst->m_aMember[j].m_uPlayerId );
				if( IsValidObj(pMember2) )
					pDstMember[j] = pMember2->GetId();
			}
			// 상대 파티에 대한 정보를 우리멤버들에게 보냄
			((CUser *)pMember)->AddDuelPartyStart( pszLeader , pDst->m_nSizeofMember, pDstMember, pDst->m_uPartyId );		// 상대방 멤버의 ID를 다보낸다.
		}
	}
}	
Ejemplo n.º 3
0
void CParty::Replace( DWORD dwWorldId, D3DXVECTOR3 & vPos, BOOL bMasterAround )
{
	CUser *pMember;
	for( int i = 0; i < m_nSizeofMember; i ++ )		// 극단원 모두에게 듀얼 해제를 세팅하고 클라에도 알림.
	{
		pMember	= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );

		if( IsValidObj( pMember ) )
		{
			/*
			if( GetQuest( QUEST_BOSS_LV1 ) != NULL )
				pMember->UnequipRide();
			
			if( GetQuest( QUEST_BOSS_LV2 ) != NULL )
				pMember->UnequipRide();
			
			if( GetQuest( QUEST_BOSS_LV3 ) != NULL )
				pMember->UnequipRide();
			*/			
			pMember->REPLACE( g_uIdofMulti, dwWorldId, vPos, REPLACE_NORMAL, nTempLayer );
#ifdef __BUFF_1107
			pMember->m_buffs.RemoveBuffs( RBF_COMMON, 0 );
#else	// __BUFF_1107
			pMember->m_SkillState.RemoveAllSkillInfluence();
#endif	// __BUFF_1107
		}
	}
}
Ejemplo n.º 4
0
void CParty::ReplaceLodestar( const CRect &rect )
{
	// locked
	CUser* pUser;
	for( int i = 0; i < m_nSizeofMember; i ++ )		// 극단원 모두에게 듀얼 해제를 세팅하고 클라에도 알림.
	{
		pUser	= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );

		if( IsValidObj( pUser ) )
		{
			CWorld* pWorld	= pUser->GetWorld();
			if( pWorld )
			{
				POINT point	= { (int)pUser->GetPos().x, (int)pUser->GetPos().z	};
				if( rect.PtInRect( point ) )
				{
					PRegionElem pRgnElem	= NULL;
					if( pWorld->GetID() != pWorld->m_dwIdWorldRevival && pWorld->m_dwIdWorldRevival != 0 )
						pRgnElem	= g_WorldMng.GetRevivalPos( pWorld->m_dwIdWorldRevival, pWorld->m_szKeyRevival );
					if( !pRgnElem )	// Find near revival pos
						pRgnElem	= g_WorldMng.GetNearRevivalPos( pWorld->GetID(), pUser->GetPos() );
					if( pRgnElem )
						pUser->REPLACE( g_uIdofMulti, pRgnElem->m_dwWorldId, pRgnElem->m_vPos, REPLACE_NORMAL, nRevivalLayer );
				}
			}
		}
	}
}
Ejemplo n.º 5
0
//
// 극단 듀얼 해제
// 
void CParty::DoDuelPartyCancel( CParty* pDuelParty )
{
#ifndef __CORESERVER
	int		i;
	
	CMover *pMember;
	for( i = 0; i < m_nSizeofMember; i ++ )		// 극단원 모두에게 듀얼 해제를 세팅하고 클라에도 알림.
	{
#ifdef __WORLDSERVER
		pMember	= (CMover *)g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
#else
#ifdef __CLIENT
		pMember	= prj.GetUserByID( m_aMember[i].m_uPlayerId );
#endif
#endif // worldserver
		if( IsValidObj( pMember ) )
		{
#ifdef __WORLDSERVER
			if( pDuelParty )
				((CUser *)pMember)->AddDuelPartyCancel( pDuelParty );		// 각 멤버들에게 듀얼이 취소되었다고 알림.
			else
				((CUser *)pMember)->AddDuelPartyCancel( NULL );		// 각 멤버들에게 듀얼이 취소되었다고 알림.
			if( pMember->m_idDuelParty != m_idDuelParty )
				Error( "CParty::DoDuelPartyCancel : 파티멤버 %s의 정보이상. %d %d", pMember->GetName(), pMember->m_idDuelParty, m_idDuelParty );
			pMember->ClearDuelParty();
#endif // worldserver
		}
	}
	m_idDuelParty = 0;		// 파티 해제
#endif	// __CORESERVER
}	
Ejemplo n.º 6
0
CMover* CParty::GetLeader( void ) 
{ 
#ifdef __WORLDSERVER
	CMover *pLeader = (CMover *)g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
	return pLeader;
#else
	CMover *pLeader = (CMover *)prj.GetUserByID( m_aMember[0].m_uPlayerId );	// 리더의 포인터
	return pLeader;
#endif
}
Ejemplo n.º 7
0
void CCoupleHelper::OnUpdatePlayerData( u_long idPlayer, PlayerData* pPlayerData )
{
	CCouple* pCouple	= GetCouple( idPlayer );
	if( pCouple )
	{
		u_long idPartner	= pCouple->GetPartner( idPlayer );
		CUser* pPartner		= g_UserMng.GetUserByPlayerID( idPartner );
		if( IsValidObj( pPartner ) )
			pPartner->AddQueryPlayerData( idPlayer, pPlayerData );
	}
}
Ejemplo n.º 8
0
int CCampus::GetBuffLevel( u_long idPlayer )
{
	int nLevel = 0;
	if( IsMaster( idPlayer ) )
	{
		for( MAP_CM::iterator it = m_mapCM.begin(); it != m_mapCM.end(); ++it )
		{
			CUser* pPupil = g_UserMng.GetUserByPlayerID( ( it->second )->GetPlayerId() );
			if( IsValidObj( pPupil ) && ( it->second )->GetLevel() == CAMPUS_PUPIL )
				++nLevel;
		}
	}
	else
	{
		CUser* pMaster = g_UserMng.GetUserByPlayerID( GetMaster() );
		if( IsValidObj( pMaster ) )
			++nLevel;
	}
	return nLevel;
}
Ejemplo n.º 9
0
void CParty::Replace( DWORD dwWorldId, LPCTSTR sKey )
{
	CUser *pMember;
	for( int i = 0; i < m_nSizeofMember; i ++ )		// 극단원 모두에게 듀얼 해제를 세팅하고 클라에도 알림.
	{
		pMember	= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
		
		if( IsValidObj( pMember ) )
		{
			PRegionElem pRgnElem = g_WorldMng.GetRevivalPos( dwWorldId, sKey );
			if( NULL != pRgnElem )
				pMember->REPLACE( g_uIdofMulti, pRgnElem->m_dwWorldId, pRgnElem->m_vPos, REPLACE_NORMAL, nRevivalLayer );
		}
	}
}
Ejemplo n.º 10
0
void CParty::DoUsePartyReCall( u_long uPartyId, u_long uLeaderid, int nSkill )
{
	CUser* pMember	= NULL;
	int		i;

	CUser* pUser    = NULL;
	pUser = g_UserMng.GetUserByPlayerID( uLeaderid );
	if( !IsValidObj( (CObj*)pUser ) )
		return;
	
	for( i = 0; i < m_nSizeofMember; i ++ )		// 단장(0)에게는 보낼필요 없다.
	{
		pMember		= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
		if( IsValidObj( (CObj*)pMember ) )
		{
			if(pMember->m_idPlayer != pUser->m_idPlayer)
#ifdef __LAYER_1015
				g_DPCoreClient.SendSummonPlayer( pUser->m_idPlayer, pUser->GetWorld()->GetID(), pUser->GetPos(), pMember->m_idPlayer, pUser->GetLayer() );
#else	// __LAYER_1015
				g_DPCoreClient.SendSummonPlayer( pUser->m_idPlayer, pUser->GetWorld()->GetID(), pUser->GetPos(), pMember->m_idPlayer );
#endif	// __LAYER_1015
		}
	}
}
Ejemplo n.º 11
0
BOOL CParty::ReplaceChkLv( int Lv )
{
	CUser *pMember;
	for( int i = 0; i < m_nSizeofMember; i ++ )		// 극단원 모두에게 듀얼 해제를 세팅하고 클라에도 알림.
	{
		pMember	= g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
		
		if( IsValidObj( pMember ) )
		{
			if( pMember->GetLevel() > Lv )
			{
				return FALSE;
			}
		}
	}

	return TRUE;
}
Ejemplo n.º 12
0
//
// 파티원들에게 bWin에 따라 승/패 사실을 알리고 듀얼을 종료시킴.
//
void CParty::DoDuelResult( CParty *pDuelOther, BOOL bWin, int nAddFame, float fSubFameRatio )
{
	CUser *pMember;
	int		i;
	
	for( i = 0; i < m_nSizeofMember; i ++ )
	{
		pMember = g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId );
		if( IsValidObj( pMember ) )
		{
			pMember->AddDuelPartyResult( pDuelOther, bWin );		// 각 멤버들에게 승/패 사실을 알림. / 상대파티원 리스트도 보냄.
			pMember->ClearDuelParty();

			if( bWin )
			{
				pMember->m_nFame += nAddFame;	// 이긴측이면 명성 증가
				pMember->AddDefinedText( TID_GAME_GETFAMEPOINT, "%d", nAddFame );	// xxx 명성 포인트가 증가
#ifdef __WORLDSERVER
				g_dpDBClient.SendLogPkPvp( pMember, NULL, nAddFame, 'E' );
#endif // __WORLDSERVER
			} 
			else
			{
				int nDecVal;
				fSubFameRatio = fSubFameRatio / 100.0f;	// 비율로 환산.
				nDecVal = (int)(pMember->m_nFame * fSubFameRatio);
				if( nDecVal == 0 )	nDecVal = 1;
				pMember->m_nFame -= nDecVal;
				if( pMember->m_nFame < 0 )	pMember->m_nFame = 0;
				pMember->AddDefinedText( TID_GAME_DECFAMEPOINT, "%d", nDecVal );	// xxx 명성 포인트가 감소.
#ifdef __WORLDSERVER
				g_dpDBClient.SendLogPkPvp( NULL, pMember, nAddFame, 'E' );
#endif // __WORLDSERVER
			}
			
			// 바뀐 명성치를 pMember의 주위에 날려줌.
			g_UserMng.AddSetFame( pMember, pMember->m_nFame );
		}
	}
	m_idDuelParty = 0;
}
Ejemplo n.º 13
0
void CGuildWarMng::Result( CGuildWar* pWar, CGuild* pDecl, CGuild* pAcpt, int nType, int nWptDecl, int nWptAcpt )
{
	CGuild* pWin, *pLose;
	switch( nType )
	{
		case WR_DECL_GN:
		case WR_DECL_SR:
		case WR_DECL_AB:
		case WR_DECL_DD:
		case WR_TRUCE:
		case WR_DRAW:
			{
				pWin	= pDecl;
				pLose	= pAcpt;
				break;
			}
		case WR_ACPT_GN:
		case WR_ACPT_SR:
		case WR_ACPT_AB:
		case WR_ACPT_DD:
			{
				pWin	= pAcpt;
				pLose	= pDecl;
				break;
			}
	}

	int nWinPointDecl = 0;
	int nWinPoint = 0;
	
	if( nType < WR_TRUCE )
	{
#ifdef __CORESERVER
		// nWinPoint
		nWinPoint	= (int)( pWin->m_nWinPoint + ( (float)( 10 + pWin->m_nWinPoint ) / (float)( ( (float)( pWin->m_nWinPoint + 4 ) / (float)( pLose->m_nWinPoint + 1 ) ) * 0.05 ) ) + 1 );
		int nMaxWinPoint	= (int)( ( 10 + pWin->m_nWinPoint * 0.05 ) * 5 );
		if( nWinPoint > nMaxWinPoint )
		{
			pWin->m_nWinPoint	+= nMaxWinPoint;
			nWinPointDecl = nMaxWinPoint;
		}
		else
		{
			pWin->m_nWinPoint	+= nWinPoint;
			nWinPointDecl = nWinPoint;
		}
		pWin->m_nWin++;
		nWinPoint	= (int)( ( 10 + pLose->m_nWinPoint * 0.02 ) );
		pLose->m_nWinPoint	-= nWinPoint;
		if( pLose->m_nWinPoint < 0 )
			pLose->m_nWinPoint	= 0;
		pLose->m_nLose++;
#else	// __CORESERVER
		pDecl->m_nWinPoint	= nWptDecl;
		pAcpt->m_nWinPoint	= nWptAcpt;
		pWin->m_nWin++;
		pLose->m_nLose++;
#endif	// __CORESERVER
	}

//	Clean up
	pWin->m_idWar	= 0;
	pWin->m_idEnemyGuild	= 0;
	pLose->m_idWar	= 0;
	pLose->m_idEnemyGuild	= 0;

	for( map<u_long, CGuildMember*>::iterator i = pWin->m_mapPMember.begin();
		i != pWin->m_mapPMember.end(); ++i )
	{
#ifdef __CORESERVER
		CPlayer* pPlayer	= g_PlayerMng.GetPlayer( i->second->m_idPlayer );
		if( pPlayer )	pPlayer->m_idWar	= 0;
#endif	// __CORESERVER
#ifdef __WORLDSERVER
		CUser* pUser	= g_UserMng.GetUserByPlayerID( i->second->m_idPlayer );
		if( IsValidObj( pUser ) )
		{
			pUser->m_idWar	= 0;
			g_UserMng.AddSetWar( pUser, 0 );
			pUser->SetPKTargetLimit( 10 );
		}
#endif	// __WORLDSERVER
	}
	for( i	= pLose->m_mapPMember.begin(); i != pLose->m_mapPMember.end(); ++i )
	{
#ifdef __CORESERVER
		CPlayer* pPlayer	= g_PlayerMng.GetPlayer( i->second->m_idPlayer );
		if( pPlayer )	pPlayer->m_idWar	= 0;
#endif	// __CORESERVER
#ifdef __WORLDSERVER
		CUser* pUser	= g_UserMng.GetUserByPlayerID( i->second->m_idPlayer );
		if( IsValidObj( pUser ) )
		{
			pUser->m_idWar	= 0;
			g_UserMng.AddSetWar( pUser, 0 );
			pUser->SetPKTargetLimit( 10 );
		}
#endif	// __WORLDSERVER
	}
#ifdef __CORESERVER
	g_dpCoreSrvr.SendWarEnd( pWar->m_idWar, pDecl->m_nWinPoint, pAcpt->m_nWinPoint, nType );
	g_DPCacheSrvr.SendWarEnd( pWar->m_idWar, pDecl->m_nWinPoint, pAcpt->m_nWinPoint, nType );
	int nDBType	= nType;
	switch( nType )
	{
		case WR_DECL_AB:
		case WR_DECL_DD:
			nDBType	= WR_DECL_GN;
			break;
		case WR_ACPT_AB:
		case WR_ACPT_DD:
			nDBType	= WR_ACPT_GN;
			break;
	}
	g_dpDatabaseClient.SendWarEnd( pWar->m_idWar, pDecl->m_idGuild, pAcpt->m_idGuild, pDecl->m_nWinPoint, pAcpt->m_nWinPoint, nDBType, pWar->m_time, pDecl->m_nWinPoint, pAcpt->m_nWinPoint, nWinPointDecl, nWinPoint );
#endif	// __CORESERVER
#ifdef __CLIENT
	char lpString[1024]	= { 0, };
	switch ( nType )
	{
		case WR_DECL_GN:
		case WR_ACPT_GN:
			{
				sprintf( lpString, prj.GetText( TID_GAME_GUILDWARWIN ), pDecl->m_szGuild, pAcpt->m_szGuild, pWin->m_szGuild, prj.GetText( TID_GAME_GUILDWARWIN_MASTER ) );
				g_WndMng.PutString( lpString , NULL, prj.GetTextColor( TID_GAME_GUILDWARWIN ) );
				break;
			}
		case WR_DECL_SR:
		case WR_ACPT_SR:
			{
				sprintf( lpString, prj.GetText( TID_GAME_GUILDWARWIN ), pDecl->m_szGuild, pAcpt->m_szGuild, pWin->m_szGuild, prj.GetText( TID_GAME_GUILDWARWIN_GIVEUP ) );
				g_WndMng.PutString( lpString , NULL, prj.GetTextColor( TID_GAME_GUILDWARWIN ) );
				break;
			}
		case WR_DECL_AB:
		case WR_ACPT_AB:
			{
				sprintf( lpString, prj.GetText( TID_GAME_GUILDWARWIN ), pDecl->m_szGuild, pAcpt->m_szGuild, pWin->m_szGuild, prj.GetText( TID_GAME_GUILDWARWIN_TIMEUP ) );
				g_WndMng.PutString( lpString , NULL, prj.GetTextColor( TID_GAME_GUILDWARWIN ) );
				break;
			}
		case WR_ACPT_DD:
		case WR_DECL_DD:
			{
				sprintf( lpString, prj.GetText( TID_GAME_GUILDWARWIN ), pDecl->m_szGuild, pAcpt->m_szGuild, pWin->m_szGuild, prj.GetText( TID_GAME_GUILDWARWIN_KILLNUM ) );
				g_WndMng.PutString( lpString , NULL, prj.GetTextColor( TID_GAME_GUILDWARWIN ) );
				break;
			}
		case WR_TRUCE:
			{
				char lpString[1024]	= { 0, };
				sprintf( lpString, prj.GetText( TID_GAME_GUILDWARPEACE ), pDecl->m_szGuild, pAcpt->m_szGuild );
				g_WndMng.PutString( lpString , NULL, prj.GetTextColor( TID_GAME_GUILDWARPEACE ) );
				break;
			}
		case WR_DRAW:
			{
				char lpString[1024]	= { 0, };
				sprintf( lpString, prj.GetText( TID_GAME_GUILDWARDRAW ), pDecl->m_szGuild, pAcpt->m_szGuild );
				g_WndMng.PutString( lpString , NULL, prj.GetTextColor( TID_GAME_GUILDWARDRAW ) );
				break;
			}
	}
#endif	// __CLIENT
	RemoveWar( pWar->m_idWar );
}
Ejemplo n.º 14
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
}
Ejemplo n.º 15
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;
}