Vector GetRandomSpot()
{
	CWorld *pEnt = GetWorldEntity();
	if ( pEnt )
	{
		Vector vMin, vMax;
		pEnt->GetWorldBounds( vMin, vMax );
		return Vector(
			RandomFloat( vMin.x, vMax.x ),
			RandomFloat( vMin.y, vMax.y ),
			RandomFloat( vMin.z, vMax.z ) );
	}
	else
	{
		return Vector( 0, 0, 0 );
	}
}
Exemple #2
0
// 클라용 대전 가능한 유저인가?
BOOL	CGuildCombat1to1Mng::IsPossibleMover( CMover* pMover )
{
	if( !pMover )
		return FALSE;
	
	CWorld* pWorld = pMover->GetWorld();
	if( pWorld )
	{
		if( pWorld->GetID() >= WI_WORLD_GUILDWAR1TO1_0 &&
			pWorld->GetID() <= WI_WORLD_GUILDWAR1TO1_L )
		{
			if( pMover->m_nGuildCombatState != 0 )
				return TRUE;
		}
	}
	
	return FALSE;
}
Exemple #3
0
void CQuiz::SetNPC()
{
	CMover* pMover	= (CMover*)CreateObj( D3DDEVICE, OT_MOVER, m_sNPC.dwNPCId );
	if( !pMover )
	{
		Error( "CQuiz::SetNPC() - pMover is NULL - %d, %s", m_sNPC.dwNPCId, m_sNPC.strCharKey.c_str() );
		return;
	}
	lstrcpy( pMover->m_szCharacterKey, m_sNPC.strCharKey.c_str() );
	pMover->InitNPCProperty();
	pMover->InitCharacter( pMover->GetCharacter() );
	pMover->SetPos( m_sNPC.vPos );
	pMover->InitMotion( MTI_STAND );
	pMover->UpdateLocalMatrix();
	pMover->AddItToGlobalId();
	m_sNPC.idNpc = pMover->GetId();
	CWorld* pWorld	= g_WorldMng.GetWorld( WI_WORLD_MADRIGAL );
	if( pWorld )
		pWorld->ADDOBJ( pMover, FALSE, nDefaultLayer );
}
//**********************************************************************
// void CWorldSquare::build()
// Build
//**********************************************************************
void CWorldSquare::build() {
#ifndef OPTIMIZE
  try {
#endif

    // Get our Values From World
    CWorld *pWorld = CWorld::Instance();
    iNumberOfCategories = pWorld->getCategoryCount();
    iMinAge             = pWorld->getMinAge();
    iMaxAge             = pWorld->getMaxAge();
    bAgePlus            = pWorld->getAgePlusGroup();

#ifndef OPTIMIZE
    if (iNumberOfCategories <= 0)
      CError::errorMissing(PARAM_CATEGORIES);
    if (iMinAge < 0)
      CError::errorMissing(PARAM_MIN_AGE);
    if (iMaxAge <= 0)
      CError::errorMissing(PARAM_MAX_AGE);
    if (iMaxAge < iMinAge)
      CError::errorLessThan(PARAM_MAX_AGE, PARAM_MIN_AGE);
#endif

    // Build our Grid
    iHeight = iNumberOfCategories;
    iWidth  = (iMaxAge+1)-iMinAge;

    pGrid = new double*[iHeight];
    for (int i = 0; i < iHeight; ++i)
      pGrid[i] = new double[iWidth];

    // Zero it
    zeroGrid();

#ifndef OPTIMIZE
  } catch (string &Ex) {
    Ex = "CWorldSquare.build()->" + Ex;
    throw Ex;
  }
#endif
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CMapData_Server::GetMapBounds( Vector &vecMins, Vector &vecMaxs )
{
	CWorld *pWorld = static_cast<CWorld*>( GetWorldEntity() );
	if ( pWorld )
	{
		// Get the world bounds.
		pWorld->GetWorldBounds( vecMins, vecMaxs );

		// Backward compatability...
		if ( ( vecMins.LengthSqr() == 0.0f ) && ( vecMaxs.LengthSqr() == 0.0f ) )
		{
			vecMins.Init( -6500.0f, -6500.0f, -6500.0f );
			vecMaxs.Init( 6500.0f, 6500.0f, 6500.0f );
		}
	}
	else
	{
		Assert( 0 );
		vecMins.Init( 0.0f, 0.0f, 0.0f );
		vecMaxs.Init( 1.0f, 1.0f, 1.0f );
	}
}
Exemple #6
0
BOOL CWndCoupleTalk::OnChildNotify( UINT message, UINT nID, LRESULT* pLResult ) 
{ 
	CWorld* pWorld = g_WorldMng();
	CObj* pObj = pWorld->GetObjFocus();
	if( pObj && pObj->GetType() == OT_MOVER )
	{
		switch( nID )
		{
		case WIDC_EDIT2: // 본문 
			if( message != EN_RETURN )
				break;
		case WIDC_BUTTON1:
			{
				CWndEdit* pWndEdit2 = (CWndEdit*)GetDlgItem( WIDC_EDIT2 );
				CString stPropose( pWndEdit2->m_string);
				if(stPropose.GetLength()>30)
					g_WndMng.PutString( "뚤꼇폅,멩겜코휭꼇콘낚법15몸櫓匡俚륜。", NULL, prj.GetTextColor( TID_GAME_NOTCOUPLETARGET ) );
				else
				{
					//警속랙箇句口
					g_DPlay.SendPropose(((CMover*)pObj)->GetName(),stPropose);
					Destroy( TRUE );
					return TRUE;
				}

				pWndEdit2->Empty();
				
			}
			break;
		}
	}
	if( nID == WTBID_CLOSE )
	{
		Destroy( TRUE );
		return TRUE;
	}
	return CWndNeuz::OnChildNotify( message, nID, pLResult ); 
} 
uint8 CEntitiesFactory::Init(CWorld &world) {
	uint8 ret = 0;
	
	Init();

	m_world = &world;

	for (std::vector<SEntityParams *>::iterator itr = g_entitiesParams.begin();
	itr != g_entitiesParams.end(); ++itr) {
		CEntity * et = SpawnEntity(*itr);
		world.AddEntity(et);
	}

	return ret;
}
Exemple #8
0
int Sphere_OnTick()
{
	// Give the world (CMainTask) a single tick. RETURN: 0 = everything is fine.
	const char *m_sClassName = "Sphere";
	EXC_TRY("Tick");
#ifdef _WIN32
	EXC_SET("service");
	g_Service.OnTick();
#endif
	EXC_SET("ships_tick");
	g_Serv.ShipTimers_Tick();

	EXC_SET("world");
	g_World.OnTick();

	// process incoming data
	EXC_SET("network-in");
#ifndef _MTNETWORK
	g_NetworkIn.tick();
#else
	g_NetworkManager.processAllInput();
#endif

	EXC_SET("server");
	g_Serv.OnTick();

	// push outgoing data
#ifndef _MTNETWORK
	if (g_NetworkOut.isActive() == false)
	{
		EXC_SET("network-out");
		g_NetworkOut.tick();
	}
#else
	EXC_SET("network-tick");
	g_NetworkManager.tick();

	EXC_SET("network-out");
	g_NetworkManager.processAllOutput();
#endif

	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_DEBUG_END;
	return g_Serv.m_iExitFlag;
}
Exemple #9
0
void Sphere_ExitServer()
{
	// Trigger server quit
	g_Serv.r_Call("f_onserver_exit", &g_Serv, NULL);

	g_Serv.SetServerMode(SERVMODE_Exiting);

#ifndef _MTNETWORK
	g_NetworkOut.waitForClose();
#else
	g_NetworkManager.stop();
#endif
	g_Main.waitForClose();
	g_PingServer.waitForClose();
	g_asyncHdb.waitForClose();
#if !defined(_WIN32) || defined(_LIBEV)
	if ( g_Cfg.m_fUseAsyncNetwork != 0 )
		g_NetworkEvent.waitForClose();
#endif
		
	g_Serv.SocketsClose();
	g_World.Close();

	LPCTSTR Reason;
	switch ( g_Serv.m_iExitFlag )
	{
		case -10:	Reason = "Unexpected error occurred";			break;
		case -9:	Reason = "Failed to bind server IP/port";		break;
		case -8:	Reason = "Failed to load worldsave files";		break;
		case -3:	Reason = "Failed to load server settings";		break;
		case -1:	Reason = "Shutdown via commandline";			break;
#ifdef _WIN32
		case 1:		Reason = "X command on console";				break;
#else
		case 1:		Reason = "Terminal closed by SIGHUP signal";	break;
#endif
		case 2:		Reason = "SHUTDOWN command executed";			break;
		case 4:		Reason = "Service shutdown";					break;
		case 5:		Reason = "Console window closed";				break;
		case 6:		Reason = "Proccess aborted by SIGABRT signal";	break;
		default:	Reason = "Server shutdown complete";			break;
	}

	g_Log.Event(LOGM_INIT|LOGL_FATAL, "Server terminated: %s (code %d)\n", Reason, g_Serv.m_iExitFlag);
	g_Log.Close();
}
Exemple #10
0
/* =============================================================================
 =============================================================================== */
bool CWorld::gotoView(int ndx, float fTime, bool bUpdateCamera)
{
	if (ndx == -1) ndx = getViewSet().getCur();
	if (!getViewSet().isValid(ndx))
		return false;

	getViewSet().setCur(ndx);

	CView	&View = getView(ndx);
	applyViewActiveLayers(View.getActiveLayers());
	g_Set.deserialize(View.getSettings());

	//  after all data is loaded so we can set up the timeline
	gotoViewTime(View);
	g_Set.m_ShowTimeline = (getDataSet().getActiveCnt() > 0 || getTextureSet().getMovieActive());
	g_World.updateTerrain();
	g_Draw.drawGL();

	if (bUpdateCamera)
		g_Draw.gotoCameraView(View.getLookAt(), View.getElevation(), View.getAzimuth(), View.getDolly(), fTime);

	return true;
}
Exemple #11
0
void CCreateMonster::CreateMonster( CUser* pUser, DWORD dwObjId, D3DXVECTOR3 vPos )
{
	if( (int)( m_mapCreateMonsterInfo.size() ) >= m_nMaxCreateNum )
	{
		pUser->AddDefinedText( TID_GAME_CREATEMON_LIMIT );
		return;
	}
	
	CItemElem* pItemElem = pUser->m_Inventory.GetAtId( dwObjId );
	if( !IsUsableItem( pItemElem ) )
		return;

	CREATE_MONSTER_PROP* pCreateMonsterProp = GetCreateMonsterProp( pItemElem );
	if( !pCreateMonsterProp )
		return;

	DWORD dwMonsterId = pCreateMonsterProp->GetRandomMonsterId();
	if( dwMonsterId == NULL_ID )
		return;

	CWorld* pWorld = pUser->GetWorld();
	MoverProp* pMoverProp = prj.GetMoverProp( dwMonsterId );

	if( pWorld && pMoverProp && pMoverProp->dwID != 0 )
	{
		D3DXVECTOR3 vDist2 = pUser->GetPos() - vPos;
		float fDist = D3DXVec3Length( &vDist2 );			// 두좌표간의 거리
		if( 15.f < fDist )
		{
			pUser->AddDefinedText( TID_GAME_CREATEMON_F_15 );
			return;
		}

		int nAttr = pWorld->GetHeightAttribute( vPos.x, vPos.z );		// 이동할 위치의 속성 읽음.
		if( nAttr == HATTR_NOWALK || nAttr == HATTR_NOMOVE )		// 못 움직이는 곳이면 Pass
		{
			pUser->AddDefinedText( TID_GAME_CREATEMON_F_AREA );
			return;
		}
		if( pUser->IsRegionAttr( RA_SAFETY ))		// 안전지역이면 Pass
		{
			pUser->AddDefinedText( TID_GAME_CREATEMON_F_AREA );
			return;
		}
		if( pWorld->GetID() != WI_WORLD_MADRIGAL )
		{
			pUser->AddDefinedText( TID_GAME_CREATEMON_F_AREA );
			return;
		}

		CObj* pObj	= CreateObj( D3DDEVICE, OT_MOVER, pMoverProp->dwID );
		if( NULL == pObj )	return;	// ASSERT( pObj );
		pObj->SetPos( vPos );
		pObj->InitMotion( MTI_STAND );
		pObj->UpdateLocalMatrix();
		((CMover*)pObj)->m_bActiveAttack = FALSE;
		((CMover*)pObj)->AddItToGlobalId();
		pWorld->ADDOBJ( pObj, FALSE, pUser->GetLayer() );
		
		LogItemInfo aLogItem;
		aLogItem.Action = "i";
		aLogItem.SendName = pUser->GetName();
		char szTemp[128] = {0,};
		sprintf( szTemp, "M_C_%s", pMoverProp->szName ); 
		memset( szTemp+31, 0, sizeof(szTemp)-31 );

		aLogItem.RecvName = szTemp;
		aLogItem.Gold = aLogItem.Gold2 = pUser->GetGold();
		aLogItem.Gold_1 = ((CMover*)pObj)->GetId();
		aLogItem.WorldId = pUser->GetWorld()->GetID();
		g_DPSrvr.OnLogItem( aLogItem, pItemElem, 1 );

		pUser->AddDefinedText( TID_GAME_CREATEMON_S, "\"%s\"", pMoverProp->szName );
		pUser->RemoveItem( (BYTE)( dwObjId ), (short)( 1 ) );
		
		CREATE_MONSTER_INFO createMonsterInfo;
		createMonsterInfo.chState = 'N';
		createMonsterInfo.dwOwnerId = pUser->m_idPlayer;
		createMonsterInfo.dwEndTick = pCreateMonsterProp->dwKeepTime + GetTickCount();
		m_mapCreateMonsterInfo.insert( make_pair( ((CMover*)pObj)->GetId(), createMonsterInfo ) );
	}
}
Exemple #12
0
int Sphere_InitServer( int argc, char *argv[] )
{
#ifdef EXCEPTIONS_DEBUG
	const char *m_sClassName = "Sphere";
#endif
	EXC_TRY("Init");
	ASSERT(MAX_BUFFER >= sizeof(CEvent));
	ASSERT(sizeof(int) == sizeof(DWORD));	// make this assumption often.
	ASSERT(sizeof(ITEMID_TYPE) == sizeof(DWORD));
	ASSERT(sizeof(WORD) == 2 );
	ASSERT(sizeof(DWORD) == 4 );
	ASSERT(sizeof(NWORD) == 2 );
	ASSERT(sizeof(NDWORD) == 4 );
	ASSERT(sizeof(CUOItemTypeRec) == 37 ); // byte pack working ?
	ASSERT((std::numeric_limits<size_t>::min)() == 0); // ensure unsigned

#ifdef _WIN32
	if ( !QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&llTimeProfileFrequency)) )
		llTimeProfileFrequency = 1000;

	#if !defined(_DEBUG) && !defined(__MINGW32__)
		EXC_SET("setting exception catcher");
		SetExceptionTranslator();
	#endif
#endif

	EXC_SET("loading");
	if ( !g_Serv.Load() )
		return -3;

	if ( argc > 1 )
	{
		EXC_SET("cmdline");
		if ( !g_Serv.CommandLine(argc, argv) )
			return -1;
	}

	WritePidFile(2);

	EXC_SET("load world");
	if ( !g_World.LoadAll() )
		return -8;

	EXC_SET("sockets init");
	if ( !g_Serv.SocketsInit() )
		return -9;

	//	load auto-complete dictionary
	EXC_SET("auto-complete");
	{
		CFileText	dict;
		if ( dict.Open(SPHERE_FILE ".dic", OF_READ|OF_TEXT|OF_DEFAULTMODE) )
		{
			TCHAR * pszTemp = Str_GetTemp();
			size_t count = 0;
			while ( !dict.IsEOF() )
			{
				dict.ReadString(pszTemp, SCRIPT_MAX_LINE_LEN-1);
				if ( *pszTemp )
				{
					TCHAR *c = strchr(pszTemp, '\r');
					if ( c != NULL )
						*c = '\0';

					c = strchr(pszTemp, '\n');
					if ( c != NULL )
						*c = '\0';

					if ( *pszTemp != '\0' )
					{
						count++;
						g_AutoComplete.AddTail(pszTemp);
					}
				}
			}
			g_Log.Event(LOGM_INIT, "Auto-complete dictionary loaded (contains %" FMTSIZE_T " words)\n", count);
			dict.Close();
		}
	}

	EXC_SET("finalizing");
	g_Serv.SetServerMode(SERVMODE_Run);
	g_Log.Event(LOGM_INIT, "Startup complete (Items=%lu, Chars=%lu, Accounts=%lu)\nPress '?' for console commands\n\n", g_Serv.StatGet(SERV_STAT_ITEMS), g_Serv.StatGet(SERV_STAT_CHARS), g_Serv.StatGet(SERV_STAT_ACCOUNTS));

	if ( !g_Accounts.Account_GetCount() )
		g_Log.Event(LOGL_WARN|LOGM_INIT, "The server has no accounts. To create admin account you must type:\n  ACCOUNT ADD [login] [password]\n  ACCOUNT [login] PLEVEL 7\n");

	// Trigger server start
	g_Serv.r_Call("f_onserver_start", &g_Serv, NULL);
	return g_Serv.m_iExitFlag;

	EXC_CATCH;

	EXC_DEBUG_START;
	g_Log.EventDebug("cmdline argc=%d starting with %p (argv1='%s')\n", argc, static_cast<void *>(argv), ( argc > 2 ) ? argv[1] : "");
	EXC_DEBUG_END;
	return -10;
}
Exemple #13
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
}
Exemple #14
0
/*
 * Do some CSG operation with one brush in this world and one brush in other world.
 */
void CWorld::DoCSGOperation(
    CEntity &enThis,
    CWorld &woOther,
    CEntity &enOther,
    const CPlacement3D &plOther,
    void (CObject3D::*DoCSGOpenSector)(CObject3D &obA, CObject3D &obB),
    void (CObject3D::*DoCSGClosedSectors)(CObject3D &obA, CObject3D &obB)
    )
{
  // assure that floating point precision is 53 bits
  AssureFPT_53();

  // get relevant brush mips in each brush
  CBrushMip &bmThis  = *GetBrushMip(enThis);
  CBrushMip &bmOther = *GetBrushMip(enOther);
  if (&bmThis==NULL || &bmOther==NULL) {
    return;
  }

  // get open sector of the other brush to object
  CBrushSectorSelectionForCSG selbscOtherOpen;
  bmOther.SelectOpenSector(selbscOtherOpen);
  CObject3D obOtherOpen;
  DOUBLEaabbox3D boxOtherOpen;
  woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherOpen, plOther,
    obOtherOpen, enThis.en_plPlacement, boxOtherOpen);

  // if there is an open sector in other object
  if (obOtherOpen.ob_aoscSectors.Count()>0) {
    CObject3D obResult;
    // deportalize the open sector
    obOtherOpen.TurnPortalsToWalls();

    // if there are any sectors in this brush
    if (bmThis.bm_abscSectors.Count()>0) {
      // move affected part of this brush to an object3d object
      CObject3D obThis;
      MoveTargetBrushPartToObject(enThis, boxOtherOpen, obThis);
      // do the open sector CSG operation on the objects
      _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG);
      (obResult.*DoCSGOpenSector)(obThis, obOtherOpen);
      _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG);

    // if there are no sectors in this brush
    } else {
      // just put the open sector directly in the result
      obResult = obOtherOpen;
    }
    // return the result back to this brush
    AddObjectToBrush(obResult, enThis);
  }

  // get closed sectors of the other brush to object
  CBrushSectorSelectionForCSG selbscOtherClosed;
  bmOther.SelectClosedSectors(selbscOtherClosed);
  CObject3D obOtherClosed;
  DOUBLEaabbox3D boxOtherClosed;
  woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherClosed, plOther,
    obOtherClosed, enThis.en_plPlacement, boxOtherClosed);

  // if there are closed sectors in other object
  if (obOtherClosed.ob_aoscSectors.Count()>0) {
    CObject3D obResult;

    // if there are any sectors in this brush
    if (bmThis.bm_abscSectors.Count()>0) {
      // move affected part of this brush to an object3d object
      CObject3D obThis;
      MoveTargetBrushPartToObject(enThis, boxOtherClosed, obThis);
      // do the closed sectors CSG operation on the objects
      _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG);
      (obResult.*DoCSGClosedSectors)(obThis, obOtherClosed);
      _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG);

    // if there are no sectors in this brush
    } else {
      // just put the closed sectors directly in the result
      obResult = obOtherClosed;
    }
    // return the result back to this brush
    AddObjectToBrush(obResult, enThis);
  }
}
Exemple #15
0
//
//
// 클라이언트용
void CMover::ProcessMoveArrival( CCtrl *pObj )
{
	// 클라이언트 처리
	if( IsActiveMover() )
	{
		switch( m_oaCmd )	// 목표에 도착한 후의 명령 처리.
		{
		case OBJACT_USESKILL:
			if( pObj->GetType() == OT_MOVER && ( m_SkillTimerStop || m_SkillTimer.TimeOut() ) )
			{
				CWorld *pWorld = GetWorld();
				D3DXVECTOR3 vStart = GetPos();			vStart.y += 0.5f;
				D3DXVECTOR3 vEnd   = pObj->GetPos();	vEnd.y += 0.5f;

				if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) )
				{
					g_WndMng.PutString( prj.GetText( TID_GAME_BLOCKTARGETING ), NULL, prj.GetTextColor( TID_GAME_BLOCKTARGETING ) );
					g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE );
					break;
				}

				PlayCombatMusic();

				int nSkillIdx = GetCmdParam(0);
				OBJID idTarget = (OBJID)GetCmdParam(1);
				SKILLUSETYPE sutType = (SKILLUSETYPE)GetCmdParam(2);
				if( (m_dwReqFlag & REQ_USESKILL) == 0 )	// 응답 요청중일땐 다시 보내선 안된다.
				{
					LPSKILL pSkill	= GetSkill( 0, nSkillIdx );		// this가 가진 스킬중 nIdx에 해당하는 스킬을 꺼낸다.
					if( pSkill == NULL )
					{
						Error( "CMD_SetUseSkill : %s skill(%d) not found", m_szName, nSkillIdx );
						return;	// skill not found
					}

					if( pSkill->dwSkill == SI_MAG_MAG_BLINKPOOL )
					{
						CWndWorld* pWndWorld;
						pWndWorld = (CWndWorld*)g_WndMng.m_pWndWorld;		
						{
							vStart = GetPos();		vStart.y += 1.0f;
							vEnd = pWndWorld->m_vTelePos;
							if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) )
							{
								g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE );
								g_WndMng.PutString( prj.GetText( TID_GAME_BLOCKTARGETING ), NULL, prj.GetTextColor( TID_GAME_BLOCKTARGETING ) );
								break;
							}
						}
						
						if(g_pMoveMark!=NULL) g_pMoveMark->m_pSfxObj->m_nCurFrame=180;
						CreateSfx(g_Neuz.m_pd3dDevice,XI_GEN_MOVEMARK01,pWndWorld->m_vTelePos);
					}
					

					// 뒤에서 공격가능한 스킬인지 판단한다
					// 강탈 스킬은 뒤에서 사용가능(일단 클라에서 판정하자~)
					if( pSkill->GetProp() && pSkill->GetProp()->dwAtkStyle == AS_BACK )
					{						
						D3DXVECTOR3 v3Pos;
						D3DXVECTOR3 v3PosSrc;
						D3DXVECTOR3 v3PosDest;
						
						// 방향벡터 1
						v3PosSrc = pObj->GetPos() - GetPos();
						D3DXVec3Normalize( &v3PosSrc, &v3PosSrc );
						
						// 방향벡터 2
						AngleToVectorXZ( &v3Pos, pObj->GetAngle(), 3.0f );
						v3PosDest = (pObj->GetPos()+v3Pos) - pObj->GetPos();
						D3DXVec3Normalize( &v3PosDest, &v3PosDest );
						
						FLOAT fDir = D3DXVec3Dot( &v3PosSrc, &v3PosDest );

						// 뒤가 아니면 스킬 사용 불가!
						if( fDir < 0.3f )
						{
							g_WndMng.PutString( prj.GetText(TID_GAME_NEVERKILLSTOP) );
							break;
						}
					}
					
#if __VER >= 8 // __S8_PK
					// 카오에게 좋은 스킬을 사용할때는 Control 키를 눌러야 함
					if( g_eLocal.GetState( EVE_PK ) )
					{
						CMover * pMover;
						pMover = prj.GetMover( idTarget );
						if( IsValidObj(pMover) && pMover != g_pPlayer && pMover->IsPlayer() && pMover->IsChaotic() )
							if( pSkill->GetProp()->nEvildoing > 0 ) // 좋은 스킬
								if( !(GetAsyncKeyState(VK_CONTROL) & 0x8000) )
									break;
					}
#endif // __VER >= 8 // __S8_PK
					
					TRACE( "OBJACT_USESKILL %d\n", nSkillIdx );
#if __VER >= 8 // __S8_PK
					BOOL bControl = ((GetAsyncKeyState(VK_CONTROL) & 0x8000)? TRUE:FALSE);
					g_DPlay.SendUseSkill( 0, nSkillIdx, idTarget, sutType, bControl );	// 목표지점에 도착하면 스킬쓴다고 알림.
#else // __VER >= 8 // __S8_PK
					g_DPlay.SendUseSkill( 0, nSkillIdx, idTarget, sutType );	// 목표지점에 도착하면 스킬쓴다고 알림.
#endif // __VER >= 8 // __S8_PK

					m_dwReqFlag |= REQ_USESKILL;	// 응답 요청중
					
				}
				ClearDestObj();		// 목표에 도달하면 추적을 멈춤.
				SendActMsg( OBJMSG_STOP );
				if( !m_SkillTimerStop )
					m_SkillTimer.Reset();
			}
			break;
		//------------------------------------------
		case OBJACT_MELEE_ATTACK:
			if( pObj->GetType() == OT_MOVER )
			{
				ItemProp *pItemProp = GetActiveHandItemProp(); 
				if( pItemProp && pItemProp->dwItemKind3 == IK3_YOYO )
				{
					CWorld *pWorld = GetWorld();
					D3DXVECTOR3 vStart = GetPos();			vStart.y += 0.5f;
					D3DXVECTOR3 vEnd   = pObj->GetPos();	vEnd.y += 0.5f;
					
					if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) )
					{
						g_WndMng.PutString( prj.GetText( TID_GAME_BLOCKTARGETING ), NULL, prj.GetTextColor( TID_GAME_BLOCKTARGETING ) );
						break;
					}
				}
				
				DoAttackMelee( (CMover *)pObj );		// pObj를 일반공격.
			}
			break;
		//---------------------------------------------
		case OBJACT_MAGIC_ATTACK:
			if( pObj->GetType() == OT_MOVER )
			{
				PlayCombatMusic();

				OBJID	idTarget = GetCmdParam(0);
				int		nMagicPower = GetCmdParam(1);
				CMover *pTarget = prj.GetMover( idTarget );		// 타겟의 아이디를 포인터로 읽음.
				if( IsInvalidObj(pTarget) )		break;			// 타겟이 거시기한 포인터면 취소시킴.
				
				SendActMsg( OBJMSG_STAND );
				ClearDestObj();		// 목표에 도달하면 추적을 멈춤.
				DoAttackMagic( pTarget, nMagicPower );
			}
			break;
		case OBJACT_RANGE_ATTACK:
			{
				if( pObj->GetType() == OT_MOVER )
				{
					PlayCombatMusic();

					OBJID	idTarget = GetCmdParam(0);
					int		nPower = GetCmdParam(1);
					CMover *pTarget = prj.GetMover( idTarget );		// 타겟의 아이디를 포인터로 읽음.
					if( IsInvalidObj(pTarget) )		break;			// 타겟이 거시기한 포인터면 취소시킴.
					
					SendActMsg( OBJMSG_STAND );
					SendActMsg( OBJMSG_STOP_TURN );
					
					ClearDestObj();									// 목표에 도달하면 추적을 멈춤.

					DoAttackRange( pTarget, nPower, 0 );			// nPower를 dwItemID에 넣는다.
				}				
			}
			break;
		//---------------------------------------------
		case OBJACT_USEITEM:
			ClearDestObj();	// 그외는 목표에 도착하면 멈춤.
			SendActMsg( OBJMSG_STAND );
			SetAngle( GetDegree(pObj->GetPos(), GetPos()) );		// 목표쪽으로 몸을 돌림.
			break;
		//---------------------------------------------
		case OBJACT_COLLECT:
			ClearDestObj();	// 그외는 목표에 도착하면 멈춤.
			SendActMsg( OBJMSG_STOP );
			SetAngle( GetDegree(pObj->GetPos(), GetPos()) );		// 목표쪽으로 몸을 돌림.
			g_DPlay.SendDoCollect( pObj );						// 서버로 보냄.
			break;
		//---------------------------------------------
		default:
			ClearDestObj();	// 그외는 목표에 도착하면 멈춤.
			SendActMsg( OBJMSG_STOP );
			break;
			
		}
		SetCmd( OBJACT_NONE );
	}
	else
	{
		BOOL bQuery	= m_pActMover->IsMove();
		
		ClearDestObj();	// 그외는 목표에 도착하면 멈춤.
		SendActMsg( OBJMSG_STOP );
		OnArrive( pObj->GetId(), 0 );

		if( bQuery )
			g_DPlay.SendQueryGetDestObj( this );
	}
}
Exemple #16
0
//
//
// 월드서버용
void CMover::ProcessMoveArrival( CCtrl *pObj )
{
	switch( m_oaCmd )	// 목표에 도착한 후의 명령 처리.
	{
	case OBJACT_USESKILL:
		if( pObj->GetType() == OT_MOVER )	// 타겟이 무버일때면 처리함.
		{
			int nSkillIdx = GetCmdParam(0);
			OBJID idTarget = (OBJID)GetCmdParam(1);
			SKILLUSETYPE sutType = (SKILLUSETYPE)GetCmdParam(2);

			LPSKILL pSkill	= GetSkill( 0, nSkillIdx );		// this가 가진 스킬중 nIdx에 해당하는 스킬을 꺼낸다.
			if( pSkill == NULL )
			{
				Error( "ProcessMoveArrival mover:%s skill(%d) not found.", m_szName, nSkillIdx );
				return;	// skill not found
			}
#if __VER >= 10 // __LEGEND	//	10차 전승시스템	Neuz, World, Trans
			if( pSkill->dwSkill == SI_MAG_MAG_BLINKPOOL || pSkill->dwSkill == SI_RIG_HERO_RETURN )
#else //__LEGEND	//	10차 전승시스템	Neuz, World, Trans
			if( pSkill->dwSkill == SI_MAG_MAG_BLINKPOOL )
#endif	//__LEGEND	//	10차 전승시스템	Neuz, World, Trans
				return;		// 아직 서버명령으로는 블링크풀 사용못함.

			CWorld *pWorld = GetWorld();
			D3DXVECTOR3 vStart = GetPos();			vStart.y += 0.5f;
			D3DXVECTOR3 vEnd   = pObj->GetPos();	vEnd.y += 0.5f;
 
			if( pWorld->IntersectObjLine( NULL, vStart, vEnd, FALSE, FALSE ) )	// 시전자와 타겟사이 장애물을 검사.
			{
				if( IsPlayer() )
					((CUser *)this)->AddDefinedText( TID_GAME_BLOCKTARGETING, "" );
				break;
			}

#if __VER >= 8 // __S8_PK
			BOOL bSuccess = DoUseSkill( 0, nSkillIdx, idTarget, sutType, FALSE );		// 목표지점에 도착하면 스킬 사용시작.
#else // __VER >= 8 // __S8_PK
			BOOL bSuccess = DoUseSkill( 0, nSkillIdx, idTarget, sutType );		// 목표지점에 도착하면 스킬 사용시작.
#endif // __VER >= 8 // __S8_PK
			if( bSuccess == FALSE )
				if( IsPlayer() )
					((CUser *)this)->m_playTaskBar.OnEndSkillQueue( (CUser *)this );

			ClearDestObj();		// 목표에 도달하면 추적을 멈춤.
			SendActMsg( OBJMSG_STOP );
		}
		break;

	default:
		SendActMsg( OBJMSG_STOP );
		ClearDestObj();		// 목표에 도달하면 추적을 멈춤.
		OnArrive( pObj->GetId(), 0 );
		break;
	} // switch

	SetCmd( OBJACT_NONE );
	
	if( IsPlayer() )
		((CUser*)this)->AddQueryGetDestObj( NULL_ID );
}
Exemple #17
0
// gets called every frame to draw the scene
void CRenderer::Update(const float dt, const uint32_t ticks)
{
    CObj* obj, *localctrl;
    int localctrlid;
    OBJITER iter;
    matrix_t m;
    vec3_t dir, up, side;
    CFrustum frustum;
    CWorld* world;

    localctrl = m_world->GetLocalController();
    localctrlid = m_world->GetLocalObj()->GetID();
    world = m_world->GetInterpWorld();

    const vec3_t campos = localctrl->GetOrigin();
    const quaternion_t camrot = localctrl->GetRot();

    m.SetCamTransform(campos, camrot);
    m.GetVec3Cam(&dir, &up, &side);
    dir = -dir;
    frustum.Setup(campos, dir, up, side,
                  RENDERER_FOV, (float)m_width/(float)m_height,
                  PLANE_NEAR,
                  PLANE_FAR);

    // light floating above the players head
    const vec3_t lightpos0(campos + vec3_t(0,25.0f,0));
    const quaternion_t lightrot0(quaternion_t(vec3_t::xAxis, -90.0f*lynxmath::DEGTORAD));
    const float lightpos0_4f[4] = {lightpos0.x, lightpos0.y, lightpos0.z, 1};
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos0_4f);
    if(m_shaderactive)
    {
        if(m_useShadows)
        {
            glUseProgram(0); // draw shadowmap with fixed function pipeline
            PrepareShadowMap(lightpos0,
                    lightrot0,
                    world,
                    localctrlid); // the player is the light
        }
        glUseProgram(m_program); // activate shader
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(m.pm);

    glClear(GL_DEPTH_BUFFER_BIT);
    glClear(GL_COLOR_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0); // normal texture channel

    if(m_shaderactive)
    {
        glUniform1i(m_tex, 0); // good old textures: GL_TEXTURE0
        glUniform1i(m_normalMap, 1); // normal maps are GL_TEXTURE1
        glUniform1i(m_lightmap, 2); // lightmap

        if(m_useShadows)
        {
            glUniform1i(m_shadowMapUniform, 7);
            glActiveTexture(GL_TEXTURE7); // shadow mapping texture GL_TEXTURE7
            glBindTexture(GL_TEXTURE_2D, m_depthTextureId);
            glActiveTexture(GL_TEXTURE0);
        }

#ifdef DRAW_NORMALS
        glUseProgram(0); // use fixed pipeline for this debug mode
#endif
    }

    // Main drawing
    DrawScene(frustum, world, localctrlid, false);

    if(m_shaderactive)
        glUseProgram(0); // don't use shader for particles

    // Particle Draw
    glDisable(GL_LIGHTING);
    glDepthMask(false);
    for(iter=world->ObjBegin();iter!=world->ObjEnd();++iter)
    {
        obj = (*iter).second;

        if(obj->GetMesh())
        {
            // Animate mesh is done in the particle loop
            // and not in DrawScene, because DrawScene
            // can be called multiple times per frame
            obj->GetMesh()->Animate(obj->GetMeshState(), dt);
        }

        if(obj->GetID() == localctrlid || !obj->GetParticleSystem())
            continue;

        // Update/animate the particles, depending on dt and the current position.
        obj->GetParticleSystem()->Update(dt, ticks, obj->GetOrigin());

        // Draw the particles. FIXME: this should use a frustum test
        obj->GetParticleSystem()->Render(side, up, dir);
    }
    glDepthMask(true);
    glColor4f(1,1,1,1);
    glEnable(GL_LIGHTING);

#ifdef DRAW_NORMALS
    // Draw vertex normals of level geometry (not face normals)
    if(world && world->GetBSP())
    {
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
        world->GetBSP()->RenderNormals();
        glEnable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
    }
#endif

    // Draw weapon
    if(m_shaderactive) // use shader for weapon
        glUseProgram(m_program);

    CModelMD5* viewmodel;
    md5_state_t* viewmodelstate;
    m_world->m_hud.GetModel(&viewmodel, &viewmodelstate);
    glDisable(GL_LIGHTING);
    if(viewmodel)
    {
        glClear(GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
          glLoadIdentity();
          viewmodel->Render(viewmodelstate);
          viewmodel->Animate(viewmodelstate, dt);
        glPopMatrix();
    }
    glEnable(GL_LIGHTING);

    // Draw HUD
    if(m_shaderactive)
        glUseProgram(0); // no shader for HUD

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0, m_width, m_height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glColor4f(1,1,1,1);
    glBindTexture(GL_TEXTURE_2D, m_crosshair);

    // Draw center crosshair
    glBegin(GL_QUADS);
        glTexCoord2d(0,1);
        glVertex3f((m_width-m_crosshair_width)*0.5f, (m_height-m_crosshair_height)*0.5f,0.0f);
        glTexCoord2d(0,0);
        glVertex3f((m_width-m_crosshair_width)*0.5f, (m_height+m_crosshair_height)*0.5f,0.0f);
        glTexCoord2d(1,0);
        glVertex3f((m_width+m_crosshair_width)*0.5f, (m_height+m_crosshair_height)*0.5f,0.0f);
        glTexCoord2d(1,1);
        glVertex3f((m_width+m_crosshair_width)*0.5f, (m_height-m_crosshair_height)*0.5f,0.0f);
    glEnd();

    // draw HUD text: score, health...
    char hudtextbuf[64];
    sprintf(hudtextbuf, "Frags: %i", m_world->m_hud.score);
    m_font.DrawGL(10.0f, m_height - 30.0f, 0.0f, hudtextbuf);
    sprintf(hudtextbuf, "%i", m_world->m_hud.health);
    m_font.DrawGL(10.0f, m_height - 35.0f - (float)m_font.GetHeight(), 0.0f, hudtextbuf);

#ifdef DRAW_SHADOWMAP // draw a small window with the scene from the light POV
    if(m_shaderactive)
    {
        //glBindTexture(GL_TEXTURE_2D, m_depthTextureId);
        glBindTexture(GL_TEXTURE_2D, g_fboShadowCamColor);
        const float shadowmap_debug_width = 200.0f;
        const float shadowmap_debug_height = shadowmap_debug_width*(float)m_height/(float)m_width;
        glBegin(GL_QUADS);
            glTexCoord2d(0,1); // upper left
            glVertex3f(0.0f, 0.0f, 0.0f);
            glTexCoord2d(0,0); //lower left
            glVertex3f(0.0f, shadowmap_debug_height, 0.0f);
            glTexCoord2d(1,0); //lower right
            glVertex3f(shadowmap_debug_width, shadowmap_debug_height, 0.0f);
            glTexCoord2d(1,1); // upper right
            glVertex3f(shadowmap_debug_width, 0.0f, 0.0f);
        glEnd();
    }
#endif

    glBindTexture(GL_TEXTURE_2D, 0);
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
}
Exemple #18
0
int Sphere_InitServer( int argc, char *argv[] )
{
	const char *m_sClassName = "Sphere";
	EXC_TRY("Init");
	ASSERT(MAX_BUFFER >= sizeof(CCommand));
	ASSERT(MAX_BUFFER >= sizeof(CEvent));
	ASSERT(sizeof(int) == sizeof(DWORD));	// make this assumption often.
	ASSERT(sizeof(ITEMID_TYPE) == sizeof(DWORD));
	ASSERT(sizeof(WORD) == 2 );
	ASSERT(sizeof(DWORD) == 4 );
	ASSERT(sizeof(NWORD) == 2 );
	ASSERT(sizeof(NDWORD) == 4 );
	ASSERT(sizeof(CUOItemTypeRec) == 37 ); // byte pack working ?
	ASSERT((std::numeric_limits<size_t>::min)() == 0); // ensure unsigned

#ifdef _WIN32
	if ( !QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&llTimeProfileFrequency)))
		llTimeProfileFrequency = 1000;

	EXC_SET("setting exception catcher");
	SetExceptionTranslator();
#endif // _WIN32

	EXC_SET("loading");
	if ( !g_Serv.Load() )
		return -3;

	if ( argc > 1 )
	{
		EXC_SET("cmdline");
		if ( !g_Serv.CommandLine(argc, argv) )
			return -1;
	}

	WritePidFile(2);

	EXC_SET("sockets init");
	if ( !g_Serv.SocketsInit() )
		return -9;
	EXC_SET("load world");
	if ( !g_World.LoadAll() )
		return -8;

	//	load auto-complete dictionary
	EXC_SET("auto-complete");
	{
		CFileText	dict;
		if ( dict.Open(GRAY_FILE ".dic", OF_READ|OF_TEXT|OF_DEFAULTMODE) )
		{
			TCHAR * pszTemp = Str_GetTemp();
			size_t count = 0;
			while ( !dict.IsEOF() )
			{
				dict.ReadString(pszTemp, SCRIPT_MAX_LINE_LEN-1);
				if ( *pszTemp )
				{
					TCHAR *c = strchr(pszTemp, '\r');
					if ( c != NULL )
						*c = '\0';

					c = strchr(pszTemp, '\n');
					if ( c != NULL )
						*c = '\0';

					if ( *pszTemp != '\0' )
					{
						count++;
						g_AutoComplete.AddTail(pszTemp);
					}
				}
			}
			g_Log.Event(LOGM_INIT, "Auto-complete dictionary loaded (contains %" FMTSIZE_T " words).\n", count);
			dict.Close();
		}
	}
	g_Serv.SetServerMode(SERVMODE_Run);	// ready to go.

	// Display EF/OF Flags
	g_Cfg.PrintEFOFFlags();

	EXC_SET("finilizing");
	g_Log.Event(LOGM_INIT, "%s", g_Serv.GetStatusString(0x24));
	g_Log.Event(LOGM_INIT, "Startup complete. items=%lu, chars=%lu\n", g_Serv.StatGet(SERV_STAT_ITEMS), g_Serv.StatGet(SERV_STAT_CHARS));

#ifdef _WIN32
	g_Log.Event(LOGM_INIT, "Press '?' for console commands\n");
#endif

	// Trigger server start
	g_Serv.r_Call("f_onserver_start", &g_Serv, NULL);
	return 0;

	EXC_CATCH;

	EXC_DEBUG_START;
	g_Log.EventDebug("cmdline argc=%d starting with %p (argv1='%s')\n", argc, static_cast<void *>(argv), ( argc > 2 ) ? argv[1] : "");
	EXC_DEBUG_END;
	return -10;
}
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;
}
//
//		오브젝트를 움직이는데 필요한 메시지를 발생
//
int		CWndWorld::ControlGround( DWORD dwMessage, CPoint point )
{
	bool	fCastCancel	= false;
	int		nMsg = 0;
	BOOL	bTempKey, bSit; // ,bCombatKey, bFlyKey

	BOOL	bUp, bDown, bLeft, bRight, bSpace, bBoard, bLForward = FALSE, bRForward = FALSE;
	BOOL	bWalk;
	static	BOOL s_bWalk2 = 0;

	CMover* pMover = CMover::GetActiveMover();

	CWndChat* pWndChat = (CWndChat*) g_WndMng.GetApplet( APP_COMMUNICATION_CHAT );
	BOOL bWhisper = g_bKeyTable['R'];
	if( pWndChat && bWhisper )
	{
		if( 0 < strlen( g_Neuz.m_szWhisperName ) )
		{
			CString strWhisper;
			strWhisper.Format( "/whisper %s ", g_Neuz.m_szWhisperName );
			pWndChat->SetFocus();
			CWndEditChat* pWndEdit = &pWndChat->m_wndEdit;
			pWndEdit->SetString( strWhisper );
			pWndEdit->SetFocus();
			g_bKeyTable['R'] = FALSE;
		}
	}
	
	// 전진/후진/스톱
	CWndBase* pWndBaseFocus = (CWndBase*) g_WndMng.GetFocusWnd();
	if( g_Neuz.m_bActiveNeuz == FALSE || ( pWndChat && pWndBaseFocus && pWndBaseFocus == pWndChat ) )
	{
		g_bKeyTable[g_Neuz.Key.chUp] = FALSE;// | m_bRButtonDown;
		g_bKeyTable[g_Neuz.Key.chLeft] = FALSE;
		g_bKeyTable['S'] = FALSE;
		g_bKeyTable['D'] = FALSE;
		g_bKeyTable['Q'] = FALSE;
		g_bKeyTable['E'] = FALSE;		
	}
	bUp	  = g_bKeyTable[g_Neuz.Key.chUp];	// | m_bRButtonDown;
	bDown = g_bKeyTable['S'];

#ifdef __BS_ADJUST_SYNC
	//gmpbigsun : 키보드 조작중에는 마우스이동 불가 
	if( bUp || bDown )
		m_bLButtonDown = FALSE;
#endif

	if( bDown )
	{
		g_WndMng.m_bAutoRun = FALSE;
	}
	if( bUp )
	{
		m_timerAutoRunPush.Reset();
		if( m_nDubleUp == 2 && m_timerAutoRun.TimeOut() == FALSE )
		{
			m_nDubleUp = 3;
			g_WndMng.m_bAutoRun = TRUE;
			m_timerAutoRun.Reset();
			m_timerAutoRunBlock.Reset();
		}
		else
		{
			m_nDubleUp = 1;
			m_timerAutoRun.Reset();
		}
		if( m_timerAutoRunBlock.TimeOut() )
			g_WndMng.m_bAutoRun = FALSE;
	}
	else
	{
		if( m_timerAutoRunPush.TimeOut() == FALSE )
		{
			if( m_nDubleUp == 1 )
				m_nDubleUp = 2;
		}
		else
		{
			m_nDubleUp = 0;
		}
	}

	if( g_WndMng.m_bAutoRun )
		bUp = TRUE;

	// 좌/우 회전
	bLeft  = g_bKeyTable[g_Neuz.Key.chLeft];
	bRight = g_bKeyTable['D'];

	bSpace	= g_bKeyTable[ VK_SPACE ];
//	bCombatKey = g_bKeyTable['C'];
//	g_bKeyTable['C'] = 0;

	bBoard = g_bKeyTable['B'];

	bSit = g_bKeyTable['V'];
	g_bKeyTable['V'] = 0;
/*		
	if( g_Option.m_nInterface == 2 )
	{
		bLForward = g_bKeyTable['Q'];
		bRForward = g_bKeyTable['E'];
		if( m_bLButtonDown )
		{
			if( bLeft )
			{
				bLeft = FALSE;
				bLForward = TRUE;
			}

			if( bRight )
			{
				bRight = FALSE;
				bRForward = TRUE;
			}
		}
	}
*/

	CWorld* pWorld = g_WorldMng.Get();
	CRect rect = GetClientRect();
	D3DXVECTOR3 vRayEnd;
	CObj* pFocusObj = pWorld->GetObjFocus();

	CActionMover *pAct = pMover->m_pActMover;
	pAct->m_dwCtrlMsg = 0;
		
	if( m_bLButtonDown )
		pAct->m_dwCtrlMsg |= CTRLMSG_LDOWN;

#if __VER >= 12 // __ITEMCREATEMON_S0602
	D3DXVECTOR3 vec3Tri[3];
	pWorld->ClientPointToVector( vec3Tri, rect, point, &pWorld->m_matProj, &g_Neuz.m_camera.m_matView, &vRayEnd, TRUE );
	g_Neuz.m_vCursorPos = vRayEnd;

	if( g_Neuz.m_pCreateMonItem )
	{
		if( bUp || bDown || bLeft || bRight || bSpace || m_bLButtonDown )
		{
			BOOL bSendCM = TRUE;
			if( m_bLButtonDown )
			{
				D3DXVECTOR3 vDist2 = g_pPlayer->GetPos() - g_Neuz.m_vCursorPos;
				float fDist = D3DXVec3Length( &vDist2 );			// 두좌표간의 거리
				if( 15.f < fDist )
				{
					g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_15 ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_15 ) );
					bSendCM = FALSE;
				}
				if( bSendCM )
				{
					int nAttr = g_pPlayer->GetWorld()->GetHeightAttribute( g_Neuz.m_vCursorPos.x, g_Neuz.m_vCursorPos.z );		// 이동할 위치의 속성 읽음.
					if( nAttr == HATTR_NOWALK || nAttr == HATTR_NOMOVE 
						|| g_pPlayer->IsRegionAttr( RA_SAFETY ) || g_pPlayer->GetWorld()->GetID() == WI_WORLD_GUILDWAR )		// 못 움직이는 곳이거나 안전지역이면 Pass
					{
						g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_AREA ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_AREA ) );
						bSendCM = FALSE;
					}
					else
					if( g_pPlayer->GetWorld()->GetID() != WI_WORLD_MADRIGAL )
					{
						g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_AREA ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_AREA ) );
						bSendCM = FALSE;
					}
					
					if( bSendCM )
					{
						g_DPlay.SendCreateMonster( MAKELONG( ITYPE_ITEM, g_Neuz.m_pCreateMonItem->m_dwObjId ), g_Neuz.m_vCursorPos );
					}
				}			
				m_bLButtonDown = FALSE;
			}
			if( bSendCM )
				g_Neuz.m_pCreateMonItem = NULL;
		}		
	}
#endif // __ITEMCREATEMON_S0602

	//TODO:ata3k님 꼭 고쳐주세요. 왜 그런지 아무도 몰라!
	// 이동금지 상태가 아닐때만 클릭으로 이동할수 있다.
#ifdef __Y_INTERFACE_VER3
	bool *bpButton;

	if( g_Option.m_nInterface == 2 )
		bpButton = &m_bLButtonUp;
	else
		bpButton = &m_bLButtonDown;
	
	if( *bpButton )	
#else //__Y_INTERFACE_VER3
	if( m_bLButtonDown )				
#endif //__Y_INTERFACE_VER3
	{
	#ifdef __Y_INTERFACE_VER3	
		if( g_Option.m_nInterface == 2 )
		{
			*bpButton = FALSE;

			if( m_timerLButtonDown.GetLeftTime() > 200 )
				return nMsg;		
		}
	#endif //__Y_INTERFACE_VER3

		D3DXVECTOR3 vec3Tri[3];
		if( pWorld->ClientPointToVector( vec3Tri, rect, point, &pWorld->m_matProj, &g_Neuz.m_camera.m_matView, &vRayEnd, TRUE ) ) 
		{
			// 이동 포인트를 얻어 목표 세팅 
			if( m_bFreeMove )
			{
	//			if( m_bLButtonDown )	// 이동금지 상태가 아닐때만 클릭으로 이동할수 있다.
				{
					{
						if( m_pWndGuideSystem  && m_pWndGuideSystem->IsVisible())
						#if __VER >= 12 // __MOD_TUTORIAL
							m_pWndGuideSystem->m_Condition.bIsClickOnLand = true;
						#else
							m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_MOVE);
						#endif
	#ifdef __IAOBJ0622					
						if( GetLastPickObj() && GetLastPickObj()->GetType() == OT_SHIP )
							pMover->SetDestPos( (CShip *)GetLastPickObj(), vRayEnd );
						else
							pMover->SetDestPos( vRayEnd );
	#else
						pMover->SetDestPos( vRayEnd );
	#endif
						pMover->m_nCorr		= -1;
	#ifndef __J0823
						m_bFreeMove		= FALSE;

						g_DPlay.SendSnapshot( TRUE );
						fCastCancel	= true;

						if( g_pMoveMark && g_pMoveMark->m_pSfxObj )
							g_pMoveMark->m_pSfxObj->m_nCurFrame		= 180;
						CSfx *pObj = CreateSfx(g_Neuz.m_pd3dDevice,XI_GEN_MOVEMARK01,vRayEnd);
						
						
						D3DXVECTOR3 vVector1 = vec3Tri[2] - vec3Tri[0];
						D3DXVECTOR3 vVector2 = vec3Tri[1] - vec3Tri[0];
						D3DXVECTOR3 vNormal;
						D3DXVec3Cross( &vNormal, &vVector1, &vVector2);	
						D3DXVec3Normalize( &vNormal, &vNormal );
						
						D3DXVECTOR3 v3Up = D3DXVECTOR3( 0.0f, -1.0f, 0.0f );
						D3DXVECTOR3 v3Cross;
						FLOAT fDot;
						FLOAT fTheta;
						D3DXVec3Cross( &v3Cross, &v3Up, &vNormal );
						fDot = D3DXVec3Dot( &v3Up, &vNormal );
						fTheta = acos( fDot );
						
						D3DXQUATERNION qDirMap;
						D3DXQuaternionRotationAxis( &qDirMap, &v3Cross, fTheta );
						
						D3DXVECTOR3 vYPW;
						QuaternionRotationToYPW( qDirMap, vYPW );
						
						pObj->m_pSfxObj->m_vRotate.x = D3DXToDegree(vYPW.x);
						pObj->m_pSfxObj->m_vRotate.y = D3DXToDegree(vYPW.y);
						pObj->m_pSfxObj->m_vRotate.z = D3DXToDegree(vYPW.z);
						
	#endif	// __J0823
						m_objidTracking		= NULL_ID;
					}
				}
			}
		}
	}
	
	//if( !pMover->IsEmptyDestPos() || !pMover->IsEmptyDestObj() )
	//	return nMsg;
#ifdef __Y_INTERFACE_VER3
	if( bUp || bDown || bLeft || bRight || bSpace || bLForward || bRForward )	// 이동 키조작이 들어가면 자동공격 멈춤.
#else //__Y_INTERFACE_VER3	
	if( bUp || bDown || bLeft || bRight || bSpace )	// 이동 키조작이 들어가면 자동공격 멈춤.
#endif //__Y_INTERFACE_VER3
	{

		if( bUp || bDown )
	#if __VER >= 12 // __MOD_TUTORIAL
		{
			CWndGuideSystem* pWndGuide = NULL;
			pWndGuide = (CWndGuideSystem*)GetWndBase( APP_GUIDE );
			if(pWndGuide && pWndGuide->IsVisible()) pWndGuide->m_Condition.bIsKeyMove = true;
		}
	#else
			m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_MOVE);
	#endif
		m_bAutoAttack = FALSE;
		g_pPlayer->ClearCmd();
		if( !bSpace )
			m_objidTracking		= NULL_ID;
	}


	if( m_objidTracking != NULL_ID )
	{
		CMover* pObjTracking	= prj.GetMover( m_objidTracking );
		if( pObjTracking )
		{
			D3DXVECTOR3 vDis	= pMover->GetPos() - pObjTracking->GetPos();
			if( D3DXVec3LengthSq( &vDis ) > 16 )
				pMover->SetDestObj( m_objidTracking );
		}
		else
			m_objidTracking		= NULL_ID;
	}

	bool fMoved	= false;
	bool fBehavior	= false;
	
	if( bUp ) {
		if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) {
			fMoved	= true;
			fCastCancel	= true;
		}
	}
	else if( bDown ) {
		if( pMover->SendActMsg( OBJMSG_BACKWARD ) == 1 ) {
			fMoved	= true;
			fCastCancel	= true;
		}
	}
#ifdef __Y_INTERFACE_VER3
	else
	if( bLForward ) {
		if( pMover->SendActMsg( OBJMSG_LFORWARD ) == 1 ) {
			fMoved	= true;
			fCastCancel	= true;
		}
	}
	else if( bRForward ) {
		if( pMover->SendActMsg( OBJMSG_RFORWARD ) == 1 ) {
			fMoved	= true;
			fCastCancel	= true;
		}
	}	
#endif //__Y_INTERFACE_VER3
	else 
//	if( (bUp == FALSE && s_bUped == TRUE) || (bDown == FALSE && s_bDowned == TRUE) )	// 키를 뗀 순간에만 처리해보자..
	if( bUp == FALSE || bDown == FALSE )
	{
		if( pMover->IsEmptyDest() ) 
		{
			if( pMover->m_pActMover->IsActJump() == FALSE && (pMover->m_pActMover->IsStateFlag( OBJSTAF_SIT ) ) == 0 )	// 앉아있을땐 실행하면 안된다.
			{
				if( pMover->SendActMsg( OBJMSG_STAND ) == 1 )
				{
					fMoved	= true;
//					TRACE( "PlayerMoved, " );
				}
			}
		}
	}
//		s_bUped = bUp;
//		s_bDowned = bDown;

	if( bLeft ) {
		if( pMover->SendActMsg( OBJMSG_LTURN ) == 1 ) {
			fMoved	= true;
		}
	}
	else if( bRight ) {
		if( pMover->SendActMsg( OBJMSG_RTURN ) == 1 ) {
			fMoved	= true;
		}
	}
	else {
		if( pMover->SendActMsg( OBJMSG_STOP_TURN ) == 1 ) {
			fMoved	= true;
//			fBehavior	= true;
		}
	}


//	jump
	if( bSpace ) 
	{
	#if __VER < 12 // __MOD_TUTORIAL
		if( m_pWndGuideSystem )
			m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_JUMP);
	#endif
		if( pMover->SendActMsg( OBJMSG_JUMP ) == 1 ) 
		{
			fBehavior	= true;
			fCastCancel	= true;
		}
	}
	if( m_bLButtonDown == TRUE && m_bRButtonDown == TRUE ) {
		if( m_timerLButtonDown.GetLeftTime() < 500 && m_timerRButtonDown.GetLeftTime() < 500 ) {
			if( g_pPlayer->SendActMsg( OBJMSG_JUMP ) == 1 ) {
				fBehavior	= true;
				fCastCancel	= true;
			}
		}
	}
#ifdef __Y_INTERFACE_VER3	
	if( g_Option.m_nInterface == 2 )
	{
		if( g_bKeyTable[VK_DIVIDE] || g_bKeyTable[191] )
		{
			bWalk = TRUE;		
		}
		else
		{
			bWalk = FALSE;			
		}	
	}
	else
	{
		bWalk = g_bKeyTable[g_Neuz.Key.chWalk];	
	}
#else //__Y_INTERFACE_VER3	
	bWalk = g_bKeyTable[g_Neuz.Key.chWalk];	
#endif //__Y_INTERFACE_VER3	
	if( bWalk && !s_bWalk2 )		// 걷기 모드 토글.
	{
		if( pMover->m_pActMover->IsStateFlag( OBJSTAF_WALK ) )
		{
			if( pMover->SendActMsg( OBJMSG_MODE_RUN ) == 1 ) {
				g_WndMng.PutString( prj.GetText( TID_GAME_RUN ), NULL, prj.GetTextColor( TID_GAME_RUN ) , CHATSTY_SYSTEM_CLIENT );
				fBehavior	= true;
			}
		} else
		{
		#if __VER < 12 // __MOD_TUTORIAL
			if(m_pWndGuideSystem)
				m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_RUN);
		#endif
			if( pMover->SendActMsg( OBJMSG_MODE_WALK ) == 1 ) {
				g_WndMng.PutString( prj.GetText( TID_GAME_WALK ), NULL, prj.GetTextColor( TID_GAME_WALK ) , CHATSTY_SYSTEM_CLIENT );		
				fBehavior	= true;
			}
		}
	}
	s_bWalk2 = bWalk;

	if( fMoved || fBehavior ) 
	{
		g_pPlayer->ClearDest();
 #ifdef __J0823
		g_DPlay.ClearPlayerDestPos();
 #endif	// __J0823
	}

	if( fMoved )
		g_DPlay.SendPlayerMoved();
	if( fBehavior )
		g_DPlay.SendPlayerBehavior();
	if( g_pPlayer->IsStateMode( STATE_BASEMOTION_MODE ) && fCastCancel ) // 캐스트 취소
	{
		g_DPlay.SendStateModeCancel( STATE_BASEMOTION_MODE, STATEMODE_BASEMOTION_CANCEL );
	}


	// 운영자가 쓰는 키. 서버로부터 좌표받아오기.
	if( bTempKey = g_bKeyTable[ '8' ] )
	{
		if( !m_bTemp3ed )
		{
			pMover->SendActMsg( OBJMSG_TEMP2 );
//			__bTestLOD ^= 1;
		}
	}
	m_bTemp3ed	= bTempKey;

//----------- 스킬사용.
/*	
	static BOOL s_bShift2, s_bKeyC2;
	BOOL bShift, bKeyC;

	if( g_Option.m_nInterface == 1 )		// 신버전 인터페이스 방식은 X 가 스킬사용이다.
	{
		bShift = g_bKeyTable[ VK_SHIFT ];
		bKeyC  = g_bKeyTable[ 'C' ];
		if( bKeyC )
		{
			int a = 0;
		}
			
		if( (bShift && !s_bShift2) || (bKeyC && !s_bKeyC2) )	
		{
			CObj* pTargetObj = CObj::m_pObjHighlight;		// 커서를 대고 있던 오브젝트가 하이라이트 오브젝이다.
			if( pTargetObj )	// 커서를 대고 있던 오브젝트가 있으면
			{
				pWorld->SetObjFocus( pTargetObj );	// 그놈을 셀렉트 하는 동시에.
				
				CMover* pMover = (CMover*)pTargetObj;
				if( pMover->GetType() == OT_MOVER )
					m_dwNextSkill = NEXTSKILL_ACTIONSLOT;	// 스킬 사용 예약.
			} else
				m_dwNextSkill = NEXTSKILL_ACTIONSLOT;	// 스킬 사용 예약.
		}
		s_bShift2 = bShift;
		s_bKeyC2 = bKeyC;
	}
*/	
//------------ 비공정 타기
	if( bBoard )
	{
		if( !s_bBoarded )		// 플레이어가 비공정에 올라타있는 상태에서. 탑승키를 누르면.
		{
			if( g_pShip == NULL )
			{
				if( g_pPlayer->GetIAObjLink() && g_pPlayer->GetIAObjLink()->GetType() == OT_SHIP && g_pPlayer->GetIAObjLink()->GetIndex() == 3 )
				{
					CShip *pShip = (CShip *)g_pPlayer->GetIAObjLink();
					if( pShip->GetMover() == NULL )		// 쥔장이 없는 배일때.
					{
						pShip->SetMover( g_pPlayer );	// 쥔장을 g_pPlayer로 설정.
						g_pShip = pShip;
							
					}
				}
			} else
			// 이미 배를 조종하고 있을때
			{
				g_pShip->SetMover( NULL );
				g_pShip = NULL;
			}
		}
	}
	s_bBoarded = bBoard;

	
#ifdef _DEBUG
	// 디버깅용 키
	if( bTempKey = g_bKeyTable[ VK_F2 ] )
	{
		if( !s_bTempKeyed )
		{
//			pMover->SendActMsg( OBJMSG_TEMP );
//			g_Option.m_nObjectDetail ++;
//			if( g_Option.m_nObjectDetail > 2 )	g_Option.m_nObjectDetail = 0;
		}
	}
	s_bTempKeyed = bTempKey;
	if( bTempKey = g_bKeyTable[ 'F' ] )
	{
		if( !m_bTemp2ed )
		{
			pMover->SendActMsg( OBJMSG_TEMP3 );
		}
	}
	m_bTemp2ed = bTempKey;
#endif
	
	return nMsg;
}
void CActionMover::PresupposePos2( D3DXVECTOR3* pv, D3DXVECTOR3* pvd, float* pf, float* pfAngleX, float* pfAccPower, u_long uTickCount )
{
	CMover* pMover	= GetMover();
	D3DXVECTOR3 v	= pMover->GetPos();
	float fAngle	= pMover->GetAngle();
	D3DXVECTOR3 vDelta	= m_vDelta;
	
	if( prj.GetItemProp( pMover->m_dwRideItemIdx ) == NULL )
		return;

	float fAcc = prj.GetItemProp( pMover->m_dwRideItemIdx )->fFlightSpeed;	// 무버가 타고있는 아이템의 인덱스에서 추진력을 꺼내옴.

	fAcc	*= 0.75f;
	float fTheta, fThetaX, d;

	DWORD dwMoveState	= GetMoveState();
	DWORD dwTurnState	= GetTurnState();
	DWORD dwLookState	= GetLookState();

	float fX = pMover->GetAngleX();
	float fAccPower	= m_fAccPower;
	float fTurnAngle;
	
	D3DXVECTOR3	vAcc;
	for( u_long i = 0; i < uTickCount; i++ )
	{
		fTheta	= D3DXToRadian( fAngle );
		switch( dwMoveState )
		{
			case OBJSTA_STAND:
				fAccPower	= 0;
				break;
			case OBJSTA_FMOVE:
				fAccPower	= fAcc;
				break;
		}
		switch( dwTurnState )
		{
			case OBJSTA_LTURN:
				fTurnAngle	= m_fTurnAngle;
				if( ( GetStateFlag() & OBJSTAF_ACC ) == 0 )
					fTurnAngle *= 2.5f;
				fAngle	+= fTurnAngle;
				if( fAngle > 360.0f )
					fAngle -= 360.0f;
				break;
			case OBJSTA_RTURN:
				fTurnAngle	= m_fTurnAngle;
				if( ( GetStateFlag() & OBJSTAF_ACC ) == 0 )
					fTurnAngle *= 2.5f;
				fAngle	-= fTurnAngle;
				if( fAngle < 0.0f )
					fAngle	+= 360.0f;
				break;
		}
		switch( dwLookState )
		{
			case OBJSTA_LOOKUP:
				if( fX > -45.0f )	fX	-= 1.0f;
				break;
			case OBJSTA_LOOKDOWN:
				if( fX < 45.0f )	fX	+= 1.0f;
				break;
		}

		fThetaX	= D3DXToRadian( fX );
		if( GetStateFlag() & OBJSTAF_TURBO )
			fAccPower	*= 1.5f;
		d	= cosf( fThetaX ) * fAccPower;
		fTheta	= D3DXToRadian( fAngle );
		
		vAcc.x	= sinf( fTheta ) * d;
		vAcc.z	= -cosf( fTheta ) * d;
		vAcc.y	= -sinf( fThetaX ) * fAccPower;

		float fLenSq	= D3DXVec3LengthSq( &vDelta );
		D3DXVECTOR3 vDeltaNorm, vAccNorm;
		D3DXVec3Normalize( &vDeltaNorm, &vDelta );
		D3DXVec3Normalize( &vAccNorm, &vAcc );
		float fDot	= D3DXVec3Dot( &vDeltaNorm, &vAccNorm );
		if( fAccPower > 0.0f )
		{
			if( fLenSq > 0.01f )
			{
				if( fDot < cosf( 70.0f ) )
				{
					vAcc	*= 2.0f;
					vDelta	*= 0.985f;
				}
			}
		}
		fLenSq	= D3DXVec3Length( &vDelta );
		if( fLenSq < 0.3f )
		{
			vDelta	+= vAcc;
		}
		vDelta	*= ( 1.0f - FRIC_AIR );
		v	+= vDelta;
		if( v.y > MAX_MOVE_HEIGHT )
			v.y	= MAX_MOVE_HEIGHT;

		CWorld* pWorld = GetWorld();
		pWorld->ClipX( v.x );
		pWorld->ClipZ( v.z );
	}

	*pv	        = v;
	*pf	        = fAngle;
	*pvd	    = vDelta;
	*pfAngleX	= fX;
	*pfAccPower	= fAccPower;

	pMover->m_nCorr = (int)uTickCount;
}