// Description:
//
// Arguments:
//
// Return:
//
void CVisualLog::WriteFrameHeaders( int iFrameNum, const char *sImageName )
{
	// Frame header example:  Frame 0 [Frame000000.jpg] [34.527]
	CTimeValue time = gEnv->pTimer->GetFrameStartTime();

	fprintf( m_fLogFile, "Frame %d [%s] [%0.3f]\n", iFrameNum, sImageName, time.GetSeconds() );  
	fprintf( m_fLogParamsFile, "Frame %d [%s] [%0.3f]\n", iFrameNum, sImageName, time.GetSeconds() );
}
Example #2
0
void
CTimer::Update()
{
    char *p0;
    struct tm *tm;
    time_t mlSec;
    uint32_t muMSec;
    CTimeValue *tp;
    struct timeval tv;
    struct timezone tz;


    if ( !MINA_TRYLOCK(&this->muLock) )
    {
        return;
    }

    gettimeofday(&tv, &tz);

    mlSec = tv.tv_sec;
    muMSec = tv.tv_usec / TIME_MSEC;

    this->moTime.Set(mlSec * TIME_SEC + tv.tv_usec * TIME_USEC, TIME_NSEC);

    tp = &this->moCacheTimes[muSlot];

    if (tp->Sec() == mlSec)
    {
        tp->Msec(muMSec);
        MINA_UNLOCK(&this->muLock);
        return;
    }

    if (muSlot == TIME_SLOTS - 1)
    {
        muSlot = 0;
    }
    else
    {
        muSlot++;
    }

    tp = &this->moCacheTimes[muSlot];
    tp->Sec(mlSec);
    tp->Msec(muMSec);

    p0 = &maacFormatTimes[muSlot][0];

    tm = gmtime(&mlSec);
    strftime(p0, FORM_TIME_LEN, "%Y-%m-%d %H:%M:%S", tm);

    this->mpoCacheTime = tp;
    this->mpcFormatTime = p0;

    MINA_UNLOCK(&this->muLock);


}
Example #3
0
CTimeValue CTimeValue::operator-(const CTimeValue& rstTime)
{
    timeval stTimeValResult;

    CTimeUtility::TimeValMinus(m_stTimeval, rstTime.m_stTimeval, stTimeValResult);
    CTimeValue stTimeManager;
    stTimeManager.SetTimeValue(stTimeValResult);

    return stTimeManager;
}
Example #4
0
void CNetworkStallTickerThread::Run()
{
	bool gotLockLastTime=true;

#if WARN_ABOUT_LONG_STALLS_IN_TICKER
	CTimeValue started=gEnv->pTimer->GetAsyncTime();
	CTimeValue ended;
#endif
	SetName("NetworkStallTicker");

	while (m_threadRunning)
	{
		if (gEnv->pNetwork)
		{
			gEnv->pNetwork->SyncWithGame(eNGS_SleepNetwork);
		}

		if (gotLockLastTime)
		{
			CrySleep(33);
		}
		else
		{
			CrySleep(1);
		}

		{
			if (gEnv->pNetwork)
			{
				SCOPED_TICKER_TRY_LOCK;
				if (SCOPED_TICKER_HAS_LOCK)
				{
					gEnv->pNetwork->SyncWithGame(eNGS_MinimalUpdateForLoading);
					gotLockLastTime=true;
				}
				else
				{
					gotLockLastTime=false;
				}
				gEnv->pNetwork->SyncWithGame(eNGS_WakeNetwork);
			}

#if WARN_ABOUT_LONG_STALLS_IN_TICKER
			ended = gEnv->pTimer->GetAsyncTime();
			if (ended.GetDifferenceInSeconds(started)>1.f)
			{
				CryLogAlways("THREADEDLOADING:: No update for %f",ended.GetDifferenceInSeconds(started));
			}
			started=ended;
#endif
		}
	}

	Stop();
}
Example #5
0
	CUnitTest::~CUnitTest(void)
	{
		TRACE(TRACE_ENABLE);

		CTimeValue elapsed = m_timeEnded-m_timeStarted;
		
		int32 days, hours, minutes;
		float seconds;
		elapsed.GetTime(days, hours, minutes, seconds);

		const char* errorColour = (m_errorTotal != 0) ? COLOUR_ERROR : COLOUR_DEFAULT;
		LOG_ALWAYS(m_log, COLOUR_TEST_INFO "[%s] " COLOUR_DEFAULT "%d tests completed in %s%d days, %02u:%02u:%06.3fs; " COLOUR_DEFAULT "%s%d errors\n\n" COLOUR_RESET, m_name, m_totalTests, (elapsed.GetTicks() < 0) ? "-" : "",  days, hours, minutes, seconds, errorColour, m_errorTotal);
	}
    virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
    {
        switch (event)
        {
        case eFE_Initialize:
        {
            pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
        }
        break;

        case eFE_Update:
        {
            float fPeriod = GetPortFloat(pActInfo,IN_PERIOD);
            CTimeValue time = gEnv->pTimer->GetFrameStartTime();
            CTimeValue dt = time - m_lastTickTime;
            if (dt.GetSeconds() >= fPeriod)
            {
                m_lastTickTime = time;
                ++m_count;
                ActivateOutput( pActInfo, OUT_COUNT, m_count );
                if (m_count >= GetPortInt( pActInfo, IN_LIMIT ))
                {
                    pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
                    ActivateOutput( pActInfo, OUT_FINISHED, GetPortAny( pActInfo, IN_START ));
                }
            }
        }
        break;
        case eFE_Activate:
        {
            if (IsPortActive(pActInfo,IN_START))
            {
                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
                m_count = 0;
                m_lastTickTime = gEnv->pTimer->GetFrameStartTime();
            }

            if (IsPortActive(pActInfo,IN_STOP))
            {
                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
            }

            if (IsPortActive(pActInfo,IN_CONTINUE))
            {
                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
            }
        }
        break;
        }
    }
Example #7
0
//------------------------------------------------------------------------
void CFireModePlugin_Overheat::Activate(bool activate)
{
	CWeapon* pWeapon = m_pOwnerFiremode->GetWeapon();
		
	CRY_ASSERT(pWeapon);

	if(activate)
	{
		m_heat = 0.f;
		m_overheat = 0.f;

		if(m_nextHeatTime > 0.0f)
		{
			CTimeValue time = gEnv->pTimer->GetFrameStartTime();
			float dt = m_nextHeatTime - time.GetSeconds();
			if(dt > 0.0f)
			{
				m_heat = min(dt,1.0f);
			}
			if(dt > 1.0f)
			{
				m_overheat = dt - 1.0f;
			}
			m_nextHeatTime = 0.0f;
		}
	}
	else
	{
		if(m_heatEffectId)
		{
			pWeapon->DetachEffect(m_heatEffectId);
			m_heatEffectId = 0;
		}

		m_nextHeatTime = 0.0f;
		if(m_heat>0.0f)
		{
			CTimeValue time = gEnv->pTimer->GetFrameStartTime();
			m_nextHeatTime = time.GetSeconds() + m_heat + m_overheat;
		}

		m_heat = 0.f;
		m_overheat = 0.f;
	}

	m_firedThisFrame = false;
}
    virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
    {
        switch (event)
        {
        case eFE_Initialize:
        {
            bool bPaused = GetPortBool(pActInfo,IN_PAUSED);
            pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, !bPaused );
            m_last = gEnv->pTimer->GetFrameStartTime();
        }
        break;

        case eFE_Update:
        {
            if (GetPortBool(pActInfo,IN_PAUSED))
                return;

            float fPeriod = GetPortFloat(pActInfo,IN_PERIOD);
            CTimeValue time = gEnv->pTimer->GetFrameStartTime();
            CTimeValue dt = time - m_last;
            if (dt.GetSeconds() >= fPeriod)
            {
                m_last = time;
                int nMin = GetPortInt(pActInfo,IN_MIN);
                int nMax = GetPortInt(pActInfo,IN_MAX);
                m_nCurrentCount++;
                if (m_nCurrentCount < nMin)
                    m_nCurrentCount = nMin;
                if (m_nCurrentCount > nMax)
                {
                    m_nCurrentCount = nMin;
                }
                ActivateOutput( pActInfo,OUT_OUT,m_nCurrentCount );
            }
        }
        break;
        case eFE_Activate:
        {
            if (IsPortActive(pActInfo,IN_PAUSED))
            {
                bool bPaused = GetPortBool(pActInfo,IN_PAUSED);
                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, !bPaused );
            }
        }
        break;
        }
    }
NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE( CGameServerChannel, SyncTimeServer, eNRT_ReliableOrdered, eMPF_NoSendDelay )
{
	CTimeValue value = gEnv->pTimer->GetAsyncTime();
	INetSendablePtr msg = new CSimpleNetMessage<SSyncTimeClient>(SSyncTimeClient(param.id, param.clientTime, param.serverTime, value.GetValue()), CGameClientChannel::SyncTimeClient);
	GetNetChannel()->AddSendable(msg, 0, NULL, NULL);
	  
	return true;
}
Example #10
0
//////////////////////////////////////////////////////////////////////////
// Create a new timer and put it in the list of managed timers.
int	CScriptTimerMgr::AddTimer( ScriptTimer &timer )
{
	CTimeValue nCurrTimeMillis = gEnv->pTimer->GetFrameStartTime();
	timer.nStartTime = nCurrTimeMillis.GetMilliSecondsAsInt64();
	timer.nEndTime = timer.nStartTime + timer.nMillis;
	if (!timer.nTimerID)
	{
		m_nLastTimerID++;
		timer.nTimerID = m_nLastTimerID;
	}
	else
	{
		if (timer.nTimerID > m_nLastTimerID)
			m_nLastTimerID = timer.nTimerID+1;
	}
	m_mapTempTimers[timer.nTimerID] = new ScriptTimer(timer);
	return timer.nTimerID;
}
Example #11
0
	void ProcessEvent(EFlowEvent event, SActivationInfo* pActivationInfo)
	{
		switch (event)
		{
		case eFE_Initialize:
		{
			SetAutoUpdate(pActivationInfo, GetPortBool(pActivationInfo, eIP_Auto));

			break;
		}

		case eFE_Activate:
		{
			if (IsPortActive(pActivationInfo, eIP_Auto))
			{
				SetAutoUpdate(pActivationInfo, GetPortBool(pActivationInfo, eIP_Auto));
			}
			else if (IsPortActive(pActivationInfo, eIP_Freq))
			{
				m_frequency = GetPortFloat(pActivationInfo, eIP_Freq);
			}
			else if (IsPortActive(pActivationInfo, eIP_Sync))
			{
				Sync(pActivationInfo);
			}

			break;
		}

		case eFE_Update:
		{
			CTimeValue delta = gEnv->pTimer->GetFrameStartTime() - m_prevTime;

			if (delta.GetSeconds() >= m_frequency)
			{
				Sync(pActivationInfo);
			}

			break;
		}
		}
	}
 virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
 {
     switch (event)
     {
     case eFE_Activate:
         if (IsPortActive(pActInfo, EIP_Start))
         {
             m_last = gEnv->pTimer->GetFrameStartTime();
             ActivateOutput(pActInfo, EOP_Started, true);
         }
         if (IsPortActive(pActInfo, EIP_Stop))
         {
             CTimeValue dt = gEnv->pTimer->GetFrameStartTime();
             dt-=m_last;
             m_last = 0.0f;
             ActivateOutput(pActInfo, EOP_Stopped, true);
             ActivateOutput(pActInfo, EOP_Time, dt.GetSeconds());
         }
         break;
     }
 }
Example #13
0
void CLagOMeter::OnClientReceivedKill(const CActor::KillParams &killParams)
{
	CTimeValue currentTime = gEnv->pTimer->GetAsyncTime();
	if (killParams.shooterId == g_pGame->GetClientActorId())
	{
		// Try to find the corresponding request hit info to see how far lagged behind we are
		int index = killParams.lagOMeterHitId;
		if (index > 0 && index < HIT_HISTORY_COUNT)
		{
			SHitRequestHistory& item = m_hitHistory[index];
			if (item.requestTime.GetValue() != 0)
			{
				CTimeValue diff = currentTime - item.requestTime;
				CTelemetryCollector* pTelemetryCollector = (CTelemetryCollector*)g_pGame->GetITelemetryCollector();
				if (pTelemetryCollector)
				{
					pTelemetryCollector->LogEvent("Kill Latency", diff.GetMilliSeconds());
				}
			}
		}
	}
}
Example #14
0
void CDownloadMgr::WaitForDownloadsToFinish(const char** resources, int numResources, float timeout)
{
	CDownloadableResourcePtr* pResources=new CDownloadableResourcePtr[numResources];
	for (int i=0; i<numResources; ++i)
	{
		CDownloadableResourcePtr pRes = FindResourceByName(resources[i]);
		if (pRes)
		{
			pRes->StartDownloading();
		}
		pResources[i] = pRes;
	}
	CTimeValue startTime = gEnv->pTimer->GetAsyncTime();
	while (true)
	{
		bool allFinished = true;
		for (int i=0; i<numResources; ++i)
		{
			CDownloadableResourcePtr pRes = pResources[i];
			if (pRes)
			{
				CDownloadableResource::TState state = pRes->GetState();
				if (state & CDownloadableResource::k_callbackInProgressMask)
				{
					allFinished = false;
					break;
				}
			}
		}
		CTimeValue currentTime = gEnv->pTimer->GetAsyncTime();
		if (allFinished || currentTime.GetDifferenceInSeconds(startTime) > timeout)
		{
			break;
		}
		CrySleep(100);
	};
	delete [] pResources;
	DispatchCallbacks();
}
Example #15
0
void CAntiCheatManager::OnSessionEnd()
{
	DumpPlayerRecords();
	DumpCheatRecords();
	DecayCheatRecords();
	
	CloseLogFile();
	BackupLogFileAndSubmit();	

	CTimeValue currentTime = gEnv->pTimer->GetAsyncTime();
	float deltaSeconds = currentTime.GetDifferenceInSeconds(m_lastDownloadTime);
	if (deltaSeconds > g_pGameCVars->g_dataRefreshFrequency * 3600)
	{
		CDownloadableResourcePtr res = GetDownloadableResource();
		if (res)
		{
			// Clear the downloaded data and start download again
			res->Purge();
			res->StartDownloading();
		}
		m_lastDownloadTime = currentTime;
	}
}
void CGameQueryListener::CleanUpServers()
{
	if(m_servers.size() == 0)
		return;

	CTimeValue now = gEnv->pTimer->GetFrameStartTime();

	std::vector<SGameServer>::iterator it;
	//kill old servers
	for(int i = 0; i < m_servers.size(); ++i)
	{
		uint32 seconds = (uint32)(now.GetSeconds() - m_servers[i].m_lastTime.GetSeconds());
		if(!seconds)
			continue;
		if(seconds > 10)
		{
			it = m_servers.begin();
			for(int inc = 0; inc < i; ++inc)
				++it;
			m_servers.erase(it);
			--i;
		}
	}
}
Example #17
0
void CallbackTimer::Update()
{
	if (!m_timeouts.empty())
	{
		if (m_resort)
		{
			std::sort(m_timeouts.begin(), m_timeouts.end());
			m_resort = false;
		}

		CTimeValue now = gEnv->pTimer->GetFrameStartTime();

		while (!m_timeouts.empty() && (m_timeouts.front().timeout <= now))
		{
			TimeoutInfo timeout = m_timeouts.front();
			m_timeouts.pop_front();

			TimerInfo timer = m_timers[timeout.timerID];

			timer.callback(timer.userdata, timeout.timerID);

			if (m_timers.validate(timeout.timerID))
			{
				if (!timer.repeating)
					m_timers.erase(timeout.timerID);
				else
				{
					CTimeValue nextTimeout = timeout.timeout + timer.interval;
					if (nextTimeout.GetValue() <= now.GetValue())
						nextTimeout.SetValue(now.GetValue() + 1);

					timeout.timeout = nextTimeout;
					m_timeouts.push_back(timeout);
					m_resort = true;
				}
			}
		}
	}
}
Example #18
0
void CFlowDelayNode::ProcessEvent( EFlowEvent event, SActivationInfo * pActInfo )
{
	switch (event)
	{
	case eFE_Initialize:
		RemovePendingTimers();
		pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
		break;

	case eFE_Activate:
		// we request a final activation if the input value changed
		// thus in case we get several inputs in ONE frame, we always only use the LAST one!
		if (IsPortActive(pActInfo, INP_IN))
		{
			pActInfo->pGraph->RequestFinalActivation(pActInfo->myID);
		}
		break;

	case eFE_FinalActivate:
	{
		bool shouldReset = GetShouldReset( pActInfo );

		if (gEnv->IsEditor())
		{
			if (shouldReset)
				m_activations.clear();
			const float delay = GetDelayTime(pActInfo);
			CTimeValue finishTime = gEnv->pTimer->GetFrameStartTime() + delay;
			m_activations[(int)finishTime.GetMilliSeconds()] = SDelayData(finishTime, pActInfo->pInputPorts[0]);
			pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
		}
		else
		{
			if (shouldReset)
			{
				for (Activations::iterator iter = m_activations.begin(); iter != m_activations.end(); ++iter) 
				{
					IGameFramework::TimerID timerId = (*iter).first;
					CCryAction::GetCryAction()->RemoveTimer( timerId );
				}
				m_activations.clear();
			}

			const float delay = GetDelayTime(pActInfo);
			CTimeValue finishTime = gEnv->pTimer->GetFrameStartTime() + delay;
			IGameFramework::TimerID timerId = CCryAction::GetCryAction()->AddTimer( delay, false, functor(CFlowDelayNode::OnTimer),
				this );
			m_activations[timerId] = SDelayData(finishTime, pActInfo->pInputPorts[0]);
		}
		break;
	}

	case eFE_Update:
		CRY_ASSERT( gEnv->IsEditor() );
		CRY_ASSERT( !m_activations.empty() );
		CTimeValue curTime = gEnv->pTimer->GetFrameStartTime();

		while (!m_activations.empty() && m_activations.begin()->second.m_timeout < curTime)
		{
			ActivateOutput( pActInfo, 0, m_activations.begin()->second.m_data );
			m_activations.erase( m_activations.begin() );
		}
		if (m_activations.empty())
			pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
		break;
	}
}
//------------------------------------------------------------------------
void CGameRulesHoldObjectiveBase::AddEntityId(int type, EntityId entityId, int index, bool isNewEntity, const CTimeValue &timeAdded)
{
	if(index >= HOLD_OBJECTIVE_MAX_ENTITIES)
	{
		CryFatalError("Too Many Hold Objective Entities Active!");
	}
	CryLog("CGameRulesHoldObjectiveBase::AddEntityId() received objective, eid=%i, index=%i, isNewEntity=%s, fTimeAdded=%lld, adding to pending queue", entityId, index, isNewEntity ? "true" : "false", timeAdded.GetMilliSecondsAsInt64());

	SHoldEntityDetails *pDetails = &m_entities[index];
	if (pDetails->m_id)
	{
		// We're overwriting another entity, disable the old one
		CleanUpEntity(pDetails);
	}
	// Can't actually activate the entity here since the entity may not be fully initialised yet (horrible ordering issue on game restart),
	// instead set it as pending and do the actual add in the ::Update(...) method
	pDetails->m_pendingId = entityId;
	pDetails->m_isNewEntity = isNewEntity;
	m_pendingTimeAdded = timeAdded;
}
Example #20
0
void CFlowDelayNode::Serialize(SActivationInfo *pActInfo, TSerialize ser)
{
	CTimeValue curTime = gEnv->pTimer->GetFrameStartTime();

	ser.BeginGroup("Local");
	// Editor mode: map with
	// key:  abs time in ms
	// data: SDelayData
	//
	// Game mode: map with
	// key:  timer id (we don't care about it)
	// data: SDelayData
	if (ser.IsWriting()) {
		// when writing, currently relative values are stored!
		ser.Value("m_activations", m_activations);
#if 0
		CryLogAlways("CDelayNode write: current time(ms): %f", curTime.GetMilliSeconds());		
		Activations::iterator iter = m_activations.begin();
		while (iter != m_activations.end()) 
		{
			CryLogAlways("CDelayNode write: ms=%d  timevalue(ms): %f",(*iter).first, (*iter).second.m_timeout.GetMilliSeconds());
			++iter;
		}
#endif
	}
	else
	{
		// FIXME: should we read the curTime from the file
		//        or is the FrameStartTime already set to the serialized value?
		// ser.Value("curTime", curTime);

		// when reading we have to differentiate between Editor and Game Mode
		if (gEnv->IsEditor()) {
			// we can directly read into the m_activations array
			// regular update is handled by CFlowGraph
			ser.Value("m_activations", m_activations);
			Activations::iterator iter = m_activations.begin();
#if 0
			CryLogAlways("CDelayNode read: current time(ms): %f", curTime.GetMilliSeconds());		
			while (iter != m_activations.end()) 
			{
				CryLogAlways("CDelayNode read: ms=%d  timevalue(ms): %f",(*iter).first, (*iter).second.m_timeout.GetMilliSeconds());
				++iter;
			}
#endif
			pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, !m_activations.empty());
		} else {
			RemovePendingTimers();
			// read serialized activations and re-register at timer
			Activations::iterator iter;
			Activations activations;
			ser.Value("m_activations", activations);
			for (iter = activations.begin(); iter != activations.end(); ++iter) {
				CTimeValue relTime = (*iter).second.m_timeout - curTime; 
				IGameFramework::TimerID timerId = CCryAction::GetCryAction()->AddTimer( relTime, false, functor(CFlowDelayNode::OnTimer),
					this );
				m_activations[timerId] = (*iter).second;
			}
		}
	}
	ser.EndGroup();
}
Example #21
0
void gkTimer::UpdateOnFrameStart()
{
	if(!m_bEnabled)
		return;

	if (sys_max_fps != 0)
	{
		CTimeValue timeFrameMax;
		timeFrameMax.SetMilliSeconds((int64)(1000.f/(float)sys_max_fps));
		static CTimeValue sTimeLast = gEnv->pTimer->GetAsyncTime();
		const CTimeValue timeLast = timeFrameMax + sTimeLast;
		while(timeLast.GetValue() > gEnv->pTimer->GetAsyncTime().GetValue())
		{
			volatile int i=0;
			while(i++ < 1000);
		}
		sTimeLast = gEnv->pTimer->GetAsyncTime();
	}




	assert(m_pfnUpdate);		// call Init() before

	if ((m_nFrameCounter & 127)==0)
	{
		// every bunch of frames, check frequency to adapt to
		// CPU power management clock rate changes
#ifdef OS_WIN32
		LARGE_INTEGER TTicksPerSec;
		if (QueryPerformanceFrequency(&TTicksPerSec))
		{ 
			// if returns false, no performance counter is available
			m_lTicksPerSec=TTicksPerSec.QuadPart;
		}
#endif
	}

	m_nFrameCounter++;

#ifdef PROFILING
	m_fFrameTime = 0.020f; // 20ms = 50fps
	g_lCurrentTime += (int)(m_fFrameTime*(float)(CTimeValue::TIMEVALUE_PRECISION));
	m_lCurrentTime = g_lCurrentTime;
	m_lLastTime = m_lCurrentTime;
	RefreshGameTime(m_lCurrentTime);
	RefreshUITime(m_lCurrentTime);
	return;
#endif
 
	int64 now = (*m_pfnUpdate)();

	if (m_lForcedGameTime >= 0)
	{
		// m_lCurrentTime contains the time, which should be current
		// but time has passed since Serialize until UpdateOnFrameStart
		// so we have to make sure to compensate!
		m_lOffsetTime = m_lForcedGameTime - now + m_lBaseTime;
		m_lLastTime = now - m_lBaseTime;
		m_lForcedGameTime = -1;
	}

	// Real time. 
	m_lCurrentTime = now - m_lBaseTime;

	//m_fRealFrameTime = m_fFrameTime = (float)(m_lCurrentTime-m_lLastTime) / (float)(m_lTicksPerSec);
	m_fRealFrameTime = m_fFrameTime = (float)((double)(m_lCurrentTime-m_lLastTime) / (double)(m_lTicksPerSec));

	if( 0 != m_fixed_time_step) // Absolute zero used as a switch. looks wrong, but runs right ;-)
	{
#ifdef OS_WIN32
		if (m_fixed_time_step < 0)
		{
			// Enforce real framerate by sleeping.
			float sleep = -m_fixed_time_step - m_fFrameTime;
	
			if (sleep > 0)
			{
				// while first
//				float now = GetAsyncCurTime();
				bool breaksleep = 0;
// 				if (sleep < 0.01f)
// 				{
// 					for (int i=0; i < 1000000; ++i)
// 					{
// 						if( GetAsyncCurTime() - now > sleep )
// 						{
// 							breaksleep = 1;
// 							break;
// 						}
// 					}
// 				}

				if (!breaksleep)
				{
					Sleep((unsigned int)(sleep*1000.f));
					m_lCurrentTime = (*m_pfnUpdate)() - m_lBaseTime;
					//m_fRealFrameTime = (float)(m_lCurrentTime-m_lLastTime) / (float)(m_lTicksPerSec);
					m_fRealFrameTime = (float)((double)(m_lCurrentTime-m_lLastTime) / (double)(m_lTicksPerSec));	
				}
			
			}
		}
#endif
		m_fFrameTime = abs(m_fixed_time_step);
	}
	else
	{
		// Clamp it
		m_fFrameTime = min(m_fFrameTime, m_max_time_step);

		// Dilate it.
		m_fFrameTime *= m_time_scale;
	}

	if (m_fFrameTime < 0) 
		m_fFrameTime = 0;



//-----------------------------------------------

	if(m_TimeSmoothing>0)
	{
	/*
		if(m_TimeSmoothing>FPS_FRAMES-1)
			m_TimeSmoothing=FPS_FRAMES-2;

		if(m_fFrameTime < 0.0000001f)
			m_fFrameTime = 0.0000001f;

		m_previousTimes[m_timecount] = m_fFrameTime;

		m_timecount++;
		if(m_timecount>=m_TimeSmoothing)
			m_timecount=0;

		// average multiple frames together to smooth changes out a bit
		float total = 0;
		for(int i = 0 ; i < m_TimeSmoothing+1; i++ ) 
			total += m_previousTimes[i];	
	    
		if(!total) 
			total = 1;

		m_fFrameTime=total/(float)(m_TimeSmoothing+1);
*/
		m_fAverageFrameTime = GetAverageFrameTime( 0.25f, m_fFrameTime, m_fAverageFrameTime); 
		m_fFrameTime=m_fAverageFrameTime;
	}

	//else

	{	
		// Adjust.
		if (m_fFrameTime != m_fRealFrameTime)
		{
			float fBefore = GetAsyncCurTime();
			int64 nAdjust = (int64)((m_fFrameTime - m_fRealFrameTime) * (double)(m_lTicksPerSec));
			m_lCurrentTime += nAdjust;
			m_lBaseTime -= nAdjust;
		}
	}

	RefreshUITime(m_lCurrentTime);
	if (m_bGameTimerPaused == false)
		RefreshGameTime(m_lCurrentTime);

	m_lLastTime = m_lCurrentTime;

	if (m_fRealFrameTime < 0.f)
		// Can happen after loading a saved game and 
		// at any time on dual core AMD machines and laptops :)
		m_fRealFrameTime = 0.0f;

	UpdateBlending();
}
Example #22
0
void CMPTutorial::Update()
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	if(!m_enabled && g_pGameCVars->g_PSTutorial_Enabled)
		EnableTutorialMode(true);
	else if(m_enabled && !g_pGameCVars->g_PSTutorial_Enabled)
		EnableTutorialMode(false);

	m_currentEvent.m_msgDisplayTime -= gEnv->pTimer->GetFrameTime();
	if(!m_enabled)
	{	
		if(m_currentEvent.m_msgDisplayTime < 0.0f && m_currentEvent.m_msgRemovalCondition != eMRC_None)
		{
			m_currentEvent.m_msgRemovalCondition = eMRC_None;
			SAFE_HUD_FUNC(ShowTutorialText(NULL,1));
		}
	}

	// update the text... must be done even if not enabled, to ensure the 'you may reenable...' 
	//	message is shown correctly.
	if(m_currentEvent.m_numChunks > 0)
	{
		// calculate how far through the current sound we are
		CTimeValue now = gEnv->pTimer->GetFrameStartTime();
		float soundTimer = now.GetMilliSeconds() - m_currentEvent.m_soundStartTime;
		assert(soundTimer >= 0);
		float soundPercent = 1.0f;
		if(m_currentEvent.m_soundLength == 0.0f && m_currentEvent.m_pCurrentSound.get())
		{
			m_currentEvent.m_soundLength = m_currentEvent.m_pCurrentSound->GetLengthMs();
		}
		if(m_currentEvent.m_soundLength > 0.0f)
		{
			soundPercent = soundTimer / m_currentEvent.m_soundLength;
		}
		for(int i=m_currentEvent.m_numChunks-1; i > m_currentEvent.m_currentChunk; --i)
		{
			if(m_currentEvent.m_chunks[i].m_startPercent <= soundPercent)
			{
				m_currentEvent.m_currentChunk = i;

				int pos = 2; // 2=bottom, 1=middle
				IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();	
				if(pClientActor && pClientActor->GetLinkedVehicle())
				{
					pos = 1;
				}

				SAFE_HUD_FUNC(ShowTutorialText(m_currentEvent.m_chunks[i].m_text, pos));
				break;
			}
		}
	}

	if(!m_enabled)
		return;

	CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor());
	if(!pPlayer)
		return;

	// don't start until game begins
	if(pPlayer->GetSpectatorMode() != 0 || g_pGame->GetGameRules()->GetCurrentStateId() != 3)
		return;

	if(!m_initialised)
	{
		m_initialised = true;

		if(g_pGame->GetHUD())
		{
			// register as a HUD listener
			g_pGame->GetHUD()->RegisterListener(this);
		}

		// go through entity list and pull out the factories.
		IEntityItPtr pIt = gEnv->pEntitySystem->GetEntityIterator();
		while (!pIt->IsEnd())
		{
			if (IEntity * pEnt = pIt->Next())
			{
				if(pEnt->GetClass() == m_pHQClass)
				{
					m_baseList.push_back(pEnt->GetId());
					//CryLog("Adding HQ %d to list: %d", pEnt->GetId(), m_baseList.size());
				}
				else if(pEnt->GetClass() == m_pAlienEnergyPointClass)
				{
					m_alienEnergyPointList.push_back(pEnt->GetId());
					//CryLog("Adding AEP %d to list: %d", pEnt->GetId(), m_alienEnergyPointList.size());
				}
				else if(pEnt->GetClass() == m_pSpawnGroupClass)
				{
					m_spawnGroupList.push_back(pEnt->GetId());
					//CryLog("Adding spawngroup %d to list: %d", pEnt->GetId(), m_spawnGroupList.size());
				}
				else if(pEnt->GetClass() == m_pFactoryClass)
				{
					m_factoryList.push_back(pEnt->GetId());
					//CryLog("Adding Factory %d to list: %d", pEnt->GetId(), m_factoryList.size());
				}
			}
		}
	}

	// first the briefing events. These are shown in order.
	bool showPrompt = CheckBriefingEvents(pPlayer);

	// player has been killed
	if(pPlayer->GetHealth() <= 0)
	{
		showPrompt = TriggerEvent(eTE_Killed);
	}
	else if(!showPrompt)
	{
		// check each event type here. Which might take a while.

		// entering a neutral factory
		// enter prototype factory
		// enter hostile factory
		// find alien crash
		m_entityCheckTimer -= gEnv->pTimer->GetFrameTime();
		if(m_entityCheckTimer < 0.0f)
		{
			CheckNearbyEntities(pPlayer);
			m_entityCheckTimer = ENTITY_CHECK_TIME;
		}

		// board vehicle and vehicle tutorials
		CheckVehicles(pPlayer);

		// player has been wounded
		if(pPlayer->GetHealth() < pPlayer->GetMaxHealth())
			TriggerEvent(eTE_Wounded);

		// bases
		m_baseCheckTimer -= gEnv->pTimer->GetFrameTime();
		if(m_baseCheckTimer < 0.0f)
		{
			CheckBases(pPlayer);
			m_baseCheckTimer = ENTITY_CHECK_TIME;
		}
	}

	bool promptShown = false;
	for(int i=0; i<eTE_NumEvents; ++i)
	{
		if(m_events[i].m_status == eMS_Waiting)
		{
			if(m_currentEvent.m_msgDisplayTime < -MESSAGE_GAP_TIME)
			{
				ShowMessage(m_events[i]);
			}
			promptShown = true;
			break;
		}
	}

	if(!promptShown	&& (m_currentEvent.m_msgRemovalCondition == eMRC_Time) && (m_currentEvent.m_msgDisplayTime < 0.0f))
	{
		HideMessage();
	}
}
Example #23
0
void CTimer::Add(CIoEvent *apoEvent, const CTimeValue& aoTimeout)
{
    this->Add(apoEvent, aoTimeout.Msec());
}
Example #24
0
STransitionSelectionParams::STransitionSelectionParams(
	const CMovementTransitions& transitions,
	const CPlayer& player,
	const CMovementRequest& request,
	const Vec3& playerPos,
	const SMovementTransitionsSample& oldSample,
	const SMovementTransitionsSample& newSample,
	const bool bHasLockedBodyTarget,
	const Vec3& targetBodyDirection,
	const Lineseg& safeLine,
	const CTimeValue runningDuration,
	const uint8 _allowedTransitionFlags,
	const float entitySpeed2D,
	const float entitySpeed2DAvg,
	const SExactPositioningTarget*const pExactPositioningTarget,
	const EStance stance,

	SActorFrameMovementParams*const pMoveParams) : m_transitionType(eTT_None), m_transitionDistance(0.0f), m_pseudoSpeed(0.0f), m_travelAngle(0.0f), m_jukeAngle(0.0f), m_stance(stance)
{
	// TODO: check for flatness?

	m_travelAngle = Ang3::CreateRadZ( newSample.bodyDirection, oldSample.moveDirection ); // probably should be oldSample?
	m_context = request.HasContext() ? request.GetContext() : 0;

	// --------------------------------------------------------------------------
	// Calculate vToMoveTarget, vAfterMoveTarget, distToMoveTarget, distAfterMoveTarget & allowedTransitionFlags

	Vec3 vToMoveTarget, vAfterMoveTarget;
	float distToMoveTarget, distAfterMoveTarget;
	uint8 allowedTransitionFlags = _allowedTransitionFlags;

	{
		if (request.HasMoveTarget())
		{
			const Vec3& vMoveTarget = request.GetMoveTarget();
			vToMoveTarget = vMoveTarget - playerPos;
			distToMoveTarget = vToMoveTarget.GetLength2D();

			m_future.hasMoveTarget = true;
			m_future.vMoveTarget = vMoveTarget;

			// Disallow certain transitions when preparing an exact positioning target
			// and fudge the distance to make sure we don't start when too close to it
			if (pExactPositioningTarget && pExactPositioningTarget->preparing && !pExactPositioningTarget->activated)
			{
				allowedTransitionFlags &= ~BIT(eTT_Stop);
				allowedTransitionFlags &= ~BIT(eTT_DirectionChange);

				const Vec3& exactPosLocation = pExactPositioningTarget->location.t;
				const float distFromMoveTargetToExactPosSquared = vMoveTarget.GetSquaredDistance(exactPosLocation);

				const float minimumDangerDistance = 0.1f;
				const float maxDistanceTraveledPerFrame = gEnv->pTimer->GetFrameTime() * 12.5f;
				const float dangerDistance = max(minimumDangerDistance, maxDistanceTraveledPerFrame);

				const bool moveTargetIsWithinDangerDistance = (distFromMoveTargetToExactPosSquared <= sqr(dangerDistance));
				if (moveTargetIsWithinDangerDistance)
				{
					// Fudge distToMoveTarget so we start at least distanceTraveledInTwoFrames
					// This only works for eTT_Start transitions (but we disabled the others above)
					distToMoveTarget = max(0.0f, distToMoveTarget - dangerDistance);
				}
			}

			if (request.HasInflectionPoint())
			{
				const Vec3& vInflectionPoint = request.GetInflectionPoint();
				vAfterMoveTarget = vInflectionPoint - vMoveTarget;
				distAfterMoveTarget = vAfterMoveTarget.GetLength2D();
			}
			else
			{
				vAfterMoveTarget.zero();
				distAfterMoveTarget = 0.0f;
			}
		}
		else
		{
			m_future.hasMoveTarget = false;

			vToMoveTarget.zero();
			vAfterMoveTarget.zero();
			distToMoveTarget = distAfterMoveTarget = 0.0f;
		}
	}

	// --------------------------------------------------------------------------

	const float maximumSpeedForStart = 0.5f;
	const float minimumSpeedForWalkStop = 1.0f;
	const float minimumSpeedForRunStop = 3.5f;
	const float minimumRunningDurationForRunStop = 1.0f; // (seconds)

	const float minimumSpeedForJuke = 4.4f*0.6f; // 4.4 is slowest runspeed in Crysis2; 0.6 is the strafing slowdown
	const float minimumRunningDurationForJuke = 0.1f; // (seconds)

	if (newSample.pseudoSpeed > 0.0f)
	{
		// Either:
		// - we are in a Stop and want to start again <-- note oldPseudoSpeed cannot be used to detect this, it could be already 0 from prev. frame
		// - we are in a Start and want to continue starting [but possibly stop or change direction at the movetarget]
		// - we are stopped and want to Start [but possibly stop or change direction at the movetarget]
		// - we are moving and want to continue moving [but possibly stop or change direction at the movetarget]

		m_pseudoSpeed = newSample.pseudoSpeed;

		if ( (allowedTransitionFlags & (1<<eTT_Start)) && (entitySpeed2DAvg <= maximumSpeedForStart) )
		{
			//New sample's movement direction is accurate for start transitions.
			m_travelAngle = Ang3::CreateRadZ( newSample.bodyDirection, newSample.moveDirection );
			m_transitionType = eTT_Start;
			m_bPredicted = true;
			m_transitionDistance = distToMoveTarget;
			m_future.vMoveDirection = newSample.moveDirection;
			const Vec3 realTargetBodyDirection = bHasLockedBodyTarget ? targetBodyDirection : m_future.vMoveDirection;
			m_targetTravelAngle = Ang3::CreateRadZ( realTargetBodyDirection, m_future.vMoveDirection );
			m_future.qOrientation = Quat::CreateRotationVDir( realTargetBodyDirection );
			MovementTransitionsLog("[%x] Juke failed because we are trying to start", gEnv->pRenderer->GetFrameID());
		}
		else // at the moment start & stop are mutually exclusive
		{
			if (!(allowedTransitionFlags & (1<<eTT_Start)))
				MovementTransitionsLog("[%x] Start failed because current animation state (%s) doesn't support starting", gEnv->pRenderer->GetFrameID(), const_cast<CPlayer&>(player).GetAnimationGraphState() ? const_cast<CPlayer&>(player).GetAnimationGraphState()->GetCurrentStateName() : "");
			else
				MovementTransitionsLog("[%x] Start failed because speed is %f while maximum %f is allowed", gEnv->pRenderer->GetFrameID(), player.GetAnimatedCharacter()->GetEntitySpeedHorizontal(), maximumSpeedForStart);

			m_transitionType = eTT_None;

			// try immediate directionchange first
			if (allowedTransitionFlags & (1<<eTT_DirectionChange))
			{
				if (
						((oldSample.pseudoSpeed == AISPEED_RUN) || (oldSample.pseudoSpeed == AISPEED_SPRINT)) &&
						(runningDuration > minimumRunningDurationForJuke) &&
						(entitySpeed2D >= minimumSpeedForJuke)
					)
				{
					if (gEnv->pAISystem && !gEnv->pAISystem->GetSmartObjectManager()->CheckSmartObjectStates(player.GetEntity(), "Busy"))
					{
						// === IMMEDIATE DIRECTIONCHANGE ===

						// ---------------------------------
						// Assume a directionchange after moving forward for one meter (assumedDistanceToJuke=1)
						// Look up a transition math for that proposed directionchange
						// ---------------------------------
						m_pseudoSpeed = oldSample.pseudoSpeed;
						m_transitionDistance = -1;

						float assumedDistanceToJuke = 1.0f;
						CRY_ASSERT(assumedDistanceToJuke > FLT_EPSILON);

						Vec3 vToProposedMoveTarget = newSample.moveDirection * distToMoveTarget; // vector from current position to current movetarget
						Vec3 vToProposedJukePoint = oldSample.moveDirection * assumedDistanceToJuke;
						Vec3 vAfterProposedJukePoint = (vToProposedMoveTarget - vToProposedJukePoint).GetNormalizedSafe(newSample.moveDirection);

						m_jukeAngle = Ang3::CreateRadZ( vToProposedJukePoint, vAfterProposedJukePoint );
						m_transitionType = eTT_DirectionChange;
						m_bPredicted = false;
						m_future.vMoveDirection = vAfterProposedJukePoint;
						Vec3 realTargetBodyDirection = bHasLockedBodyTarget ? targetBodyDirection : vAfterProposedJukePoint;
						m_targetTravelAngle = Ang3::CreateRadZ( realTargetBodyDirection, vAfterProposedJukePoint );

						MovementTransitionsLog("[%x] Considering angle %+3.2f", gEnv->pRenderer->GetFrameID(), RAD2DEG(m_jukeAngle));

						const STransition* pTransition = NULL;
						int index = -1;
						STransitionMatch bestMatch;
						transitions.FindBestMatch(*this, &pTransition, &index, &bestMatch);

						if (pTransition)
						{
							// -------------------------------------------------------
							// We found a transition matching our guess. Adjust juke point to match the distance of the transition we found
							// -------------------------------------------------------
							float proposedTransitionDistance = (pTransition->minDistance + pTransition->maxDistance)*0.5f;
							CRY_ASSERT(proposedTransitionDistance > FLT_EPSILON);
							vToProposedJukePoint = oldSample.moveDirection * proposedTransitionDistance;
							vAfterProposedJukePoint = vToProposedMoveTarget - vToProposedJukePoint;
							float proposedDistAfterMoveTarget = vAfterProposedJukePoint.GetLength2D();
							vAfterProposedJukePoint.NormalizeSafe(newSample.moveDirection);

							if (proposedDistAfterMoveTarget >= transitions.GetMinDistanceAfterDirectionChange())
							{
								m_jukeAngle = Ang3::CreateRadZ( vToProposedJukePoint, vAfterProposedJukePoint );
								m_future.vMoveDirection = vAfterProposedJukePoint;
								realTargetBodyDirection = bHasLockedBodyTarget ? targetBodyDirection : vAfterProposedJukePoint;
								m_targetTravelAngle = Ang3::CreateRadZ( realTargetBodyDirection, vAfterProposedJukePoint );

								MovementTransitionsLog("[%x] Proposing angle %+3.2f", gEnv->pRenderer->GetFrameID(), RAD2DEG(m_jukeAngle));

								m_transitionDistance = proposedTransitionDistance;
								m_future.qOrientation = Quat::CreateRotationVDir( realTargetBodyDirection );
							}
							else
							{
								MovementTransitionsLog("[%x] Immediate Juke failed because not enough distance after the juke (distance needed = %f, max distance = %f)", gEnv->pRenderer->GetFrameID(), transitions.GetMinDistanceAfterDirectionChange(), proposedDistAfterMoveTarget);
								m_transitionType = eTT_None;
							}
						}
						else
						{
							MovementTransitionsLog("[%x] Immediate Juke failed because no animation found for this angle/stance/speed", gEnv->pRenderer->GetFrameID());
							m_transitionType = eTT_None;
						}
					}
					else
					{
						MovementTransitionsLog("[%x] Immediate Juke failed because smart object is playing", gEnv->pRenderer->GetFrameID());
					}
				}
				else
				{
					if (!((oldSample.pseudoSpeed == AISPEED_RUN) || (oldSample.pseudoSpeed == AISPEED_SPRINT)))
					{
						MovementTransitionsLog("[%x] Immediate Juke failed because current pseudospeed (%f) is not supported", gEnv->pRenderer->GetFrameID(), oldSample.pseudoSpeed);
					}
					else if (runningDuration <= minimumRunningDurationForJuke)
					{
						MovementTransitionsLog("[%x] Immediate Juke failed because running only %f seconds while more than %f is needed", gEnv->pRenderer->GetFrameID(), runningDuration.GetSeconds(), minimumRunningDurationForJuke);
					}
					else //if (entitySpeed2D < minimumSpeedForJuke)
					{
						MovementTransitionsLog("[%x] Immediate Juke failed because speed is only %f while %f is needed", gEnv->pRenderer->GetFrameID(), entitySpeed2D, minimumSpeedForJuke);
					}
				}
			}
			else
			{
				MovementTransitionsLog("[%x] Immediate Juke failed because current animation state (%s) doesn't support juking", gEnv->pRenderer->GetFrameID(), const_cast<CPlayer&>(player).GetAnimationGraphState() ? const_cast<CPlayer&>(player).GetAnimationGraphState()->GetCurrentStateName() : NULL);
			}

			if (m_transitionType == eTT_None) // directionchange wasn't found
			{
				if ((allowedTransitionFlags & (1<<eTT_Stop)) && (distAfterMoveTarget < FLT_EPSILON))
				{
					// === PREDICTED STOP ===
					// We want to stop in the future
					m_transitionType = eTT_Stop;
					m_bPredicted = true;
					m_transitionDistance = distToMoveTarget;
					m_future.vMoveDirection = vToMoveTarget.GetNormalizedSafe(newSample.moveDirection);
					m_arrivalAngle = request.HasDesiredBodyDirectionAtTarget() ? Ang3::CreateRadZ( request.GetDesiredBodyDirectionAtTarget(), m_future.vMoveDirection ) : 0.0f;
					m_future.qOrientation = request.HasDesiredBodyDirectionAtTarget() ? Quat::CreateRotationVDir(request.GetDesiredBodyDirectionAtTarget()) : Quat::CreateRotationVDir(m_future.vMoveDirection);
					MovementTransitionsLog("[%x] Predicted Juke failed because we are trying to stop", gEnv->pRenderer->GetFrameID());
				}
				else if ((allowedTransitionFlags & (1<<eTT_DirectionChange)) && (distAfterMoveTarget >= transitions.GetMinDistanceAfterDirectionChange()))
				{
					// === PREDICTED DIRECTIONCHANGE ===
					// We want to change direction in the future
					// NOTE: This logic will fail if we trigger the juke really late, because then the distToMoveTarget will be very small and the angle calculation not precise
					m_transitionType = eTT_DirectionChange;
					m_bPredicted = true;
					m_transitionDistance = distToMoveTarget;
					m_jukeAngle = Ang3::CreateRadZ( vToMoveTarget, vAfterMoveTarget );
					m_future.vMoveDirection = vAfterMoveTarget.GetNormalized();
					const Vec3 realTargetBodyDirection = bHasLockedBodyTarget ? targetBodyDirection : m_future.vMoveDirection;
					m_future.qOrientation = Quat::CreateRotationVDir( realTargetBodyDirection );
					m_targetTravelAngle = Ang3::CreateRadZ( realTargetBodyDirection, m_future.vMoveDirection );
				}
			}
		}
	}
	else // if (newSample.pseudoSpeed <= 0.0f)
	{
		// Either:
		// - we are in a Stop and want to continue stopping
		// - we are moving and suddenly want to stop
		// - we are in a Start and want to stop <-- oldPseudoSpeed logic is wrong, oldPseudoSpeed will be 0 for a while so we should use real velocity
		// - we are stopped already and just want to stay stopped
		MovementTransitionsLog("[%x] Juke failed because we are not running or trying to stop", gEnv->pRenderer->GetFrameID());
		MovementTransitionsLog("[%x] Start failed because we are not requesting movement", gEnv->pRenderer->GetFrameID());

		if (
			(( (oldSample.pseudoSpeed == AISPEED_RUN) || (oldSample.pseudoSpeed == AISPEED_SPRINT)) && (runningDuration > minimumRunningDurationForRunStop) && (entitySpeed2D >= minimumSpeedForRunStop))
			||
			((oldSample.pseudoSpeed == AISPEED_WALK) && (entitySpeed2D >= minimumSpeedForWalkStop))
		)
		{
			if (allowedTransitionFlags & (1<<eTT_Stop))
			{
				// === IMMEDIATE STOP ===
				if( gEnv->pAISystem )
				{
					ISmartObjectManager* pSmartObjectManager = gEnv->pAISystem->GetSmartObjectManager();
					if (!pSmartObjectManager || !pSmartObjectManager->CheckSmartObjectStates(player.GetEntity(), "Busy"))
					{
						// Trigger immediate stop when currently running and suddenly wanting to stop.
						//
						// NOTE: If this happens right before a forbidden area and the safeLine is not correct
						//    or the Stop transition distance isn't configured properly the AI will enter it..
						//
						m_pseudoSpeed = oldSample.pseudoSpeed;
						m_transitionDistance = -1;
						m_arrivalAngle = 0.0f;
							m_transitionType = eTT_Stop;
						m_bPredicted = false;

						const STransition* pTransition = NULL;
						int index = -1;
						STransitionMatch bestMatch;
						transitions.FindBestMatch(*this, &pTransition, &index, &bestMatch);

						float minDistanceForStop = pTransition ? pTransition->minDistance : 0.0f;

						bool bIsOnSafeLine = IsOnSafeLine(safeLine, playerPos, newSample.moveDirection, minDistanceForStop);

						if (bIsOnSafeLine)
						{
							m_transitionDistance = minDistanceForStop;
							m_future.vMoveDirection = newSample.moveDirection;
							m_future.qOrientation = Quat::CreateRotationVDir(newSample.moveDirection);

							pMoveParams->desiredVelocity = player.GetEntity()->GetWorldRotation().GetInverted() * player.GetLastRequestedVelocity();

							float maxSpeed = player.GetStanceMaxSpeed(m_stance);
							if (maxSpeed > 0.01f)
								pMoveParams->desiredVelocity /= maxSpeed;
						}
						else
						{
							m_transitionType = eTT_None;
						}
					}
				}
			}
		}
	}

	if (request.HasDesiredSpeed())
	{
		m_future.speed = request.GetDesiredTargetSpeed();
	}
}
Example #25
0
static void SaveToXML(const XmlNodeRef& n, const char* name, const CTimeValue& t)
{
	n->setAttr(name, t.GetMilliSecondsAsInt64());
}
Example #26
0
void CMPTutorial::ShowMessage(STutorialEvent& event)
{
	assert(event.m_status == eMS_Waiting);

	// cancel previous sound if necessary
	if(m_currentEvent.m_pCurrentSound.get())
	{
		m_currentEvent.m_pCurrentSound->Stop(ESoundStopMode_AtOnce);
		m_currentEvent.m_pCurrentSound = NULL;
	}

	// also play the sound here
	if(gEnv->pSoundSystem && event.m_soundName.compare("None"))
	{
		string soundName = "mp_american/" + event.m_soundName;
		m_currentEvent.m_pCurrentSound = gEnv->pSoundSystem->CreateSound(soundName.c_str(),FLAG_SOUND_VOICE);
		if (m_currentEvent.m_pCurrentSound.get())
		{
			m_currentEvent.m_pCurrentSound->AddEventListener(this, "mptutorial");
			m_currentEvent.m_msgDisplayTime = 1000.0f;	// will be removed by sound finish event
			m_currentEvent.m_pCurrentSound->Play();
			m_currentEvent.m_soundLength = m_currentEvent.m_pCurrentSound->GetLengthMs();		// NB this almost certainly returns 0 as the sound isn't buffered yet :(
			CTimeValue time = gEnv->pTimer->GetFrameStartTime();
			m_currentEvent.m_soundStartTime = time.GetMilliSeconds();
		}
	}
	else
	{
		m_currentEvent.m_msgDisplayTime = MESSAGE_DISPLAY_TIME;

	}

	// create the localised text string from enum
	string msg;
	wstring localizedString;
	wstring finalString;
	ILocalizationManager *pLocalizationMan = gEnv->pSystem->GetLocalizationManager();
	if(!pLocalizationMan) 
		return;

	if(m_currentEvent.m_pCurrentSound)
	{
		msg = GetSoundKey(m_currentEvent.m_pCurrentSound->GetName());
		pLocalizationMan->GetSubtitle(msg.c_str(), localizedString, true);
	}
	else
	{
		msg = "@mp_Tut" + event.m_name;
		pLocalizationMan->LocalizeString(msg, localizedString);
	}

	if(localizedString.empty())
		return;

	// fill out keynames if necessary
	if(!strcmp(event.m_name, "BoardVehicle"))
	{
		// special case for this event - has 5 actions associated...
		string action1 = "@cc_";
		string action2 = "@cc_";
		string action3 = "@cc_";
		string action4 = "@cc_";
		string action5 = "@cc_";

		action1 += GetKeyName("v_changeseat1");
		action2 += GetKeyName("v_changeseat2");
		action3 += GetKeyName("v_changeseat3");
		action4 += GetKeyName("v_changeseat4");
		action5 += GetKeyName("v_changeseat5");

		wstring wActions[5];
		pLocalizationMan->LocalizeString(action1, wActions[0]);
		pLocalizationMan->LocalizeString(action2, wActions[1]);
		pLocalizationMan->LocalizeString(action3, wActions[2]);
		pLocalizationMan->LocalizeString(action4, wActions[3]);
		pLocalizationMan->LocalizeString(action5, wActions[4]);

		const wchar_t* params[] = {wActions[0].c_str(), wActions[1].c_str(), wActions[2].c_str(), wActions[3].c_str(), wActions[4].c_str()};
		pLocalizationMan->FormatStringMessage(finalString, localizedString, params, 5);
	}
	else if(!event.m_action.empty())
	{
		// first get the key name (eg 'mouse1') and make it into a format the localization system understands

		string action = "@cc_";
		action += GetKeyName(event.m_action.c_str());
		wstring wActionString;
		pLocalizationMan->LocalizeString(action, wActionString);

		// now place this in the right place in the string.
		pLocalizationMan->FormatStringMessage(finalString, localizedString, wActionString.c_str());
	}
	else
	{
		finalString = localizedString;
	}

	// split the text into chunks (to allow super-long strings to fit within the window)
	CreateTextChunks(finalString);

	// set status
	event.m_status = eMS_Displaying;

	// set message removal condition
	m_currentEvent.m_msgRemovalCondition = event.m_removal;
	if(!event.m_soundName.compare("None") && m_currentEvent.m_msgRemovalCondition == eMRC_SoundFinished)
		m_currentEvent.m_msgRemovalCondition = eMRC_Time;	// since for now there're some that don't have audio.
}
	float GetDuration(int iA, int iB)
	{
		CTimeValue dt = m_stickHistoryTime[iB] - m_stickHistoryTime[iA];
		return fabs_tpl(dt.GetSeconds());
	}