Exemplo n.º 1
0
void CHLTVDirector::StartInstantBroadcastShot()
{
	m_nNextShotTick = m_nBroadcastTick + TIME_TO_TICKS( MAX_SHOT_LENGTH );

	if ( m_iCameraManIndex > 0 )
	{
		// camera man is still recording and live, resend camera man message
		IGameEvent *msg = gameeventmanager->CreateEvent( "hltv_cameraman", true );
		if ( msg )
		{
			msg->SetInt("index", m_iCameraManIndex );
			m_pHLTVServer->BroadcastEvent( msg );
			gameeventmanager->FreeEvent( msg );

			m_iPVSEntity = m_iCameraManIndex;
			m_nNextShotTick = m_nBroadcastTick+TIME_TO_TICKS( MIN_SHOT_LENGTH ); 
		}
	}
	else
	{
		RemoveEventsFromHistory(-1); // all

		AnalyzePlayers();

		AnalyzeCameras();

		StartRandomShot();
	}
}
Exemplo n.º 2
0
void CHLTVDirector::UpdateSettings()
{
	// set delay
	m_fDelay = tv_delay.GetFloat();
	m_fDelay = clamp( m_fDelay, HLTV_MIN_DELAY, HLTV_MAX_DELAY );

	// broadcast time is current time - delay time
	int newBroadcastTick = gpGlobals->tickcount - TIME_TO_TICKS( m_fDelay );

	if( (m_nBroadcastTick == 0) && (newBroadcastTick > 0) )
	{
		// we start broadcasting right now, reset NextShotTimer
		m_nNextShotTick = 0;
	}

	// check if camera man is still valid 
	if ( m_iCameraManIndex > 0 )
	{
		CBasePlayer *pPlayer = UTIL_PlayerByIndex( m_iCameraManIndex );
		if ( !pPlayer || pPlayer->GetTeamNumber() != TEAM_SPECTATOR )
		{
			SetCameraMan( 0 );
		}
	}

   	m_nBroadcastTick = MAX( 0, newBroadcastTick );
}
Exemplo n.º 3
0
void CHLTVDirector::FrameUpdatePostEntityThink( void )
{
	if ( !m_pHLTVServer )
		return;	// don't do anything

	// This function is called each tick
	UpdateSettings();	// update settings from cvars

	if ( m_nNextAnalyzeTick < gpGlobals->tickcount )
	{
		m_nNextAnalyzeTick = gpGlobals->tickcount + TIME_TO_TICKS( 0.5f );

		AnalyzePlayers();

		AnalyzeCameras();
	}

	if ( m_nBroadcastTick <= 0 )
	{
		// game start is still in delay loop
		StartDelayMessage();
	}
	else if ( m_nNextShotTick <= m_nBroadcastTick )
	{
		// game is being broadcasted, generate camera shots
		StartNewShot();		
	}
}
Exemplo n.º 4
0
void lagcompensation::create_move() {
	last_eye_positions.push_front(g_ctx.m_local->get_eye_pos());
	if (last_eye_positions.size() > 128)
		last_eye_positions.pop_back();

	auto nci = g_csgo.m_engine()->GetNetChannelInfo();
	if (!nci)
		return;

	const int latency_ticks = TIME_TO_TICKS(nci->GetLatency(FLOW_OUTGOING));
	const auto latency_based_eye_pos = last_eye_positions.size() <= latency_ticks ? last_eye_positions.back() : last_eye_positions[latency_ticks];

	for (int i = 1; i <= g_csgo.m_globals()->m_maxclients; i++) {
		auto e = static_cast<player_t *>(g_csgo.m_entitylist()->GetClientEntity(i));
		auto & player = players[i];

		player.m_e = e;

		if (!e) { player.m_e = nullptr; continue; }

		if (!e->valid(true))
			continue;

		player.m_resolver->m_e = e;
		player.m_resolver->create_move(latency_based_eye_pos);
	}
}
Exemplo n.º 5
0
void CHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	
	bool bPlayerHurt = Q_strcmp( "player_hurt", name ) == 0;
	bool bPlayerKilled = Q_strcmp( "player_death", name ) == 0;
	bool bRoundStart = Q_strcmp( "round_start", name ) == 0;
	bool bRoundEnd = Q_strcmp( "round_end", name ) == 0;

	if ( bPlayerHurt || bPlayerKilled )
	{
		CBaseEntity *victim = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );
		CBaseEntity *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") );

		if ( !victim )
			return;

		if ( attacker == victim || attacker == NULL )
		{
			// player killed self or by WORLD
			StartChaseCameraShot( victim->entindex(), 0, 96, 20, 0, false );
		}
		else // attacker != NULL
		{
			// check if we would show it from ineye view
			bool bInEye = (bPlayerKilled && RandomFloat(0,1) > 0.33) || (bPlayerHurt && RandomFloat(0,1) > 0.66); 

			// if we show ineye view, show it more likely from killer
			if ( RandomFloat(0,1) > (bInEye?0.3f:0.7f)  )
			{
				V_swap( attacker, victim );
			}
						
			// hurting a victim is shown as chase more often
			// view from behind over head
			// lower view point, dramatic
			// view over shoulder, randomly left or right
			StartChaseCameraShot( victim->entindex(), attacker->entindex(), 96, -20, (RandomFloat()>0.5)?30:-30, bInEye );
		}
				
		// shot 2 seconds after death/hurt
		m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
	}
	else if ( bRoundStart || bRoundEnd )
	{
		StartBestFixedCameraShot( false );
	}
	else
	{
		DevMsg( "No known TV shot for event %s\n", name );
	}
}
Exemplo n.º 6
0
/*======================================
 *    receive  a mail to mailbox
 *       接收邮件从邮箱
 *======================================*/
void* acoral_mbox_recv(acoral_evt_t * event, acoral_time timeout)
{
	void            *msg;
	acoral_sr         cpu_sr;
	acoral_thread_t  *cur;
	
	if (acoral_intr_nesting > 0)
		return NULL;

	if(event->type!=ACORAL_EVENT_MBOX)
		return NULL;
	
	HAL_ENTER_CRITICAL();
	acoral_spin_lock(&event->spin_lock);
	if( event->data == NULL)
	{
		cur = acoral_cur_thread;
		if (timeout > 0)
		{
			cur->delay = TIME_TO_TICKS(timeout);
			timeout_queue_add(cur);
		}
		acoral_unrdy_thread(cur);
		acoral_evt_queue_add(event, cur);
		acoral_spin_unlock(&event->spin_lock);
		HAL_EXIT_CRITICAL();
		acoral_sched();
		HAL_ENTER_CRITICAL();
		acoral_spin_lock(&event->spin_lock);

		if (timeout > 0 && cur->delay <= 0)
		{
			acoral_evt_queue_del(cur);
			acoral_spin_unlock(&event->spin_lock);
			HAL_EXIT_CRITICAL();
			return NULL;
		}

		msg        = event->data;
		event->data = NULL;
		acoral_spin_unlock(&event->spin_lock);
		HAL_EXIT_CRITICAL();
		return msg;
	}
	
	msg         = event->data;
	event->data = NULL;
	acoral_spin_unlock(&event->spin_lock);
	HAL_EXIT_CRITICAL();

	return msg;
}
Exemplo n.º 7
0
// when running in threaded host mode, the clock drifts by a predictable algorithm
// because the client lags the server by one frame
// so at each update from the network we have lastframeticks-1 pending ticks to execute
// on the client.  If the clock has drifted by exactly that amount, allow it to drift temporarily
// NOTE: When the server gets paused the tick count is still incorrect for a frame
// NOTE: It should be possible to fix this by applying pause before the tick is incremented
// NOTE: or decrementing the client tick after receiving pause
// NOTE: This is due to the fact that currently pause is applied at frame start on the server
// NOTE: and frame end on the client
void CClockDriftMgr::SetServerTick( int nTick )
{
#if !defined( SWDS )
	m_nServerTick = nTick;

	int nMaxDriftTicks = IsEngineThreaded() ? 
		TIME_TO_TICKS( (cl_clockdrift_max_ms_threadmode.GetFloat() / 1000.0) ) :
		TIME_TO_TICKS( (cl_clockdrift_max_ms.GetFloat() / 1000.0) );

	int clientTick = cl.GetClientTickCount() + g_ClientGlobalVariables.simTicksThisFrame - 1;
	if ( cl_clock_correction_force_server_tick.GetInt() == 999 )
	{
		// If this is the first tick from the server, or if we get further than cl_clockdrift_max_ticks off, then 
		// use the old behavior and slam the server's tick into the client tick.
		if ( !IsClockCorrectionEnabled() ||
			 clientTick == 0 || 
			 abs(nTick - clientTick) > nMaxDriftTicks
			)
		{
			cl.SetClientTickCount( nTick - (g_ClientGlobalVariables.simTicksThisFrame - 1) );
			if ( cl.GetClientTickCount() < cl.oldtickcount )
			{
				cl.oldtickcount = cl.GetClientTickCount();
			}
			memset( m_ClockOffsets, 0, sizeof( m_ClockOffsets ) );
		}
	}
	else
	{
		// Used for testing..
		cl.SetClientTickCount( nTick + cl_clock_correction_force_server_tick.GetInt() );
	}

	// adjust the clock offset by the clock with thread mode compensation
	m_ClockOffsets[m_iCurClockOffset] = clientTick - m_nServerTick;
	m_iCurClockOffset = (m_iCurClockOffset + 1) % NUM_CLOCKDRIFT_SAMPLES;
#endif // SWDS
}
Exemplo n.º 8
0
void CHLTVDirector::FinishCameraManShot()
{
	Assert( m_iCameraMan == m_iPVSEntity );

	int index = FindFirstEvent( m_nBroadcastTick );

	if ( index == m_EventHistory.InvalidIndex() )
	{
		// check next frame again if event history is empty
		m_nNextShotTick = m_nBroadcastTick+1;
		return;
	}

	m_nNextShotTick = m_nBroadcastTick + TIME_TO_TICKS( DEF_SHOT_LENGTH );

	//check if camera turns camera off within broadcast time and game time
	while( index != m_EventHistory.InvalidIndex() )
	{
		CGameEvent &dc = m_EventHistory[index];

		if ( dc.m_Tick >= m_nNextShotTick )
			break;

		if ( Q_strcmp( dc.m_Event->GetName(), "hltv_cameraman") == 0 )
		{
			int iNewCameraMan = dc.m_Event->GetInt("index");

			if ( iNewCameraMan == 0 )
			{
				// camera man switched camera off
				m_nNextShotTick = dc.m_Tick+1;
				m_iCameraMan = 0;
				return;
			}
		}

		index = m_EventHistory.NextInorder( index );
	}

	// camera man is still recording and live, resend camera man message
	IGameEvent *msg = gameeventmanager->CreateEvent( "hltv_cameraman", true );
	if ( msg )
	{
		msg->SetInt("index", m_iCameraMan );
		m_pHLTVServer->BroadcastEvent( msg );
		gameeventmanager->FreeEvent( msg );
	}

}
Exemplo n.º 9
0
void CHLTVDirector::StartRandomShot() 
{
	int toTick = m_nBroadcastTick + TIME_TO_TICKS ( DEF_SHOT_LENGTH );
	m_nNextShotTick = MIN( m_nNextShotTick, toTick );

	if ( RandomFloat(0,1) < 0.25 && tv_allow_static_shots.GetBool() )
	{
		// create a static shot from a level camera
		StartBestFixedCameraShot( false );
	}
	else
	{
		// follow a player
		StartBestPlayerCameraShot();
	}
}
void CDemoActionSkipAhead::FireAction( void )
{
	// demo->StartSkippingAhead( m_bUsingSkipFrame, m_nSkipToFrame, m_flSkipToTime );
	// demo->PushDemoAction( GetActionName() );

	// Don't this this, instead wait for demo to notify us that it's finished skipping
	// SetFinishedAction( true );
	if ( m_bUsingSkipTick )
	{
		demoplayer->SkipToTick( m_nSkipToTick, false, false );
	}
	else
	{
		demoplayer->SkipToTick( TIME_TO_TICKS(m_flSkipToTime), false, false );
	}

	SetFinishedAction( true );
}
Exemplo n.º 11
0
void CHLTVDirector::StartDelayMessage()
{
	if ( m_nNextShotTick > gpGlobals->tickcount )
		return;

	// check the next 8 seconds for interrupts/important events
	m_nNextShotTick = gpGlobals->tickcount + TIME_TO_TICKS( DEF_SHOT_LENGTH );

	// game hasn't started yet, we are still in the broadcast delay hole
	IGameEvent *msg = gameeventmanager->CreateEvent( "hltv_message", true );

	if ( msg )
	{
		msg->SetString("text", "Please wait for broadcast to start ..." );

		// send spectators the HLTV director command as a game event
		m_pHLTVServer->BroadcastEvent( msg );
		gameeventmanager->FreeEvent( msg );
	}

	StartBestFixedCameraShot( true );
}
Exemplo n.º 12
0
// Called during player movement to set up/restore after lag compensation
void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCmd *cmd )
{
	//DONT LAG COMP AGAIN THIS FRAME IF THERES ALREADY ONE IN PROGRESS
	//IF YOU'RE HITTING THIS THEN IT MEANS THERES A CODE BUG
	if ( m_pCurrentPlayer )
	{
		Assert( m_pCurrentPlayer == NULL );
		Warning( "Trying to start a new lag compensation session while one is already active!\n" );
		return;
	}

	// sort out any changes to the AI indexing
	if ( m_bNeedsAIUpdate ) // to be called once per frame... must happen BEFORE lag compensation -
	{// if that happens, that is. if not its called at the end of the frame
		m_bNeedsAIUpdate = false;
		UpdateAIIndexes();
	}

	// Assume no players or entities need to be restored
	m_RestorePlayer.ClearAll();
	m_RestoreEntity.ClearAll();
	m_bNeedToRestore = false;

	m_pCurrentPlayer = player;
	
	if ( !player->m_bLagCompensation		// Player not wanting lag compensation
		 || (gpGlobals->maxClients <= 1)	// no lag compensation in single player
		 || !sv_unlag.GetBool()				// disabled by server admin
		 || player->IsBot() 				// not for bots
		 || player->IsObserver()			// not for spectators
		)
		return;

	// NOTE: Put this here so that it won't show up in single player mode.
	VPROF_BUDGET( "StartLagCompensation", VPROF_BUDGETGROUP_OTHER_NETWORKING );
	Q_memset( m_RestoreData, 0, sizeof( m_RestoreData ) );
	Q_memset( m_ChangeData, 0, sizeof( m_ChangeData ) );
	Q_memset( m_EntityRestoreData, 0, sizeof( m_EntityRestoreData ) );
	Q_memset( m_EntityChangeData, 0, sizeof( m_EntityChangeData ) );

	// Get true latency

	// correct is the amout of time we have to correct game time
	float correct = 0.0f;

	INetChannelInfo *nci = engine->GetPlayerNetInfo( player->entindex() ); 

	if ( nci )
	{
		// add network latency
		correct+= nci->GetLatency( FLOW_OUTGOING );
	}

	// calc number of view interpolation ticks - 1
	int lerpTicks = TIME_TO_TICKS( player->m_fLerpTime );

	// add view interpolation latency see C_BaseEntity::GetInterpolationAmount()
	correct += TICKS_TO_TIME( lerpTicks );
	
	// check bouns [0,sv_maxunlag]
	correct = clamp( correct, 0.0f, sv_maxunlag.GetFloat() );

	// correct tick send by player 
	int targettick = cmd->tick_count - lerpTicks;

	// calc difference between tick send by player and our latency based tick
	float deltaTime =  correct - TICKS_TO_TIME(gpGlobals->tickcount - targettick);

	if ( fabs( deltaTime ) > 0.2f )
	{
		// difference between cmd time and latency is too big > 200ms, use time correction based on latency
		// DevMsg("StartLagCompensation: delta too big (%.3f)\n", deltaTime );
		targettick = gpGlobals->tickcount - TIME_TO_TICKS( correct );
	}
	
	// Iterate all active players
	const CBitVec<MAX_EDICTS> *pEntityTransmitBits = engine->GetEntityTransmitBitsForClient( player->entindex() - 1 );
	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
		if ( !pPlayer || player == pPlayer )
			continue;

		// Custom checks for if things should lag compensate (based on things like what team the player is on).
		if ( !player->WantsLagCompensationOnEntity( pPlayer, cmd, pEntityTransmitBits ) )
			continue;

		// Move other player back in time
		BacktrackPlayer( pPlayer, TICKS_TO_TIME( targettick ) );
	}

	// also iterate all monsters
	CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
	int nAIs = g_AI_Manager.NumAIs();

	for ( int i = 0; i < nAIs; i++ )
	{
		CAI_BaseNPC *pNPC = ppAIs[i];
		// Custom checks for if things should lag compensate
		if ( !pNPC || !player->WantsLagCompensationOnEntity( pNPC, cmd, pEntityTransmitBits ) )
			continue;
		
		// Move NPC back in time
		BacktrackEntity( pNPC, TICKS_TO_TIME( targettick ) );
	}
}
Exemplo n.º 13
0
void CTFHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
{
    // show event at least for 2 more seconds after it occured
    const char *name = event->m_Event->GetName();

    int thera = RandomFloat()>0.5?20:-20;

    if ( !Q_strcmp( "teamplay_point_startcapture", name ) ||
            !Q_strcmp( "teamplay_point_captured", name ) ||
            !Q_strcmp( "teamplay_capture_blocked", name ) )
    {
        CBaseEntity *pCapturePoint = GetCapturePointByIndex( event->m_Event->GetInt( "cp" ) );

        int iCameraIndex = -1;
        float flClosest = 99999.9f;

        if ( pCapturePoint )
        {
            // Does it have an associated viewpoint?
            for ( int i = 0; i<m_nNumFixedCameras; i++ )
            {
                CBaseEntity *pCamera = m_pFixedCameras[ i ];

                if ( pCamera )
                {
                    byte pvs[MAX_MAP_CLUSTERS/8];
                    int clusterIndex = engine->GetClusterForOrigin( pCamera->GetAbsOrigin() );
                    engine->GetPVSForCluster( clusterIndex, sizeof(pvs), pvs );
                    bool bCameraInPVS = engine->CheckOriginInPVS( pCapturePoint->GetAbsOrigin(), pvs, sizeof( pvs ) );

                    if ( bCameraInPVS == true )
                    {
                        float flDistance = (pCapturePoint->GetAbsOrigin() - pCamera->GetAbsOrigin()).Length();
                        if ( flDistance <= flClosest )
                        {
                            iCameraIndex = i;
                            flClosest = flDistance;
                        }
                    }
                }
            }
        }

        CBasePlayer *pPlayer = NULL;

        if ( !Q_strcmp( "teamplay_point_captured", name ) )
        {
            const char *pszCappers = event->m_Event->GetString("cappers");
            int nLength = Q_strlen(pszCappers);

            if ( nLength > 0 )
            {
                int iRandomCapper = pszCappers[ RandomInt(0,nLength-1) ];
                pPlayer = UTIL_PlayerByIndex( iRandomCapper );
            }
        }
        else if ( !Q_strcmp( "teamplay_capture_blocked", name ) )
        {
            int iBlocker = event->m_Event->GetInt("blocker");
            pPlayer = UTIL_PlayerByIndex( iBlocker );
        }

        if ( pPlayer )
        {
            if ( iCameraIndex >= 0 && RandomFloat() > 0.66f )
            {
                StartFixedCameraShot( iCameraIndex, pPlayer->entindex() );
            }
            else if ( pCapturePoint )
            {
                StartChaseCameraShot( pPlayer->entindex(), pCapturePoint->entindex(), 96, 20, thera, false );
            }
            else
            {
                StartChaseCameraShot( pPlayer->entindex(), 0, 96, 20, 0, false );
            }
        }
        else if ( iCameraIndex >= 0 && pCapturePoint )
        {
            // no player known for this event
            StartFixedCameraShot( iCameraIndex, pCapturePoint->entindex() );
        }

        // shot 2 seconds after event
        m_nNextShotTick = min( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(1.0)) );
    }
    else if ( !Q_strcmp( "object_destroyed", name ) )
    {
        CBasePlayer *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") );
        if ( attacker )
        {
            int iObjectIndex = event->m_Event->GetInt("index");
            StartChaseCameraShot( attacker->entindex(), iObjectIndex, 96, 20, thera, false );
        }
    }
    else if ( !Q_strcmp( "ctf_flag_captured", name ) )
    {
        CBasePlayer *capper = UTIL_PlayerByUserId( event->m_Event->GetInt("capper") );
        if ( capper )
        {
            StartChaseCameraShot( capper->entindex(), 0, 96, 20, 0, false );
        }
    }
    else if ( !Q_strcmp( "teamplay_flag_event", name ) )
    {
        StartChaseCameraShot( event->m_Event->GetInt("player"), 0, 96, 20, 0, false );
    }
    else
    {

        // let baseclass create a shot
        BaseClass::CreateShotFromEvent( event );
    }
}
Exemplo n.º 14
0
inline int GetServerTickCount()
{
	int nTick = TIME_TO_TICKS( engine->GetLastTimeStamp() );
	return nTick;
}
Exemplo n.º 15
0
/*=============================
 *  the appliation for mutex
 *      信号号申请操作
 *  优先级继承的优先级反转解决
 *=============================*/
acoral_u32 acoral_mutex_pend(acoral_evt_t *evt, acoral_time timeout)
{
    acoral_sr        cpu_sr;
    acoral_u8        highPrio;
    acoral_u8        ownerPrio;
    acoral_thread_t *thread;
    acoral_thread_t *cur;

    if(acoral_intr_nesting>0)
        return MUTEX_ERR_INTR;

    cur=acoral_cur_thread;

    HAL_ENTER_CRITICAL();
    acoral_spin_lock(&evt->spin_lock);
    if (NULL== evt)
    {
        acoral_spin_unlock(&evt->spin_lock);
        HAL_EXIT_CRITICAL();
        return MUTEX_ERR_NULL;
    }

    if ((acoral_u8)(evt->count & MUTEX_L_MASK) == MUTEX_AVAI)
    {
        /* 申请成功*/
        evt->count &= MUTEX_U_MASK;
        evt->count |= cur->prio;
        evt->data = (void*)cur;
        acoral_spin_unlock(&evt->spin_lock);
        HAL_EXIT_CRITICAL();
        return MUTEX_SUCCED;
    }

    /* 互斥量已被占有*/
    /* 这里要看进程是否一个核上的*/
    /* 是一个核上的任务才有可能发生优先级反转*/
    highPrio = (acoral_u8)(evt->count >> 8);
    ownerPrio = (acoral_u8)(evt->count & MUTEX_L_MASK);
    thread = (acoral_thread_t*)evt->data;

    if (thread->prio != highPrio&&ownerPrio>cur->prio)
    {
        /*有可能优先级反转,提升拥有者优先级*/
        if(highPrio==0)
            highPrio=cur->prio;
        acoral_thread_change_prio(thread,highPrio);
    }
    /*不需要或不能提高优先级*/
    acoral_unrdy_thread(cur);
    acoral_evt_queue_add(evt,cur);
    if (timeout > 0)
    {
        /*加载到超时队列*/
        cur->delay = TIME_TO_TICKS(timeout);
        timeout_queue_add(cur);
    }
    acoral_spin_unlock(&evt->spin_lock);
    HAL_EXIT_CRITICAL();
    acoral_sched();
    HAL_ENTER_CRITICAL();
    acoral_spin_lock(&evt->spin_lock);
    if(evt->data!=cur&&timeout>0&&cur->delay<=0) {
        acoral_printk("Time Out Return\n");
        acoral_evt_queue_del(cur);
        acoral_spin_unlock(&evt->spin_lock);
        HAL_EXIT_CRITICAL();
        return MUTEX_ERR_TIMEOUT;
    }

    //---------------
    // modify by pegasus 0804: timeout_queue_del [+]
    timeout_queue_del(cur);

    if(evt->data!=cur) {
        acoral_printk("Err Ready Return\n");
        acoral_evt_queue_del(cur);
        acoral_spin_unlock(&evt->spin_lock);
        HAL_EXIT_CRITICAL();
        return MUTEX_ERR_RDY;
    }

    return MUTEX_SUCCED;
}
Exemplo n.º 16
0
void Resolver::Resolve()
{
	for (int i = 1; i <= g_GlobalVars->maxClients; i++)
	{
		auto &record = arr_infos[i];
		if (!record.m_bActive)
			continue;

		C_BasePlayer *player = C_BasePlayer::GetPlayerByIndex(i);
		if (!player || !player->IsAlive() || player->IsDormant() || player == g_LocalPlayer)
			continue;

		if (record.m_flVelocity == 0.f && player->m_vecVelocity().Length2D() != 0.f)
		{
			Math::VectorAngles(player->m_vecVelocity(), record.m_angDirectionFirstMoving);
			record.m_nCorrectedFakewalkIdx = 0;
		}

		auto firedShots = g_LocalPlayer->m_iShotsFired();

		if (g_Options.debug_fliponkey)
		{
			float_t new_yaw = player->m_flLowerBodyYawTarget();
			if (g_InputSystem->IsButtonDown(g_Options.debug_flipkey))
				new_yaw += 180.f;
			new_yaw = Math::ClampYaw(new_yaw);
			player->m_angEyeAngles().yaw = new_yaw;
			return;
		}

		if (g_Options.hvh_resolver_override && g_InputSystem->IsButtonDown(g_Options.hvh_resolver_override_key))
		{
			Override(); //needs an improvement sometimes f****d up xD

			Global::resolverModes[player->EntIndex()] = "Overriding";

			return;
		}

		AnimationLayer curBalanceLayer, prevBalanceLayer;

		ResolveInfo curtickrecord;
		curtickrecord.SaveRecord(player);

		if ((player->m_fFlags() & FL_ONGROUND) && (IsFakewalking(player, curtickrecord) || (player->m_vecVelocity().Length2D() > 0.1f && player->m_vecVelocity().Length2D() < 45.f && !(player->m_fFlags() & FL_DUCKING)))) //Fakewalk, shiftwalk check // We have to rework the fakewalk resolving, it sucks :D
		{
			float_t new_yaw = ResolveFakewalk(player, curtickrecord);
			new_yaw = Math::ClampYaw(new_yaw);

			player->m_angEyeAngles().yaw = new_yaw;

			Global::resolverModes[player->EntIndex()] = "Fakewalking";

			continue;
		}
		if (IsEntityMoving(player))
		{
			float_t new_yaw = player->m_flLowerBodyYawTarget();
			new_yaw = Math::ClampYaw(new_yaw);

			player->m_angEyeAngles().yaw = new_yaw;

			record.m_flStandingTime = player->m_flSimulationTime();
			record.m_flMovingLBY = player->m_flLowerBodyYawTarget();
			record.m_bIsMoving = true;

			Global::resolverModes[player->EntIndex()] = "Moving";

			continue;
		}
		if (IsAdjustingBalance(player, curtickrecord, &curBalanceLayer))
		{
			if (fabsf(LBYDelta(curtickrecord)) > 35.f)
			{
				float_t new_yaw = player->m_flLowerBodyYawTarget() + record.m_flLbyDelta;
				new_yaw = Math::ClampYaw(new_yaw);

				player->m_angEyeAngles().yaw = new_yaw;

				Global::resolverModes[player->EntIndex()] = "Fakehead (delta > 35)";
			}
			if (IsAdjustingBalance(player, record, &prevBalanceLayer))
			{
				if ((prevBalanceLayer.m_flCycle != curBalanceLayer.m_flCycle) || curBalanceLayer.m_flWeight == 1.f)
				{
					float
						flAnimTime = curBalanceLayer.m_flCycle,
						flSimTime = player->m_flSimulationTime();

					if (flAnimTime < 0.01f && prevBalanceLayer.m_flCycle > 0.01f && g_Options.rage_lagcompensation && CMBacktracking::Get().IsTickValid(TIME_TO_TICKS(flSimTime - flAnimTime)))
					{
						CMBacktracking::Get().SetOverwriteTick(player, QAngle(player->m_angEyeAngles().pitch, player->m_flLowerBodyYawTarget(), 0), (flSimTime - flAnimTime), 2);
					}

					float_t new_yaw = player->m_flLowerBodyYawTarget();
					new_yaw = Math::ClampYaw(new_yaw);

					player->m_angEyeAngles().yaw = new_yaw;

					Global::resolverModes[player->EntIndex()] = "Breaking LBY";

					continue;
				}
				else if (curBalanceLayer.m_flWeight == 0.f && (prevBalanceLayer.m_flCycle > 0.92f && curBalanceLayer.m_flCycle > 0.92f)) // breaking lby with delta < 120
				{
					if (player->m_flSimulationTime() >= record.m_flStandingTime + 0.22f && record.m_bIsMoving)
					{
						record.m_flLbyDelta = record.m_flLowerBodyYawTarget - player->m_flLowerBodyYawTarget();

						float_t new_yaw = player->m_flLowerBodyYawTarget() + record.m_flLbyDelta;
						new_yaw = Math::ClampYaw(new_yaw);

						player->m_angEyeAngles().yaw = new_yaw;

						record.m_bIsMoving = false;

						Global::resolverModes[player->EntIndex()] = "Breaking LBY (delta < 120)";

						continue;
					}

					if (player->m_flSimulationTime() >= record.m_flStandingTime + 1.32f && std::fabsf(record.m_flLbyDelta) < 35.f)
					{
						record.m_flLbyDelta = record.m_flMovingLBY - player->m_flLowerBodyYawTarget();
						float_t new_yaw = player->m_flLowerBodyYawTarget() + record.m_flLbyDelta;
						new_yaw = Math::ClampYaw(new_yaw);

						player->m_angEyeAngles().yaw = new_yaw;

						record.m_bIsMoving = false;

						Global::resolverModes[player->EntIndex()] = "LBY delta < 35";

						continue;
					}
				}
			}
			else
			{
				float_t new_yaw = player->m_flLowerBodyYawTarget();
				new_yaw = Math::ClampYaw(new_yaw);

				player->m_angEyeAngles().yaw = new_yaw;

				Global::resolverModes[player->EntIndex()] = "Other";

				continue;
			}
		}
		if (player->m_flSimulationTime() >= record.m_flStandingTime + 0.22f && record.m_bIsMoving)
		{
			record.m_flLbyDelta = record.m_flLowerBodyYawTarget - player->m_flLowerBodyYawTarget();

			float_t new_yaw = player->m_flLowerBodyYawTarget() + record.m_flLbyDelta;
			new_yaw = Math::ClampYaw(new_yaw);

			player->m_angEyeAngles().yaw = new_yaw;

			record.m_bIsMoving = false;

			Global::resolverModes[player->EntIndex()] = "Breaking LBY (delta < 120)";

			continue;
		}
		if (player->m_flSimulationTime() >= record.m_flStandingTime + 1.32f && std::fabsf(record.m_flLbyDelta) < 35.f)
		{
			record.m_flLbyDelta = record.m_flMovingLBY - player->m_flLowerBodyYawTarget();
			float_t new_yaw = player->m_flLowerBodyYawTarget() + record.m_flLbyDelta;
			new_yaw = Math::ClampYaw(new_yaw);

			player->m_angEyeAngles().yaw = new_yaw;

			record.m_bIsMoving = false;

			Global::resolverModes[player->EntIndex()] = "LBY delta < 35";

			continue;
		}

		float_t new_yaw = player->m_flLowerBodyYawTarget() + record.m_flLbyDelta;
		new_yaw = Math::ClampYaw(new_yaw);

		player->m_angEyeAngles().yaw = new_yaw;
	}
}
Exemplo n.º 17
0
CGameEvent *CHLTVDirector::FindBestGameEvent()
{
	int	bestEvent[4];
	int	bestEventPrio[4];

	Q_memset( bestEvent, 0, sizeof(bestEvent) );
	Q_memset( bestEventPrio, 0, sizeof(bestEventPrio) );
	
	int index = FindFirstEvent( m_nBroadcastTick );
		
	// search for next 4 best events within next 8 seconds
	for (int i = 0; i<4; i ++)
	{
		bestEventPrio[i] = 0;
		bestEvent[i] = 0;
	
		int tillTick = m_nBroadcastTick + TIME_TO_TICKS( 2.0f*(1.0f+i) );

		if ( tillTick > m_nNextShotTick )
			break;

		// sum all action for the next time
		while ( index != m_EventHistory.InvalidIndex()  )
		{
			CGameEvent &event = m_EventHistory[index];

			if ( event.m_Tick > tillTick )
				break;

			int priority = event.m_Priority;

			if ( priority > bestEventPrio[i] )
			{
				bestEvent[i] = index;
				bestEventPrio[i] = priority;
			}
			
			index = m_EventHistory.NextInorder( index );
		}
	}

	if ( !( bestEventPrio[0] || bestEventPrio[1] || bestEventPrio[2] ) )
		return NULL; // no event found at all, give generic algorithm a chance

	// camera cut rules :

	if ( bestEventPrio[1] >= bestEventPrio[0] &&
		 bestEventPrio[1] >= bestEventPrio[2] &&
		 bestEventPrio[1] >= bestEventPrio[3] )
	{
		return &m_EventHistory[ bestEvent[1] ];	// best case
	}
	else if ( bestEventPrio[0] > bestEventPrio[1] &&
			  bestEventPrio[0] > bestEventPrio[2] )
	{
		return &m_EventHistory[ bestEvent[0] ];	// event 0 is very important
	}
	else if (	bestEventPrio[2] > bestEventPrio[3] ) 
	{
		return &m_EventHistory[ bestEvent[2] ];	
	}
	else
	{
		// event 4 is the best but too far away, so show event 1 
		if ( bestEvent[0] )
			return &m_EventHistory[ bestEvent[0] ];
		else
			return NULL;
	}
}
Exemplo n.º 18
0
void CHLTVDirector::StartNewShot()
{
	// we can remove all events the
	int smallestTick = MAX(0, gpGlobals->tickcount - TIME_TO_TICKS(HLTV_MAX_DELAY) );
    RemoveEventsFromHistory( smallestTick );

	if ( m_iCameraMan > 0 )
	{
		// we already have an active camera man,
		// wait until he releases the "record" lock
		FinishCameraManShot();
		return;	
	}

	if ( StartCameraManShot() )
	{
		// now we have an active camera man
		return;
	} 

    // ok, no camera man active, now check how much time
	// we have for the next shot, if the time diff to the next
	// important event we have to switch to is too short (<2sec)
	// just extent the current shot and don't start a new one

	// check the next 8 seconds for interrupts/important events
	m_nNextShotTick = m_nBroadcastTick + TIME_TO_TICKS( MAX_SHOT_LENGTH );

	if ( m_nBroadcastTick <= 0 )
	{
		// game hasn't started yet, we are still in the broadcast delay hole
		IGameEvent *msg = gameeventmanager->CreateEvent( "hltv_message", true );

		if ( msg )
		{
			msg->SetString("text", "Please wait for broadcast to start ..." );
			
			// send spectators the HLTV director command as a game event
			m_pHLTVServer->BroadcastEvent( msg );
			gameeventmanager->FreeEvent( msg );
		}

		StartBestFixedCameraShot( true );
		return;
	}

	int index = FindFirstEvent( m_nBroadcastTick );

	while( index != m_EventHistory.InvalidIndex() )
	{
		CGameEvent &dc = m_EventHistory[index];

		if ( dc.m_Tick >= m_nNextShotTick )
			break; // we have searched enough

		// a camera man is always interrupting auto director
		if ( Q_strcmp( dc.m_Event->GetName(), "hltv_cameraman") == 0 )
		{
			if ( dc.m_Event->GetInt("index") > 0 )
			{
				// stop the next cut when this cameraman starts recording
				m_nNextShotTick = dc.m_Tick;
				break;
			}
		}

		index = m_EventHistory.NextInorder( index );
	} 

	float flDuration = TICKS_TO_TIME(m_nNextShotTick - m_nBroadcastTick);

	if ( flDuration < MIN_SHOT_LENGTH )
		return;	// not enough time for a new shot

	// find the most intesting game event for next shot
	CGameEvent *dc = FindBestGameEvent();

	if ( dc )
	{
		// show the game event
		CreateShotFromEvent( dc );
	}
	else
	{
		// no interesting events found, start random shot
		StartRandomShot();
	}
}
Exemplo n.º 19
0
/*===================================
 *
 *  消息接收
 *===================================*/
void* acoral_msg_recv (acoral_msgctr_t* msgctr,
						acoral_u32  id,
						acoral_time  timeout,
						acoral_u32  *err)
{
	void             *dat;
	acoral_sr        cpu_sr;
	acoral_list_t    *p, *q;
	acoral_msg_t     *pmsg;
	acoral_thread_t  *cur;

	if (acoral_intr_nesting > 0)
	{
		*err = MST_ERR_INTR;
		return NULL;
	}
	if (NULL == msgctr)
	{
		*err = MST_ERR_NULL;
		return NULL;
	}

	cur = acoral_cur_thread;

	HAL_ENTER_CRITICAL();
	acoral_spin_lock(&msgctr->spin_lock);
	if(timeout>0){
		cur->delay = TIME_TO_TICKS(timeout);
		timeout_queue_add( cur);
	}
	while(1)
	{
		p = &msgctr->msglist;
		q = p->next;
		for( ;p != q; q = q->next)
		{
			pmsg = list_entry( q, acoral_msg_t, msglist);
			if ( (pmsg->id == id) && (pmsg->n > 0))
			{
				/*-----------------*/
				/* 有接收消息*/
				/*-----------------*/
				pmsg->n--;
				/*-----------------*/
				/* 延时列表删除*/
				/*-----------------*/
				timeout_queue_del(cur);
				dat = pmsg->data;
				acoral_list_del (q);
				acoral_release_res ((acoral_res_t *)pmsg);		
				msgctr->count--;
				acoral_spin_unlock(&msgctr->spin_lock);
				HAL_EXIT_CRITICAL();
				return dat;
			}
		}
	
		/*-----------------*/
		/*  没有接收消息*/
		/*-----------------*/
		msgctr->wait_thread_num++;
		acoral_msgctr_queue_add(msgctr, cur);
		acoral_unrdy_thread(cur);
		acoral_spin_unlock(&msgctr->spin_lock);
		HAL_EXIT_CRITICAL();
		acoral_sched();
		/*-----------------*/
		/*  看有没有超时*/
		/*-----------------*/
		HAL_ENTER_CRITICAL();
		acoral_spin_lock(&msgctr->spin_lock);
	
		if (timeout>0&&(acoral_32)cur->delay <=0 )
			break;

	}

	/*---------------*/
	/*  超时退出*/
	/*---------------*/
//	timeout_queue_del(cur);
	if(msgctr->wait_thread_num>0)
		msgctr->wait_thread_num--;
	acoral_list_del(&cur->waiting);
	acoral_spin_unlock(&msgctr->spin_lock);
	HAL_EXIT_CRITICAL();
	*err = MST_ERR_TIMEOUT;
	return NULL;

}
Exemplo n.º 20
0
void CHLTVDirector::CreateShotFromEvent( CGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	IGameEvent *shot = NULL;

	bool bPlayerHurt = Q_strcmp( "player_hurt", name ) == 0;
	bool bPlayerKilled = Q_strcmp( "player_death", name ) == 0;
	bool bRoundStart = Q_strcmp( "round_start", name ) == 0;
	bool bRoundEnd = Q_strcmp( "round_end", name ) == 0;

	if ( bPlayerHurt || bPlayerKilled )
	{
		CBaseEntity *victim = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );
		CBaseEntity *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") );

		if ( !victim )
			return;

		if ( attacker == victim || attacker == NULL )
		{
			// player killed self or by WORLD
			shot = gameeventmanager->CreateEvent( "hltv_chase", true );
			shot->SetInt( "target1", victim->entindex() );
			shot->SetInt( "target2", 0 );
			shot->SetInt( "theta", 0 );	// view from behind over head
			shot->SetInt( "phi", 20 );	// from above
			shot->SetFloat( "distance", 96.0f );
		}
		else // attacker != NULL
		{
			// check if we would show it from ineye view
			bool bInEye = (bPlayerKilled && RandomFloat(0,1) > 0.33) || (bPlayerHurt && RandomFloat(0,1) > 0.66); 

			// if we show ineye view, show it more likely from killer
			if ( RandomFloat(0,1) > (bInEye?0.3f:0.7f)  )
			{
				swap( attacker, victim );
			}
						
			// hurting a victim is shown as chase more often
			shot = gameeventmanager->CreateEvent( "hltv_chase", true );
			shot->SetInt( "target1", victim->entindex() );
			shot->SetInt( "target2", attacker->entindex() );

			// view from behind over head
			shot->SetInt( "phi", -20 ); // lower view point, dramatic
			shot->SetFloat( "distance", 96.0f );
			shot->SetInt( "ineye", bInEye?1:0 );
							
			// view over shoulder, randomly left or right
			if ( RandomFloat(0,1) > 0.5  )
			{
				shot->SetInt( "theta", 30 ); // swing left
			}
			else
			{
				shot->SetInt( "theta", -30 ); // swing right
			}
			
		}
				
		// shot 2 seconds after death/hurt
		m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = victim->entindex();
	}
	else if ( bRoundStart || bRoundEnd )
	{
		StartBestFixedCameraShot( false );
	}
	else
	{
		DevMsg( "No known TV shot for event %s\n", name );
	}


	if ( shot )
	{
		m_pHLTVServer->BroadcastEvent( shot );
		gameeventmanager->FreeEvent( shot );
	}
}
Exemplo n.º 21
0
void CCSHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	IGameEvent *shot = NULL;

	if ( !Q_strcmp( "hostage_rescued", name ) ||
		 !Q_strcmp( "hostage_hurt", name ) ||
		 !Q_strcmp( "hostage_follows", name ) ||
		 !Q_strcmp( "hostage_killed", name ) )
	{
		CBaseEntity *player = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );
		
		if ( !player )
			return;

		// shot player as primary, hostage as secondary target
		shot = gameeventmanager->CreateEvent( "hltv_chase", true );
		shot->SetInt( "target1", player->entindex() );
		shot->SetInt( "target2", event->m_Event->GetInt("hostage") );
		shot->SetFloat( "distance", 96.0f );
		shot->SetInt( "theta", 40 );
		shot->SetInt( "phi", 20 );

		// shot 2 seconds after event
		m_nNextShotTick = min( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = player->entindex();
	}

	else if ( !Q_strcmp( "bomb_pickup", name ) ||
		!Q_strcmp( "bomb_dropped", name ) ||
		!Q_strcmp( "bomb_planted", name ) ||
		!Q_strcmp( "bomb_defused", name ) )
	{
		CBaseEntity *player = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );

		if ( !player )
			return;

		shot = gameeventmanager->CreateEvent( "hltv_chase", true );
		shot->SetInt( "target1", player->entindex() );
		shot->SetInt( "target2", 0 );
		shot->SetFloat( "distance", 64.0f );
		shot->SetInt( "theta", 200 );
		shot->SetInt( "phi", 10 );

		// shot 2 seconds after pickup
		m_nNextShotTick = min( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = player->entindex();
	}
	else
	{
		// let baseclass create a shot
		BaseClass::CreateShotFromEvent( event );

		return;
	}

	if ( shot )
	{
		m_pHLTVServer->BroadcastEvent( shot );
		gameeventmanager->FreeEvent( shot );
		DevMsg("DrcCmd: %s\n", name );
	}
}