Example #1
0
void CBackCamera::Process( LPDIRECT3DDEVICE9 pd3dDevice ,float fFactor )
{
#ifdef __CLIENT
	CMover *pMover = CMover::GetActiveMover();
	// 여기서 카메라 세팅!!!!!
	if( pMover == NULL )	return;

	CWorld* pWorld = pMover->GetWorld();
	if( pWorld == NULL )
		return;
	D3DXMATRIX matView, mat;

	FLOAT fAngle = 0, fAngleY = 0;

	D3DXVECTOR3 vPos = pMover->GetPos();
	
	vPos.y += 0.9f;
#if __VER >= 13 // __HOUSING
	if(m_nCamMode == CM_MYROOM)
	{
		if(m_fZoom <= 0.5f) m_fZoom = 0.5f;
	//	if(m_fZoom >= 3.0f) m_fZoom = 3.0f;
	}
#endif // __HOUSING
	CMover* pMoverTarget = (CMover*)g_WorldMng.Get()->GetObjFocus() ;
	D3DXVECTOR3 vTarget,vTemp;
	if( pMoverTarget && pMover->m_pActMover->IsFly() && (pMover->m_dwFlag & MVRF_TRACKING) ) 
	{	// 날고 있는 경우 타겟이 있다면
		// 타겟쪽으로 카메라 방향을 수정한다.
		vTemp = vPos - pMoverTarget->GetPos();
		if( vTemp.z > 0 ) 
		{
			fAngle =- (float)( atan( vTemp.x / vTemp.z ) * 180 / 3.1415926f );
		}
		else 
		{
			fAngle =- (float)( atan( vTemp.x / vTemp.z ) * 180 / 3.1415926f ) + 180;
		}
		D3DXVECTOR3	vDistXZ = vTemp;
		vDistXZ.y = 0;
		float fDistSq = D3DXVec3Length( &vDistXZ );		// XZ평면에서의 길이
		fAngleY = atan2( fDistSq, vTemp.y/* * vTemp.y*/ );
		fAngleY = D3DXToDegree( fAngleY );

		float fReg1 = vTemp.y / 40.0f;
		if( fReg1 > 0 )
		{
			if( fReg1 >= 2.0f )	fReg1 = 2.0f;
		} else
		if( fReg1 < 0 )
		{
			if( fReg1 <= -2.0f )	fReg1 = -2.0f;
		}

		m_fCurRoty = m_fRoty + m_fZoom * fReg1;
		if( m_bLock )
			fAngle = 0;

	}
	else 
	{
		fAngle = pMover->GetAngle();
		if( m_bLock )
			fAngle = 0;
		fAngleY = 90.0f;

		m_fCurRoty = m_fRoty + m_fZoom * 4;
	}
	m_vLookAt = vPos;

#ifdef __Y_CAMERA_SLOW_8
	if( !g_WndMng.m_pWndWorld->m_bRButtonDown && ( !g_bKeyTable[ VK_LEFT ] && !g_bKeyTable[ VK_RIGHT ] ) )
	{
		static FLOAT fSpeed = 2.0f;
		BOOL  bLeft = FALSE;
		BOOL  bRight = FALSE;
		FLOAT fTemp = 0.0f;

		fTemp = m_fRotx;

		if( (GetAnglePie(fTemp) == 1 && GetAnglePie(m_fCurRotx) == 4) )
			bRight = TRUE;

		if( (GetAnglePie(fTemp) == 4 && GetAnglePie(m_fCurRotx) == 1) )
			bLeft = TRUE;

		if( bRight )
		{
			m_fCurRotx += m_fRotx;

			if( m_fCurRotx < fTemp )
			{
				m_fCurRotx += fSpeed;
			}

			m_fCurRotx -= m_fRotx;

			if( m_fCurRotx >= 0.0f )
			{
				m_fCurRotx = -360.0f;
			}
		}

		if( bLeft )
		{
			fTemp += -360.0f;
			
			if( m_fCurRotx > fTemp )
			{
				m_fCurRotx += -fSpeed;

				if( m_fCurRotx < -360.0f )
					m_fCurRotx = 0.0f;
			}

			fTemp -= -360.0f;
		}

		if( !bLeft && !bRight )
		{
			FLOAT fGoal = fabs(m_fCurRotx - fTemp);
			if( m_fCurRotx < fTemp )
			{
				if( fGoal > fSpeed )
					m_fCurRotx += fSpeed;
			}
			else
			{
				if( fGoal > fSpeed )
					m_fCurRotx -= fSpeed;
			}
		}
	}
	else
	{
		m_fCurRotx = m_fRotx;
	}

#else //__Y_CAMERA_SLOW_8
	m_fCurRotx = m_fRotx;
#endif //__Y_CAMERA_SLOW_8

#ifdef __XUZHU
	_g_fReg[0] = fAngleY;
#endif
	
	float fAdjAng = (1.0f - fAngleY / 90.0f) * 45.0f;
	m_fCurRoty += fAdjAng;
	m_fCurRoty += pMover->GetAngleX();
	
	if( pMover->m_pActMover->IsFly() )	// 비행할땐 조금 들어주자
		m_fCurRoty += 0.0f;
	if( m_fCurRoty > 80.0f ) 
		m_fCurRoty = 80.0f;

#if __VER >= 13 // __HOUSING
	if(m_nCamMode == CM_MYROOM)
	{
		if(m_fCurRoty <= 10.0f) 
		{
			m_fCurRoty = 10.0f;
			if(m_fRoty > 0.0f) m_fRoty = 0.0f;
			if(m_fRoty < -30.0f) m_fRoty = -30.0f;
		}
	}
#endif // __HOUSING

	fAngle = m_fCurRotx - fAngle + 180.0f;

	D3DXMATRIX matTemp;
	// zoom 상태에 따라 카메라 위치를 조정
	extern float fDiv;
	
	if( fDiv == 2.0f )
		//vTemp = D3DXVECTOR3( 0.0f, 0.0f, -0.0f - (m_fZoom / 2.0f) * 2.0f );
		vTemp = D3DXVECTOR3( 0.0f, 0.0f, -0.0f - 2.0f );
	else
	{
		if( g_pShip )
			vTemp = D3DXVECTOR3( 0.0f, 0.0f, -4.0f - m_fZoom * 16.0f );
		else
			//vTemp = D3DXVECTOR3( 0.0f, 0.0f, -50.0f );
			vTemp = D3DXVECTOR3( 0.0f, 0.0f, -4.0f - m_fZoom * 2.0f );
	}
	
	D3DXVECTOR3 vecOut;
	D3DXMatrixRotationX( &matTemp, D3DXToRadian( m_fCurRoty / 1.0f ) );
	D3DXVec3TransformCoord( &vTemp, &vTemp, &matTemp );
	D3DXMatrixRotationY( &matTemp, D3DXToRadian( fAngle ) );
	D3DXVec3TransformCoord( &m_vOffsetDest, &vTemp, &matTemp );

	D3DXVECTOR3 vecOffsetDelta = ( ( m_vOffsetDest - m_vOffset ) + m_vPosVal ) / fFactor;

	m_vOffset += vecOffsetDelta;

	m_vPosVal /= 2;

	m_vPos = vPos + m_vOffset;

	BOOL  bCrash;
	FLOAT fLength;
	static D3DXVECTOR3 m_vLimitPos;
	D3DXVECTOR3 m_vOutPos = m_vPos;

	m_vLookAt.y += 0.4f;
#if __VER >= 11 // __GUILD_COMBAT_1TO1
	if( g_pPlayer && g_GuildCombat1to1Mng.IsPossibleMover( g_pPlayer ) )
		bCrash = FALSE;
	else
		bCrash = pWorld->CheckBound( &m_vPos, &m_vLookAt, &m_vOutPos, &fLength );
#else //__GUILD_COMBAT_1TO1
	bCrash = pWorld->CheckBound( &m_vPos, &m_vLookAt, &m_vOutPos, &fLength );
#endif //__GUILD_COMBAT_1TO1

	// 충돌이있다면 마지막으로 충돌했던 거리를 저장
	if( bCrash )
		m_fLength2 = fLength;

	// 전프레임에 충돌, 현재는 충돌이 아닐때...즉, 서서히 뒤로 가게하는 시점..
	if( m_bOld && bCrash == FALSE )
	{
		m_fLength1 = fLength;
		m_bStart = TRUE;
	}

	if( m_bStart )
	{
		D3DXVECTOR3 vCPos = vPos + m_vOffset;
		D3DXVECTOR3 vDir  = vCPos - m_vLookAt;
		D3DXVec3Normalize(&vDir, &vDir);
#if __VER >= 12 // __CAM_FAST_RECOVER
		m_fLength2 += 0.37f;
#else
		m_fLength2 += 0.07f;
#endif
		if( m_fLength2 > fLength )
			m_bStart = FALSE;

		m_vOutPos = m_vLookAt + (vDir * m_fLength2);
	}
	else
	if( bCrash )
	{/*
		if( fLength < 5.0f )
		{
			D3DXVECTOR3 vCPos = vPos + m_vOffset;
			D3DXVECTOR3 vDir  = vCPos  - m_vLookAt;
			D3DXVec3Normalize(&vDir, &vDir);
			
			FLOAT fff = m_vOutPos.y;
			m_vOutPos = m_vLookAt + (vDir * 5.0f);
			m_vOutPos.y = fff;
		}
	 */
	}

	m_bOld = bCrash;

	g_ModelGlobal.SetCamera( m_vOutPos, m_vLookAt );

	m_vPos = m_vOutPos;
#endif // CLIENT
}
int		CWndWorld::ControlFlying( DWORD dwMessage, CPoint point )
{
	static	float	fTurnAngle	= 0.0f;
	static BOOL	s_bTraceKeyed = 0, s_bSelectKeyed = 0, s_bTurbo2 = 0;
//	static	BOOL	s_bFastTurn;
	int		nMsg = 0;
//	BOOL	bFlyKey;
 	BOOL	bUp, bDown, bLeft, bRight;
	BOOL	bAcc = FALSE;
	BOOL	bTurbo;
//	BOOL	bFastTurn = FALSE;
	BYTE nFrame		= MAX_CORR_SIZE_150;
	CMover* pMover = CMover::GetActiveMover();

	bUp	  = g_bKeyTable[g_Neuz.Key.chUp];
	bDown = g_bKeyTable['S'];

	// 좌/우 회전
	bLeft  = g_bKeyTable[g_Neuz.Key.chLeft];
	bRight = g_bKeyTable['D'];
	
	// 급선회.
//	bFastTurn = g_bKeyTable[ VK_SHIFT ];
	
//	CMover* pMoverTarget = (CMover*)g_WorldMng.Get()->GetObjFocus() ;

	// 가속 상태면 전진 명령 계속 보냄
	bool fMoved	= false;
	bool fBehavior	= false;
	
	if( pMover->m_pActMover->IsStateFlag( OBJSTAF_ACC ) ) {
		if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) {
			fMoved	= true;
		}
	}
	else {
		if( pMover->SendActMsg( OBJMSG_STAND ) == 1 ) {
			fMoved	= true;
		}
	}
	//
	bAcc	= g_bKeyTable[VK_SPACE];
	if( bAcc && !s_bAccKeyed ) 		// 키 누른순간에만 토글시킴.
	{
		if( pMover->m_pActMover->IsStateFlag( OBJSTAF_ACC ) ) 		// 가속중이었다면 
		{
			pMover->SendActMsg( OBJMSG_ACC_STOP );		// 가속 멈춤
			if( pMover->m_pActMover->IsActTurn() )
			{
				fMoved	= true;
			}
		}
		else 
		{
			// 가속중이 아니었다면 가속 시킴.
			if( pMover->SendActMsg( OBJMSG_ACC_START ) == 0 )		
				g_WndMng.PutString( prj.GetText( TID_GAME_AIRFUELEMPTY ) );
			else
			{
				if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) 
					fMoved	= true;
			}
		}
	}
	s_bAccKeyed = bAcc;

	bTurbo = g_bKeyTable[g_Neuz.Key.chWalk];
	if( bTurbo && !s_bTurbo2 )		// 토글 방식.
	{
		if( pMover->m_pActMover->IsStateFlag( OBJSTAF_TURBO ) )
		{
			if( pMover->SendActMsg( OBJMSG_MODE_TURBO_OFF ) == 1 )
				fMoved = true;
		} else
		{
			if( pMover->SendActMsg( OBJMSG_MODE_TURBO_ON ) == 1 )
				fMoved = true;
		}
	}
	s_bTurbo2 = bTurbo;
	
	if( pMover->m_pActMover->IsFly() )
	{
		if( g_bKeyTable[g_Neuz.Key.chTrace] && !s_bTraceKeyed )
		{
			CCtrl* pFocusObj = (CCtrl*)(pMover->GetWorld()->GetObjFocus());
			if( pFocusObj && pFocusObj->GetType() == OT_MOVER )
			{
				CMover* pFocusMover = (CMover*)pFocusObj;
				if( pMover->m_dwFlag & MVRF_TRACKING )	// 이미 실행중이면 해제.
				{
					pMover->m_dwFlag &= (~MVRF_TRACKING);		// 추적모드해제.
					pMover->m_idTracking = NULL_ID;
				} else
				{
					// 비행중 추적모드.
					pMover->m_dwFlag |= MVRF_TRACKING;		// 추적모드.
					pMover->m_idTracking = pFocusMover->GetId();
				}
			} else
			{	// 타겟이 없을때 Z키를 누르면 자동추적이 풀린다.
				pMover->m_dwFlag &= (~MVRF_TRACKING);		// 추적모드해제.
				pMover->m_idTracking = NULL_ID;
			}
		}
		s_bTraceKeyed = g_bKeyTable[g_Neuz.Key.chTrace];

		// 타겟선택 키
		if( g_bKeyTable[VK_TAB] && !s_bSelectKeyed )
		{
			if( m_aFlyTarget.GetSize() > 0 )		// 선택된 타겟있을때.
			{
				if( m_nSelect >= m_aFlyTarget.GetSize() )
					m_nSelect = 0;
				OBJID idSelect = m_aFlyTarget.GetAt( m_nSelect++ );
				CMover *pSelectMover = prj.GetMover( idSelect );
				if( IsValidObj(pSelectMover) )
				{
					CWorld *pWorld = pMover->GetWorld();
					if( pWorld )
					{
						pWorld->SetObjFocus( pSelectMover );			// 이놈을 타겟으로 설정함.
						pMover->m_idTracking = pSelectMover->GetId();	// 탭으로 타겟을 바꾸면 자동추적타겟도 그놈으로 바뀐다.
					}
				}
			}
		}
		s_bSelectKeyed = g_bKeyTable[VK_TAB];
	}



	if( /*m_bFlyMove &&*/ m_bLButtonDown || g_bKeyTable[VK_INSERT] )	// 192 = `
	{
		CObj *pObj = pMover->GetWorld()->GetObjFocus();		// 타겟잡힌놈이 있을때만 휘두를수 있다.
		if( pObj && pObj->GetType() == OT_MOVER )
		{
			if( pMover->IsAttackAble( pObj ) )	// 공격 가능한지 검사.
			{
				OBJID	idTarget = ((CMover *)pObj)->GetId();
				ItemProp *pWeapon = pMover->GetActiveHandItemProp();
				if( pWeapon )
				{
					g_pPlayer->PlayCombatMusic();

					if( pWeapon->dwItemKind3 == IK3_WAND )
					{
						D3DXVECTOR3 vFront, vTarget;
						AngleToVector( &vFront, g_pPlayer->GetAngle(), -g_pPlayer->GetAngleX(), 1.0f );
						vTarget = pObj->GetPos() - g_pPlayer->GetPos();
						D3DXVec3Normalize( &vTarget, &vTarget );		// 타겟쪽으로의 벡터의 유닛벡터.
						FLOAT fDot = D3DXVec3Dot( &vFront, &vTarget );
						if( fDot >= cosf(D3DXToRadian(60.0f)) )	// 타겟이 내가 보는 방향의 +-30도 안에 있으면 발사할수 있다.
						{
							if( pMover->IsRangeObj( pObj, 64.0f ) )		// 사정거리에 들어오면 발사.
							{
								pMover->DoAttackMagic( pObj, 0 );
							}
						}
					}
					else
					{
						pMover->SendActMsg( OBJMSG_ATK1, idTarget );
					}
				}
			}
		}
	}

//	fTurnAngle	= 0.6f;
	ItemProp* pItemProp = prj.GetItemProp( g_pPlayer->GetRideItemIdx() );
	if( pItemProp )
	{
		fTurnAngle = pItemProp->fFlightLRAngle;
	}
	else
	{
		Error( "ControlFlying : 빗자루정보 읽기 실패 %d", g_pPlayer->GetRideItemIdx() );
		fTurnAngle = 0.6f;
	}

	if( bUp ) {
		if( g_WorldMng.Get()->GetFullHeight( pMover->GetPos() ) < pMover->GetPos().y ) {
			if( pMover->SendActMsg( OBJMSG_LOOKDOWN ) == 1 ) {
				fMoved	= true;
			}
		}
	}
	else if( bDown ) {
		if( pMover->SendActMsg( OBJMSG_LOOKUP ) == 1 ) {
			fMoved	= true;
		}
	}
	else {
		if( pMover->SendActMsg( OBJMSG_STOP_LOOK ) == 1 ) {
			fMoved	= true;
		}
	}

	if( bLeft ) {
		m_fRollAng -= 1.0f;
		if( m_fRollAng < -45.0f )	
			m_fRollAng = -45.0f;
		if( pMover->SendActMsg( OBJMSG_LTURN, (int)( fTurnAngle * 100.0f ) ) == 1 ) {
			fMoved	= true;
		}
	}
	else if( bRight ) {
		m_fRollAng += 1.0f;
		if( m_fRollAng > 45.0f )	
			m_fRollAng = 45.0f;
		if( pMover->SendActMsg( OBJMSG_RTURN, (int)( fTurnAngle * 100.0f ) ) == 1 ) {
			fMoved	= true;
		}
	}
	else {
		if( m_fRollAng < 0 )
		{
			m_fRollAng += 2.0f;
			if( m_fRollAng > 0 )	m_fRollAng = 0;
		} else
		if( m_fRollAng > 0 )
		{
			m_fRollAng -= 2.0f;
			if( m_fRollAng < 0 )	m_fRollAng = 0;
		}
		if( pMover->SendActMsg( OBJMSG_STOP_TURN ) == 1 ) {
			fMoved	= true;
//			fBehavior	= true;
		}
	}

	// 오른쪽 버튼 드래그는 빗자루 움직임
	if( dwMessage == WM_MOUSEMOVE /*&& m_bRButtonDown*/ )
	{
		float fAng = pMover->GetAngle();
		float fAdd = (point.x - m_ptMouseOld.x) / 2.0f;
		fAng -= fAdd;
		pMover->SetAngle( fAng );
		
		float fAngX = pMover->GetAngleX();
		float fAddX = (point.y - m_ptMouseOld.y) / 4.0f;
		fAngX += fAddX;
		if( fAddX > 0 && fAngX > 45.0f )
			fAngX = 45.0f;
		else
		if( fAddX < 0 && fAngX < -45.0f )
			fAngX = -45.0f;
			
		pMover->SetAngleX( fAngX );

		if( fAdd || fAddX )
			g_DPlay.PostPlayerAngle( TRUE );
	}
	


	BOOL bTempKey;
	if( bTempKey = g_bKeyTable[ '8' ] )
	{
		if( !m_bTemp3ed )
		{
			pMover->SendActMsg( OBJMSG_TEMP2 );
			//			__bTestLOD ^= 1;
		}
	}
	m_bTemp3ed	= bTempKey;
	


	if( fMoved )
	{
		g_DPlay.SendPlayerMoved2( nFrame );
	}
	if( fBehavior )
	{
		pMover->ClearDest();
		g_DPlay.SendPlayerBehavior2();
	}
	
	return nMsg;
}
BOOL CAIMonster2::BeginAttack()
{
	CMover	*pMover = GetMover();

	OBJMSG		dwMsg = OBJMSG_NONE;
	DWORD		dwItemID = 0;
	MoverProp	*pProp = pMover->GetProp();

	// 추격하여 도착하면 선택되었던 공격방식을 적용시킨다.
	switch( m_nAttackType )
	{
	case CAT_NORMAL:		dwMsg = OBJMSG_ATK1;	dwItemID = pProp->dwAtk1;	break;
	case CAT_NORMAL2:		dwMsg = OBJMSG_ATK2;	dwItemID = pProp->dwAtk1;	break;
	case CAT_QUAKEDOUBLE:	dwMsg = OBJMSG_ATK3;	dwItemID = pProp->dwAtk3;	break;
	case CAT_QUAKE_ONE:		dwMsg = OBJMSG_ATK4;	dwItemID = pProp->dwAtk2;	break;
	default:
		ASSERT(0);
	}

	if( dwMsg == OBJMSG_NONE )
		return FALSE;

	if( m_idTarget == NULL_ID )
		return FALSE;

//	LPMODELELEM lpModelElem = prj.m_modelMng.GetModelElem( OT_MOVER, pMover->GetIndex() );
//	if( lpModelElem == NULL )
//		return FALSE;
//	if( lpModelElem->m_nMax 
	dwMsg = OBJMSG_ATK1;

	int nResult = pMover->DoAttackMelee( m_idTarget, dwMsg, dwItemID );
	if( nResult )
	{
		CMover *pTarget = prj.GetMover( m_idTarget );			
		// 이벤트 메세지
		// 보스몬스터가 유저에게 말을 한다.
		switch( m_nAttackType )
		{
		case CAT_QUAKEDOUBLE:
			{
				if( pTarget )
				{
					g_UserMng.AddWorldShout( pMover->GetName(), prj.GetText(TID_GAME_BOSS_BIGMUSCLE_MSG_04),
						pTarget->GetPos(), pTarget->GetWorld() );
				}
			}
			break;
		case CAT_QUAKE_ONE:
			{
				if( pTarget )
				{
					TCHAR szChar[128] = { 0 };
					sprintf( szChar, prj.GetText(TID_GAME_BOSS_BIGMUSCLE_MSG_05), pTarget->GetName() );
					g_UserMng.AddWorldShout( pMover->GetName(), szChar,
						pTarget->GetPos(), pTarget->GetWorld() );
				}
			}
			break;
		}					

		return TRUE;
	} 

	return FALSE;
}