//-----------------------------------------------------------------------------
// Purpose: Creates a flame and attaches it to a target entity.
// Input  : pTarget - 
//-----------------------------------------------------------------------------
CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMaterialName, 
	float flStartTime, int nDissolveType, bool *pRagdollCreated )
{
	if ( pRagdollCreated )
	{
		*pRagdollCreated = false;
	}

	if ( !pMaterialName )
	{
		pMaterialName = DISSOLVE_SPRITE_NAME;
	}

	if ( pTarget->IsPlayer() )
	{
		// Simply immediately kill the player.
		CBasePlayer *pPlayer = assert_cast< CBasePlayer* >( pTarget );
		pPlayer->SetArmorValue( 0 );
		CTakeDamageInfo info( pPlayer, pPlayer, pPlayer->GetHealth(), DMG_GENERIC | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE );
		pPlayer->TakeDamage( info );
		return NULL;
	}

	CEntityDissolve *pDissolve = (CEntityDissolve *) CreateEntityByName( "env_entity_dissolver" );

	if ( pDissolve == NULL )
		return NULL;

	pDissolve->m_nDissolveType = nDissolveType;
	if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) )
	{
		if ( pTarget->IsNPC() && pTarget->MyNPCPointer()->CanBecomeRagdoll() )
		{
			CTakeDamageInfo info;
			CBaseEntity *pRagdoll = CreateServerRagdoll( pTarget->MyNPCPointer(), 0, info, COLLISION_GROUP_DEBRIS, true );
			pRagdoll->SetCollisionBounds( pTarget->CollisionProp()->OBBMins(), pTarget->CollisionProp()->OBBMaxs() );

			// Necessary to cause it to do the appropriate death cleanup
			if ( pTarget->m_lifeState == LIFE_ALIVE )
			{
				CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
				CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE );
				pTarget->TakeDamage( ragdollInfo );
			}

			if ( pRagdollCreated )
			{
				*pRagdollCreated = true;
			}

			UTIL_Remove( pTarget );
			pTarget = pRagdoll;
		}
	}

	pDissolve->SetModelName( AllocPooledString(pMaterialName) );
	pDissolve->AttachToEntity( pTarget );
	pDissolve->SetStartTime( flStartTime );
	pDissolve->Spawn();

	// Send to the client even though we don't have a model
	pDissolve->AddEFlags( EFL_FORCE_CHECK_TRANSMIT );

	// Play any appropriate noises when we start to dissolve
	if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) )
	{
		pTarget->DispatchResponse( "TLK_ELECTROCUTESCREAM" );
	}
	else
	{
		pTarget->DispatchResponse( "TLK_DISSOLVESCREAM" );
	}
	return pDissolve;
}
//-----------------------------------------------------------------------------
// Purpose: Input handler for showing the message and/or playing the sound.
//-----------------------------------------------------------------------------
void CEnvInstructorHint::InputShowHint( inputdata_t &inputdata )
{
	static int s_InstructorServerHintEventCreate = 0;
	IGameEvent * event = gameeventmanager->CreateEvent( "instructor_server_hint_create", false, &s_InstructorServerHintEventCreate );
	if ( event )
	{
		CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, m_iszHintTargetEntity );
		if( pTargetEntity == NULL && !m_bStatic )
			pTargetEntity = inputdata.pActivator;

		if( pTargetEntity == NULL )
			pTargetEntity = GetWorldEntity();

		char szColorString[128];
		Q_snprintf( szColorString, sizeof( szColorString ), "%.3d,%.3d,%.3d", m_Color.r, m_Color.g, m_Color.b );

		int iFlags = 0;
		
		iFlags |= (m_iPulseOption == 0) ? 0 : (LOCATOR_ICON_FX_PULSE_SLOW << (m_iPulseOption - 1));
		iFlags |= (m_iAlphaOption == 0) ? 0 : (LOCATOR_ICON_FX_ALPHA_SLOW << (m_iAlphaOption - 1));
		iFlags |= (m_iShakeOption == 0) ? 0 : (LOCATOR_ICON_FX_SHAKE_NARROW << (m_iShakeOption - 1));
		iFlags |= m_bStatic ? LOCATOR_ICON_FX_STATIC : 0;

		CBasePlayer *pActivator = NULL;
		bool bFilterByActivator = m_bLocalPlayerOnly;

#ifdef INFESTED_DLL
		CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>( inputdata.pActivator );
		if ( pMarine )
		{
			pActivator = pMarine->GetCommander();
		}
#else
		if ( inputdata.value.StringID() != NULL_STRING )
		{
			CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, inputdata.value.String() );
			pActivator = dynamic_cast<CBasePlayer*>( pTarget );
			if ( pActivator )
			{
				bFilterByActivator = true;
			}
		}
		else
		{
			if ( GameRules()->IsMultiplayer() == false )
			{
				pActivator = UTIL_GetLocalPlayer(); 
			}
			else
			{
				Warning( "Failed to play server side instructor hint: no player specified for hint\n" );
				Assert( 0 );
			}
		}
#endif

		const char *pActivatorCaption = m_iszActivatorCaption.ToCStr();
		if ( !pActivatorCaption || pActivatorCaption[ 0 ] == '\0' )
		{
			pActivatorCaption = m_iszCaption.ToCStr();
		}

		event->SetString( "hint_name", GetEntityName().ToCStr() );
		event->SetString( "hint_replace_key", m_iszReplace_Key.ToCStr() );
		event->SetInt( "hint_target", pTargetEntity->entindex() );
		event->SetInt( "hint_activator_userid", ( pActivator ? pActivator->GetUserID() : 0 ) );
		event->SetInt( "hint_timeout", m_iTimeout );
		event->SetString( "hint_icon_onscreen", m_iszIcon_Onscreen.ToCStr() );
		event->SetString( "hint_icon_offscreen", m_iszIcon_Offscreen.ToCStr() );
		event->SetString( "hint_caption", m_iszCaption.ToCStr() );
		event->SetString( "hint_activator_caption", pActivatorCaption );
		event->SetString( "hint_color", szColorString );
		event->SetFloat( "hint_icon_offset", m_fIconOffset );
		event->SetFloat( "hint_range", m_fRange );
		event->SetInt( "hint_flags", iFlags );
		event->SetString( "hint_binding", m_iszBinding.ToCStr() );
		event->SetBool( "hint_allow_nodraw_target", m_bAllowNoDrawTarget );
		event->SetBool( "hint_nooffscreen", m_bNoOffscreen );
		event->SetBool( "hint_forcecaption", m_bForceCaption );
		event->SetBool( "hint_local_player_only", bFilterByActivator );

		gameeventmanager->FireEvent( event );
	}
}
Beispiel #3
0
/* <1dfdff> ../cstrike/dlls/tutor.cpp:66 */
void MonitorTutorStatus()
{
	static cvar_t *tutor_enable = NULL;
	static bool tutor_enableCvarExists = true;

	bool shouldTutorBeOn = false;
	int numHumans = 0;

	if (!tutor_enableCvarExists || s_nextCvarCheckTime > gpGlobals->time)
	{
		return;
	}

	if (tutor_enable != NULL || (tutor_enable = CVAR_GET_POINTER("tutor_enable")) != NULL)
	{
		if (!s_tutorDisabledThisGame && tutor_enable->value > 0.0f)
		{
			shouldTutorBeOn = true;
		}
	}
	else
		tutor_enableCvarExists = false;

	for (int i = 1; i <= gpGlobals->maxClients; ++i)
	{
		CBasePlayer *pPlayer = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));

		if (pPlayer && !pPlayer->IsBot())
		{
			++numHumans;
		}
	}

	if (shouldTutorBeOn)
	{
		if (numHumans <= 1)
		{
			if (TheTutor == NULL)
			{
				CBasePlayer *localPlayer = UTIL_GetLocalPlayer();

				if (localPlayer != NULL)
				{
					ClientPrint(localPlayer->pev, HUD_PRINTCENTER, "#CZero_Tutor_Turned_On");
				}

				TheTutor = new CCSTutor;
			}
		}
		else
			s_tutorDisabledThisGame = true;
	}
	else
	{
		if (TheTutor != NULL)
		{
			CBasePlayer *localPlayer = UTIL_GetLocalPlayer();

			if (localPlayer != NULL)
			{
				ClientPrint(localPlayer->pev, HUD_PRINTCENTER, "#CZero_Tutor_Turned_Off");
			}

			delete TheTutor;
			TheTutor = NULL;
		}
	}

	s_nextCvarCheckTime = gpGlobals->time + 1.0f;
}
bool ShouldRemoveThisRagdoll( CBaseAnimating *pRagdoll )
{
	if ( g_RagdollLVManager.IsLowViolence() )
	{
		return true;
	}

#ifdef CLIENT_DLL

	/* we no longer ignore enemies just because they are on fire -- a ragdoll in front of me
	   is always a higher priority for retention than a flaming zombie behind me. At the 
	   time I put this in, the ragdolls do clean up their own effects if culled via SUB_Remove().
	   If you're encountering trouble with ragdolls leaving effects behind, try renabling the code below.
    /////////////////////
	//Just ignore it until we're done burning/dissolving.
	if ( pRagdoll->GetEffectEntity() )
		return false;
	*/

	Vector vMins, vMaxs;
		
	Vector origin = pRagdoll->m_pRagdoll->GetRagdollOrigin();
	pRagdoll->m_pRagdoll->GetRagdollBounds( vMins, vMaxs );

	if( engine->IsBoxInViewCluster( vMins + origin, vMaxs + origin) == false )
	{
		if ( g_debug_ragdoll_removal.GetBool() )
		{
			debugoverlay->AddBoxOverlay( origin, vMins, vMaxs, QAngle( 0, 0, 0 ), 0, 255, 0, 16, 5 );
			debugoverlay->AddLineOverlay( origin, origin + Vector( 0, 0, 64 ), 0, 255, 0, true, 5 );
		}

		return true;
	}
	else if( engine->CullBox( vMins + origin, vMaxs + origin ) == true )
	{
		if ( g_debug_ragdoll_removal.GetBool() )
		{
			debugoverlay->AddBoxOverlay( origin, vMins, vMaxs, QAngle( 0, 0, 0 ), 0, 0, 255, 16, 5 );
			debugoverlay->AddLineOverlay( origin, origin + Vector( 0, 0, 64 ), 0, 0, 255, true, 5 );
		}

		return true;
	}

#else
	CBasePlayer *pPlayer = UTIL_GetLocalPlayer();

	if( !UTIL_FindClientInPVS( pRagdoll->edict() ) )
	{
		if ( g_debug_ragdoll_removal.GetBool() )
			 NDebugOverlay::Line( pRagdoll->GetAbsOrigin(), pRagdoll->GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 255, 0, true, 5 );

		return true;
	}
	else if( !pPlayer->FInViewCone( pRagdoll ) )
	{
		if ( g_debug_ragdoll_removal.GetBool() )
			 NDebugOverlay::Line( pRagdoll->GetAbsOrigin(), pRagdoll->GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, 255, true, 5 );
		
		return true;
	}

#endif

	return false;
}
	void CSingleplayRules::NPCKilled(CBaseEntity *pVictim, const CTakeDamageInfo &info)
	{
		CBasePlayer *pEntity = UTIL_GetLocalPlayer();
		if (pVictim->m_isRareEntity)
		{
			switch (GetSkillLevel())
			{
			case SKILL_EASY:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier1.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier1.GetInt());
				}
				break;

			case SKILL_MEDIUM:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier2.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier2.GetInt());
				}
				break;

			case SKILL_HARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier3.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier3.GetInt());
				}
				break;

			case SKILL_VERYHARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier4.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier4.GetInt());
				}
				break;

			case SKILL_NIGHTMARE:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier5.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier5.GetInt());
				}
				break;
			}
		}
		else
		{
			switch (GetSkillLevel())
			{
			case SKILL_EASY:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier1.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier1.GetInt());
				}
				break;

			case SKILL_MEDIUM:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier2.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier2.GetInt());
				}
				break;

			case SKILL_HARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier3.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier3.GetInt());
				}
				break;

			case SKILL_VERYHARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier4.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier4.GetInt());
				}
				break;

			case SKILL_NIGHTMARE:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier5.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier5.GetInt());
				}
				break;
			}
		}
		pEntity->IncrementFragCount(1);

#define KILLING_SPREE_AMOUNT	5
#define KILLING_FRENZY_AMOUNT	10
#define OVERKILL_AMOUNT	15
#define RAMPAGE_AMOUNT	20
#define UNSTOPPABLE_AMOUNT	25
#define INCONCEIVABLE_AMOUNT	30
#define INVINCIBLE_AMOUNT	35
#define GODLIKE_AMOUNT	40

		if (info.GetInflictor() == pEntity)
		{
			if (sv_player_voice.GetBool())
			{
				if (sv_player_voice_kill.GetBool())
				{
					int killvoicerandom = random->RandomInt(0, sv_player_voice_kill_freq.GetInt());
					if (killvoicerandom == 0)
					{
						pEntity->EmitSound("Player.VoiceKill");
					}
				}
			}
		}

		if (sv_killingspree.GetBool())
		{
			int m_iKillsInSpree = pEntity->FragCount();

			if (m_iKillsInSpree == KILLING_SPREE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_KILLINGSPREE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3);
				}
			}
			if (m_iKillsInSpree == KILLING_FRENZY_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_KILLINGFRENZY");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(4);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(6);
				}
			}
			if (m_iKillsInSpree == OVERKILL_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_OVERKILL");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(6);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(9);
				}
			}
			if (m_iKillsInSpree == RAMPAGE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_RAMPAGE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(8);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(12);
				}
			}
			if (m_iKillsInSpree == UNSTOPPABLE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_UNSTOPPABLE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(10);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(15);
				}
			}
			if (m_iKillsInSpree == INCONCEIVABLE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_INCONCEIVABLE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(12);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(18);
				}
			}
			if (m_iKillsInSpree == INVINCIBLE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_INVINCIBLE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(14);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(21);
				}
			}
			if (m_iKillsInSpree == GODLIKE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_GODLIKE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(16);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(24);
				}
			}
		}

		if (pVictim->m_isRareEntity)
		{
			if (g_fr_classic.GetBool())
			{
				pEntity->LevelUpClassic();
			}
		}
	}
Beispiel #6
0
void CMapzoneEdit::Update()
{
    if (mom_zone_edit.GetBool())
    {
        if (!m_bEditing)
        {
            m_nBuildStage = BUILDSTAGE_NONE;
            m_bEditing = true;
        }
    }
    else
    {
        if (m_bEditing)
        {
            m_nBuildStage = BUILDSTAGE_NONE;
            m_bEditing = false;
        }

        return;
    }

    CBasePlayer *pPlayer = UTIL_GetLocalPlayer();

    if (!pPlayer) return;


    trace_t tr;
    Vector vecFwd;

    AngleVectors(pPlayer->EyeAngles(), &vecFwd);

    UTIL_TraceLine(pPlayer->EyePosition(), pPlayer->EyePosition() + vecFwd * m_flReticleDist, MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr);

    Vector vecAim = tr.endpos;

    if (mom_zone_grid.GetInt() > 0)
        VectorSnapToGrid(&vecAim, (float) mom_zone_grid.GetInt());


    if (m_nBuildStage >= BUILDSTAGE_START)
    {
        Vector vecP2, vecP3, vecP4;

        if (m_nBuildStage >= BUILDSTAGE_END)
        {
            vecP3 = m_vecBuildEnd;
        }
        else
        {
            vecP3 = vecAim;
        }

        vecP3[2] = m_vecBuildStart[2];

        // Bottom
        vecP2[0] = m_vecBuildStart[0];
        vecP2[1] = vecP3[1];
        vecP2[2] = m_vecBuildStart[2];

        vecP4[0] = vecP3[0];
        vecP4[1] = m_vecBuildStart[1];
        vecP4[2] = m_vecBuildStart[2];

        DebugDrawLine(m_vecBuildStart, vecP2, 255, 255, 255, true, -1.0f);
        DebugDrawLine(vecP2, vecP3, 255, 255, 255, true, -1.0f);
        DebugDrawLine(vecP3, vecP4, 255, 255, 255, true, -1.0f);
        DebugDrawLine(vecP4, m_vecBuildStart, 255, 255, 255, true, -1.0f);

        if (m_nBuildStage >= BUILDSTAGE_END)
        {
            Vector vecP5, vecP6, vecP8;

            m_vecBuildEnd[2] = SnapToGrid(m_vecBuildStart[2] + GetZoneHeightToPlayer(pPlayer), (float) mom_zone_grid.GetInt());

            // Top
            vecP5 = m_vecBuildStart;
            vecP5.z = m_vecBuildEnd[2];

            vecP6 = vecP2;
            vecP6.z = m_vecBuildEnd[2];

            vecP8 = vecP4;
            vecP8.z = m_vecBuildEnd[2];

            DebugDrawLine(vecP5, vecP6, 255, 255, 255, true, -1.0f);
            DebugDrawLine(vecP6, m_vecBuildEnd, 255, 255, 255, true, -1.0f);
            DebugDrawLine(m_vecBuildEnd, vecP8, 255, 255, 255, true, -1.0f);
            DebugDrawLine(vecP8, vecP5, 255, 255, 255, true, -1.0f);

            // Bottom to top
            DebugDrawLine(m_vecBuildStart, vecP5, 255, 255, 255, true, -1.0f);
            DebugDrawLine(vecP2, vecP6, 255, 255, 255, true, -1.0f);
            DebugDrawLine(vecP3, m_vecBuildEnd, 255, 255, 255, true, -1.0f);
            DebugDrawLine(vecP4, vecP8, 255, 255, 255, true, -1.0f);
        }
    }

    // Draw surface normal. Makes it a bit easier to see where reticle is hitting.
    if (tr.DidHit())
    {
        DebugDrawLine(vecAim, vecAim + tr.plane.normal * 24.0f, 0, 0, 255, true, -1.0f);
    }

    DrawReticle(&vecAim, (mom_zone_grid.GetInt() > 0) ? ((float) mom_zone_grid.GetInt() / 2.0f) : 8.0f);
}
//---------------------------------------------------------
// Returns distance to the nearest BaseCombatCharacter.
//---------------------------------------------------------
float CBounceBomb::FindNearestNPC()
{
	float flNearest = (BOUNCEBOMB_WARN_RADIUS * BOUNCEBOMB_WARN_RADIUS) + 1.0;

	// Assume this search won't find anyone.
	SetNearestNPC( NULL );

	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 ];

		if( pNPC->IsAlive() )
		{
			// ignore hidden objects
			if ( pNPC->IsEffectActive( EF_NODRAW ) )
				continue;

			// Don't bother with NPC's that are below me.
			if( pNPC->EyePosition().z < GetAbsOrigin().z )
				continue;

			// Disregard things that want to be disregarded
			if( pNPC->Classify() == CLASS_NONE )
				continue; 

			// Disregard bullseyes
			if( pNPC->Classify() == CLASS_BULLSEYE )
				continue;

			// Disregard turrets
			if( pNPC->m_iClassname == gm_iszFloorTurretClassname || pNPC->m_iClassname == gm_iszGroundTurretClassname )
				continue;


			float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();

			if( flDist < flNearest )
			{
				// Now do a visibility test.
				if( FVisible( pNPC, MASK_SOLID_BRUSHONLY ) )
				{
					flNearest = flDist;
					SetNearestNPC( pNPC );
				}
			}
		}
	}

	// finally, check the player.
	CBasePlayer *pPlayer = UTIL_GetLocalPlayer();

	if( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) )
	{
		float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr();

		if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) )
		{
			flNearest = flDist;
			SetNearestNPC( pPlayer );
		}
	}

	if( m_hNearestNPC.Get() )
	{
		// If sprite is active, update its color to reflect who is nearest.
		if( IsFriend( m_hNearestNPC ) )
		{
			if( m_bFoeNearest )
			{
				// Changing state to where a friend is nearest.

				if( IsFriend( m_hNearestNPC ) )
				{
					// Friend
					UpdateLight( true, 0, 255, 0, 190 );
					m_bFoeNearest = false;
				}
			}
		}
		else // it's a foe
		{
			if( !m_bFoeNearest )
			{
				// Changing state to where a foe is nearest.
				UpdateLight( true, 255, 0, 0, 190 );
				m_bFoeNearest = true;
			}
		}
	}

	return sqrt( flNearest );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, const impactdamagetable_t &table, float energyScale, bool allowStaticDamage, int &damageType, bool bDamageFromHeldObjects )
{
	damageType = DMG_CRUSH;
	int otherIndex = !index;

	// UNDONE: Expose a flag for self-inflicted damage?  Can't think of a valid case so far.
	if ( pEvent->pEntities[0] == pEvent->pEntities[1] )
		return 0;

	if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_NO_NPC_IMPACT_DMG )
	{
		if( pEvent->pEntities[index]->IsNPC() || pEvent->pEntities[index]->IsPlayer() )
		{
			return 0;
		}
	}

	// use implicit velocities on ragdolls since they may have high constraint velocities that aren't actually executed, just pushed through contacts
	if (( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PART_OF_RAGDOLL) && pEvent->pEntities[index]->IsPlayer() )
	{
		pEvent->pObjects[otherIndex]->GetImplicitVelocity( &pEvent->preVelocity[otherIndex], &pEvent->preAngularVelocity[otherIndex] );
	}

	// Dissolving impact damage results in death always.
	if ( ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_DMG_DISSOLVE ) && 
			!pEvent->pEntities[index]->IsEFlagSet(EFL_NO_DISSOLVE) )
	{
		damageType |= DMG_DISSOLVE;
		return 1000;
	}

	if ( energyScale <= 0.0f )
		return 0;

	const int gameFlagsNoDamage = FVPHYSICS_CONSTRAINT_STATIC | FVPHYSICS_NO_IMPACT_DMG;

	// NOTE: Crushing damage is handled by stress calcs in vphysics update functions, this is ONLY impact damage
	// this is a non-moving object due to a constraint - no damage
	if ( pEvent->pObjects[otherIndex]->GetGameFlags() & gameFlagsNoDamage )
		return 0;

	// If it doesn't take damage from held objects and the object is being held - no damage
	if ( !bDamageFromHeldObjects && ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) )
	{
		// If it doesn't take damage from held objects - no damage
		if ( !bDamageFromHeldObjects )
			return 0;
	}

	if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_MULTIOBJECT_ENTITY )
	{
		// UNDONE: Add up mass here for car wheels and prop_ragdoll pieces?
		IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
		int count = pEvent->pEntities[otherIndex]->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) );
		for ( int i = 0; i < count; i++ )
		{
			if ( pList[i]->GetGameFlags() & gameFlagsNoDamage )
				return 0;
		}
	}

	if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
	{
		// players can't damage held objects
		if ( pEvent->pEntities[otherIndex]->IsPlayer() )
			return 0;

		allowStaticDamage = false;
	}

#if 0
	{
		PhysGetDamageInflictorVelocityStartOfFrame( pEvent->pObjects[otherIndex], pEvent->preVelocity[otherIndex], pEvent->preAngularVelocity[otherIndex] );
	}
#endif

	float otherSpeedSqr = pEvent->preVelocity[otherIndex].LengthSqr();
	float otherAngSqr = 0;
	
	// factor in angular for sharp objects
	if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_DMG_SLICE )
	{
		otherAngSqr = pEvent->preAngularVelocity[otherIndex].LengthSqr();
	}

	float otherMass = pEvent->pObjects[otherIndex]->GetMass();

	if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
	{
		// if the player is holding the object, use its real mass (player holding reduced the mass)
		
		CBasePlayer *pPlayer = NULL;

		if ( gpGlobals->maxClients == 1 )
		{
			pPlayer = UTIL_GetLocalPlayer();
		}
		else
		{
			// See which MP player is holding the physics object and then use that player to get the real mass of the object.
			// This is ugly but better than having linkage between an object and its "holding" player.
			for ( int i = 1; i <= gpGlobals->maxClients; i++ )
			{
				CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i );
				if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() )
				{
					pPlayer = tempPlayer;
					break;
				}
			}
		}

		if ( pPlayer )
		{
			otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] );
		}
	}

	// NOTE: sum the mass of each object in this system for the purpose of damage
	if ( pEvent->pEntities[otherIndex] && (pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_MULTIOBJECT_ENTITY) )
	{
		otherMass = PhysGetEntityMass( pEvent->pEntities[otherIndex] );
	}
	
	if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_HEAVY_OBJECT )
	{
		otherMass = table.largeMassMin;
		if ( energyScale < 2.0f )
		{
			energyScale = 2.0f;
		}
	}

	// UNDONE: allowStaticDamage is a hack - work out some method for 
	// breakable props to impact the world and break!!
	if ( !allowStaticDamage )
	{
		if ( otherMass < table.minMass )
			return 0;
		// check to see if the object is small
		if ( otherMass < table.smallMassMax && otherSpeedSqr < table.smallMassMinSpeedSqr )
			return 0;
		
		if ( otherSpeedSqr < table.minSpeedSqr && otherAngSqr < table.minRotSpeedSqr )
			return 0;
	}

	// Add extra oomph for floating objects
	if ( pEvent->pEntities[index]->IsFloating() && !pEvent->pEntities[otherIndex]->IsWorld() )
	{
		if ( energyScale < 3.0f )
		{
			energyScale = 3.0f;
		}
	}

	float damage = 0;
	bool bDebug = false;//(&table == &gDefaultPlayerImpactDamageTable);

	// don't ever take spin damage from slowly spinning objects
	if ( otherAngSqr > table.minRotSpeedSqr )
	{
		Vector otherInertia = pEvent->pObjects[otherIndex]->GetInertia();
		float angularMom = DotProductAbs( otherInertia, pEvent->preAngularVelocity[otherIndex] );
		damage = ReadDamageTable( table.angularTable, table.angularCount, angularMom * energyScale, bDebug );
		if ( damage > 0 )
		{
//			Msg("Spin : %.1f, Damage %.0f\n", FastSqrt(angularMom), damage );
			damageType |= DMG_SLASH;
		}
	}
	
	float deltaV = pEvent->preVelocity[index].Length() - pEvent->postVelocity[index].Length();
	float mass = pEvent->pObjects[index]->GetMass();

	// If I lost speed, and I lost less than min velocity, then filter out this energy
	if ( deltaV > 0 && deltaV < table.myMinVelocity )
	{
		deltaV = 0;
	}
	float eliminatedEnergy = deltaV * deltaV * mass;

	deltaV = pEvent->preVelocity[otherIndex].Length() - pEvent->postVelocity[otherIndex].Length();
	float otherEliminatedEnergy = deltaV * deltaV * otherMass;
	
	// exaggerate the effects of really large objects
	if ( otherMass >= table.largeMassMin )
	{
		otherEliminatedEnergy *= table.largeMassScale;
		float dz = pEvent->preVelocity[otherIndex].z - pEvent->postVelocity[otherIndex].z;

		if ( deltaV > 0 && dz < 0 && pEvent->preVelocity[otherIndex].z < 0 )
		{
			float factor = fabs(dz / deltaV);
			otherEliminatedEnergy *= (1 + factor * (table.largeMassFallingScale - 1.0f));
		}
	}

	eliminatedEnergy += otherEliminatedEnergy;

	// now in units of this character's speed squared
	float invMass = pEvent->pObjects[index]->GetInvMass();
	if ( !pEvent->pObjects[index]->IsMoveable() )
	{
		// inv mass is zero, but impact damage is enabled on this
		// prop, so recompute:
		invMass = 1.0f / pEvent->pObjects[index]->GetMass();
	}
	else if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
	{
		// if the player is holding the object, use it's real mass (player holding reduced the mass)

		CBasePlayer *pPlayer = NULL;
		if ( gpGlobals->maxClients == 1 )
		{
			pPlayer = UTIL_GetLocalPlayer();
		}
		else
		{
			// See which MP player is holding the physics object and then use that player to get the real mass of the object.
			// This is ugly but better than having linkage between an object and its "holding" player.
			for ( int i = 1; i <= gpGlobals->maxClients; i++ )
			{
				CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i );
				if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() )
				{
					pPlayer = tempPlayer;
					break;
				}
			}
		}

		if ( pPlayer )
		{
			float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] );
			if ( mass > 0 )
			{
				invMass = 1.0f / mass;
			}
		}
	}

	eliminatedEnergy *= invMass * energyScale;
	
	damage += ReadDamageTable( table.linearTable, table.linearCount, eliminatedEnergy, bDebug );

	if ( !pEvent->pObjects[otherIndex]->IsStatic() && otherMass < table.smallMassMax && table.smallMassCap > 0 )
	{
		damage = clamp( damage, 0.f, table.smallMassCap );
	}

	return damage;
}
void QUA_helicopter::Think(void)
{
	if (!m_bSpawn) {
	CBasePlayer	*pPlayer = UTIL_GetLocalPlayer();
	
	/*if ( m_bEngineLocked )
	{
		m_bUnableToFire = true;
		
		if ( pPlayer != NULL )
		{
			pPlayer->m_Local.m_iHideHUD |= HIDEHUD_VEHICLE_CROSSHAIR;
		}
	}
	else
	{*/
		// Start this as false and update it again each frame
		//m_bUnableToFire = false;

		if ( pPlayer != NULL )
		{
			pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_VEHICLE_CROSSHAIR;
		}
	//}

	SetNextThink( gpGlobals->curtime );

	

	//StudioFrameAdvance();

	if(m_fReloadTime<=gpGlobals->curtime && m_iAmmoCount<40) {
		m_iAmmoCount++;
		m_fReloadTime=gpGlobals->curtime+0.5f;
	}
	if(m_fCannonCharge<=gpGlobals->curtime && m_iCannonCount<100) {
		m_iCannonCount++;
		m_fCannonCharge=gpGlobals->curtime+0.02f;
	}
	if ( m_hPlayer )
	{
		/*engine->Con_NPrintf( 10, " " );
		engine->Con_NPrintf( 11, "PILOTABLE VEHICLE HELICOPTER" );
		engine->Con_NPrintf( 12, " " );
		engine->Con_NPrintf( 13, "Cursors : Movement" );
		engine->Con_NPrintf( 14, "Duck : Down" );
		engine->Con_NPrintf( 15, "Jump : up" );
		engine->Con_NPrintf( 16, "Attack 1 : Machine Gun" );
	*/	Vector vecEyeDir, vecEyePos;
		m_hPlayer->EyePositionAndVectors( &vecEyePos, &vecEyeDir, NULL, NULL );

		// Trace out from the player's eye point.
		Vector	vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH );
		trace_t	trace;
		UTIL_TraceLine( vecEyePos, vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &trace );

		// See if we hit something, if so, adjust end position to hit location.
		if ( trace.fraction < 1.0 )
		{
   			vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH * trace.fraction );
		}

		//m_vecLookCrosshair = vecEndPos;
		m_vecGunCrosshair=vecEndPos;
		//AimPrimaryWeapon( vecEndPos );
	}
	PostThink();
	SetNextThink( gpGlobals->curtime);
	}
}
//-----------------------------------------------------------------------------
// Purpose: Finds an entity given a procedural name.
// Input  : szName - The procedural name to search for, should start with '!'.
//			pSearchingEntity - 
//			pActivator - The activator entity if this was called from an input
//				or Use handler.
//-----------------------------------------------------------------------------
CBaseEntity *CGlobalEntityList::FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller )
{
	//
	// Check for the name escape character.
	//
	if ( szName[0] == '!' )
	{
		const char *pName = szName + 1;

		//
		// It is a procedural name, look for the ones we understand.
		//
		if ( FStrEq( pName, "player" ) )
		{
		#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
			return (CBaseEntity *)UTIL_GetLocalPlayer(); 
		#else
			return (CBaseEntity *)UTIL_PlayerByIndex( 1 );
		#endif //SecobMod__Enable_Fixed_Multiplayer_AI
		}
		else if ( FStrEq( pName, "pvsplayer" ) )
		{
			if ( pSearchingEntity )
			{
				return CBaseEntity::Instance( UTIL_FindClientInPVS( pSearchingEntity->edict() ) );
			}
			else if ( pActivator )
			{
				// FIXME: error condition?
				return CBaseEntity::Instance( UTIL_FindClientInPVS( pActivator->edict() ) );
			}
			else
			{
				// FIXME: error condition?
			#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
				return (CBaseEntity *)UTIL_GetLocalPlayer(); 
			#else
				return (CBaseEntity *)UTIL_PlayerByIndex( 1 );
			#endif //SecobMod__Enable_Fixed_Multiplayer_AI
			}

		}
		else if ( FStrEq( pName, "activator" ) )
		{
			return pActivator;
		}
		else if ( FStrEq( pName, "caller" ) )
		{
			return pCaller;
		}
		else if ( FStrEq( pName, "picker" ) )
		{
		#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
			return FindPickerEntity( UTIL_GetLocalPlayer() ); 
		#else
			return FindPickerEntity( UTIL_PlayerByIndex(1) );
		#endif //SecobMod__Enable_Fixed_Multiplayer_AI
		}
		else if ( FStrEq( pName, "self" ) )
		{
			return pSearchingEntity;
		}
		else 
		{
			Warning( "Invalid entity search name %s\n", szName );
			Assert(0);
		}
	}

	return NULL;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAI_AllyManager::CountAllies( int *pTotal, int *pMedics )
{
	(*pTotal) = (*pMedics) = 0;

	#ifdef SecobMod__Enable_Fixed_Multiplayer_AI //should be ifndef?
		//Do nothing here.
	#else
		if ( !AI_IsSinglePlayer() ) 
		{
			// @TODO (toml 10-22-04): no MP support right now
			return;
		}

		const Vector &	vPlayerPos = UTIL_GetLocalPlayer()->GetAbsOrigin();
	#endif //SecobMod__Enable_Fixed_Multiplayer_AI

	const Vector &	vPlayerPos = UTIL_GetLocalPlayer()->GetAbsOrigin();
	CAI_BaseNPC **	ppAIs 	= g_AI_Manager.AccessAIs();
	int 			nAIs 	= g_AI_Manager.NumAIs();

	for ( int i = 0; i < nAIs; i++ )
	{
		if ( ppAIs[i]->IsAlive() && ppAIs[i]->IsPlayerAlly() )
		{
			// Vital allies do not count.
			if( ppAIs[i]->Classify() == CLASS_PLAYER_ALLY_VITAL )
				continue;

			// They only count if I can use them.
			if( ppAIs[i]->HasSpawnFlags(SF_CITIZEN_NOT_COMMANDABLE) )
				continue;
			
			// They only count if I can use them.
			#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
				if( ppAIs[i]->IRelationType( UTIL_GetNearestPlayer(ppAIs[i]->GetAbsOrigin()) ) != D_LI )
				continue;
			#else
				if( ppAIs[i]->IRelationType( UTIL_GetLocalPlayer() ) != D_LI )
				continue;
			#endif //SecobMod__Enable_Fixed_Multiplayer_AI	

			// Skip distant NPCs
			#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
				Vector vNearestPlayerPos = UTIL_GetNearestPlayer(ppAIs[i]->GetAbsOrigin())->GetAbsOrigin();
				if ( !ppAIs[i]->IsInPlayerSquad() && 
					!UTIL_FindClientInPVS( ppAIs[i]->edict() ) && 
					( ( ppAIs[i]->GetAbsOrigin() - vNearestPlayerPos ).LengthSqr() > 150*12 ||
				  	fabsf( ppAIs[i]->GetAbsOrigin().z - vNearestPlayerPos.z ) > 192 ) )
				continue;
			#else
				if ( !ppAIs[i]->IsInPlayerSquad() && 
				!UTIL_FindClientInPVS( ppAIs[i]->edict() ) && 
				( ( ppAIs[i]->GetAbsOrigin() - vPlayerPos ).LengthSqr() > 150*12 ||
				  fabsf( ppAIs[i]->GetAbsOrigin().z - vPlayerPos.z ) > 192 ) )
				continue;
			#endif //SecobMod__Enable_Fixed_Multiplayer_AI

			if( FClassnameIs( ppAIs[i], "npc_citizen" ) ) 
			{  
				CNPC_Citizen *pCitizen = assert_cast<CNPC_Citizen *>(ppAIs[i]);
				if ( !pCitizen->CanJoinPlayerSquad() )
					continue;

				if ( pCitizen->WasInPlayerSquad() && !pCitizen->IsInPlayerSquad() )
					continue;

				if ( ppAIs[i]->HasSpawnFlags( SF_CITIZEN_MEDIC ) )
					(*pMedics)++;
			}

			(*pTotal)++;
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: Allows the turret to fire on targets if they're visible
//-----------------------------------------------------------------------------
void CNPC_RocketTurret::FollowThink( void )
{
	// Default to player as enemy
	if ( GetEnemy() == NULL )
	{
		SetEnemy( UTIL_GetLocalPlayer() );
	}

	SetSequence ( LookupSequence( "idle" ) );
	//Allow descended classes a chance to do something before the think function
	if ( PreThink() || GetEnemy() == NULL )
	{
		return;
	}
	//Update our think time
	SetNextThink( gpGlobals->curtime + ROCKET_TURRET_THINK_RATE );

	UpdateAimPoint();

	m_vecGoalAngles = m_vecAnglesToEnemy;

	// Chase enemy
	if ( !m_bHasSightOfEnemy )
	{
		// Aim at the last known location
		m_vecGoalAngles = m_vecCurrentAngles;

		// Lost sight, move to search think
		SetThink( &CNPC_RocketTurret::SearchThink );
	}

	//Turn to face
	UpdateFacing();

	// If our facing direction hits our enemy, fire the beam
	Ray_t rayDmg;
	Vector vForward;
	AngleVectors( m_vecCurrentAngles, &vForward, NULL, NULL );
	Vector vEndPoint = EyePosition() + vForward*ROCKET_TURRET_RANGE;
	rayDmg.Init( EyePosition(), vEndPoint );
	rayDmg.m_IsRay = true;
	trace_t traceDmg;

	// This version reorients through portals
	CTraceFilterSimple subfilter( this, COLLISION_GROUP_NONE );
	CTraceFilterTranslateClones filter ( &subfilter );
	float flRequiredParameter = 2.0f;
	CProp_Portal* pFirstPortal = UTIL_Portal_FirstAlongRay( rayDmg, flRequiredParameter );
	UTIL_Portal_TraceRay_Bullets( pFirstPortal, rayDmg, MASK_VISIBLE_AND_NPCS, &filter, &traceDmg, false );

	if ( traceDmg.m_pEnt )
	{
		// This thing we're hurting is our enemy
		if ( traceDmg.m_pEnt == GetEnemy() )
		{
			// If we're past the cooldown time, fire another rocket
			if ( (gpGlobals->curtime - m_flTimeLastFired) > ROCKET_TURRET_ROCKET_FIRE_COOLDOWN_TIME )
			{
				SetThink( &CNPC_RocketTurret::LockingThink );
			}
		}
	}
}
void CNPC_RocketTurret::Activate( void )
{
	m_filterBeams.SetPassEntity( this );
	m_filterBeams.SetPassEntity2( UTIL_GetLocalPlayer() );
	BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &data - 
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::InputCalculateType( inputdata_t &data )
{{
	#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
		// spawn gear for the nearest player 
		CBasePlayer *pNearest = UTIL_GetNearestPlayer(GetAbsOrigin()); 
		if ( pNearest != NULL ) 
			SpawnDynamicItem( pNearest ); 
	#else
		CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
		SpawnDynamicItem( pPlayer );
	#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &data - 
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::InputBecomeMaster( inputdata_t &data )
{
	if ( g_MasterResupply )
		g_MasterResupply->m_bIsMaster = false;

	g_MasterResupply = this;
	m_bIsMaster = true;

	// Stop thinking now that I am the master.
	SetThink( NULL );
}


//-----------------------------------------------------------------------------
// Chooses an item when the player is full
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::SpawnFullItem( CItem_DynamicResupply *pMaster, CBasePlayer *pPlayer, int iDebug )
{
	// Can we not actually spawn the item?
	if ( !HasSpawnFlags(SF_DYNAMICRESUPPLY_ALWAYS_SPAWN) )
		return;

	float flRatio[NUM_AMMO_ITEMS];
	int i;
	float flTotalProb = 0.0f;
	for ( i = 0; i < NUM_AMMO_ITEMS; ++i )
	{
		int iAmmoType = GetAmmoDef()->Index( g_DynamicResupplyAmmoItems[i].sAmmoDef );
		bool bCanSpawn = pPlayer->Weapon_GetWpnForAmmo( iAmmoType ) != NULL;

		if ( bCanSpawn && ( g_DynamicResupplyAmmoItems[i].flFullProbability != 0 ) && ( pMaster->m_flDesiredAmmo[i] != 0.0f ) )
		{
			flTotalProb += g_DynamicResupplyAmmoItems[i].flFullProbability;
			flRatio[i] = flTotalProb;
		}
		else
		{
			flRatio[i] = -1.0f;
		}
	}

	if ( flTotalProb == 0.0f )
	{
		// If we're supposed to fallback to just a health vial, do that and finish.
		if ( pMaster->HasSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL) )
		{
			CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles(), this );

			if ( iDebug )
			{
				Msg("Player is full, spawning item_healthvial due to spawnflag.\n");
			}
			return;
		}

		// Otherwise, spawn the first ammo item in the list
		flRatio[0] = 1.0f;
		flTotalProb = 1.0f;
	}
	
	float flChoice = random->RandomFloat( 0.0f, flTotalProb ); 
	for ( i = 0; i < NUM_AMMO_ITEMS; ++i )
	{
		if ( flChoice <= flRatio[i] )
		{
			CBaseEntity::Create( g_DynamicResupplyAmmoItems[i].sEntityName, GetAbsOrigin(), GetAbsAngles(), this );

			if ( iDebug )
			{
				Msg("Player is full, spawning %s \n", g_DynamicResupplyAmmoItems[i].sEntityName );
			}
			return;
		}
	}

	if ( iDebug )
	{
		Msg("Player is full on all health + ammo, is not spawning.\n" );
	}
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::FindPotentialItems( int nCount, DynamicResupplyItems_t *pItems, int iDebug, SpawnInfo_t *pSpawnInfo )
{
	int i;
	for ( i = 0; i < nCount; ++i )
	{
		pSpawnInfo[i].m_iPotentialItems = 0;
	}

	// Count the potential addition of items in the PVS
	CBaseEntity *pEntity = NULL;
	while ( (pEntity = UTIL_EntitiesInPVS( this, pEntity )) != NULL )
	{
		if ( pEntity->WorldSpaceCenter().DistToSqr( WorldSpaceCenter() ) > (POTENTIAL_ITEM_RADIUS * POTENTIAL_ITEM_RADIUS) )
			continue;

		for ( i = 0; i < nCount; ++i )
		{
			if ( !FClassnameIs( pEntity, pItems[i].sEntityName ) )
				continue;

			if ( iDebug == 2 )
			{
				NDebugOverlay::Line( WorldSpaceCenter(), pEntity->WorldSpaceCenter(), 0,255,0, true, 20.0 );
			}

			++pSpawnInfo[i].m_iPotentialItems;
			break;
		}
	}

	if ( iDebug )
	{
		Msg("Searching the PVS:\n");
		for ( int i = 0; i < nCount; i++ )
		{
			Msg("   Found %d '%s' in the PVS.\n", pSpawnInfo[i].m_iPotentialItems, pItems[i].sEntityName );
		}
	}
}
Beispiel #15
0
	//	pBeam->SetEndWidth( 0.05f );

	// Higher brightness means less transparent
	pBeam->SetBrightness(255);
	pBeam->SetColor(255, 185 + random->RandomInt(-16, 16), 40);
	pBeam->RelinkBeam();

	// The beam should only exist for a very short time
	pBeam->LiveForTime(0.1f);
}

void CWeaponMomentumGun::DoImpactEffect(trace_t &tr, int nDamageType)
{
	//Draw our beam
	DrawBeam(tr.startpos, tr.endpos, 15.5);
	if ((tr.surface.flags & SURF_SKY) == false)
	{
		CPVSFilter filter(tr.endpos);
		te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0);
		//m_nBulletType = GetAmmoDef()->Index("GaussEnergy");
		//UTIL_ImpactTrace(&tr, m_nBulletType);
	}
}

CON_COMMAND(holster_weapon, "Holster test.") {
	CBasePlayer* pPlayer = UTIL_GetLocalPlayer();
	if (pPlayer) {
		CBaseCombatWeapon* active = pPlayer->GetActiveWeapon();
		active->SetWeaponVisible(!active->IsWeaponVisible());
	}
}
/* <1ef79d> ../cstrike/dlls/career_tasks.cpp:385 */
void CCareerTask::__MAKE_VHOOK(OnEvent)(GameEventType event, CBasePlayer *pVictim, CBasePlayer *pAttacker)
{
	if (m_isComplete)
		return;

	if (event == m_event)
	{
		if ((m_defuser && !pAttacker->m_bIsDefusing) || (m_vip && !pAttacker->m_bIsVIP))
			return;

		if (m_rescuer)
		{
			int hostages_ = 0;
			CBaseEntity *hostageEntity = NULL;

			while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL)
			{
				if (hostageEntity->pev->takedamage != DAMAGE_YES)
					continue;

				CHostage *hostage = static_cast<CHostage *>(hostageEntity);

				if (!hostage->IsFollowingSomeone())
					continue;

				if (hostage->IsValid() && hostage->m_target == pAttacker)
					++hostages_;
			}

			if (!hostages_)
			{
				return;
			}
		}

		if (m_event != EVENT_KILL || (!m_weaponId && !m_weaponClassId)
			&& m_event != EVENT_HEADSHOT || (!m_weaponId && !m_weaponClassId)
			&& m_event != EVENT_PLAYER_TOOK_DAMAGE || (!m_weaponId && !m_weaponClassId))
		{
			if (m_event == EVENT_ROUND_WIN)
			{
				if (!Q_strcmp(m_name, "defendhostages"))
				{
					int hostages_ = 0;
					CBaseEntity *hostageEntity = NULL;

					while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL)
					{
						if (hostageEntity->pev->takedamage != 1.0f && hostageEntity->pev->deadflag != DEAD_DEAD)
							++hostages_;
					}

					if (!hostages_)
					{
						++m_eventsSeen;
						SendPartialNotification();
					}
				}
				else if (!Q_strcmp(m_name, "hostagessurvive"))
				{
					int hostages_ = 0;
					CBaseEntity *hostageEntity = NULL;

					while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL)
					{
						CHostage *hostage = (CHostage *)hostageEntity;

						if (hostage && hostage->IsDead())
							++hostages_;
					}

					if (!hostages_)
					{
						++m_eventsSeen;
						SendPartialNotification();
					}
				}
				else if (!Q_strcmp(m_name, "winfast"))
				{
					if (m_eventsNeeded >= TheCareerTasks->GetRoundElapsedTime())
					{
						m_eventsSeen = m_eventsNeeded;
						SendPartialNotification();
					}
				}
				else if (IsTaskCompletableThisRound())
				{
					++m_eventsSeen;
					SendPartialNotification();
				}
			}
			else
			{
				++m_eventsSeen;
				SendPartialNotification();
			}
		}
	}

	if (event == m_event && !m_mustLive && m_eventsSeen >= m_eventsNeeded && IsTaskCompletableThisRound())
	{
		CBasePlayer *player = UTIL_GetLocalPlayer();
		EMIT_SOUND(ENT(player->pev), CHAN_VOICE, "events/task_complete.wav", VOL_NORM, ATTN_NORM);

		m_isComplete = true;
		MESSAGE_BEGIN(MSG_ALL, gmsgCZCareer);
			WRITE_STRING("TASKDONE");
			WRITE_BYTE(m_id);
		MESSAGE_END();

		if (TheTutor != NULL)
		{
			TheTutor->OnEvent(EVENT_CAREER_TASK_DONE);
		}

		UTIL_LogPrintf("Career Task Done %d\n", m_id);

		if (m_event == EVENT_ROUND_WIN && !Q_strcmp(m_name, "winfast"))
		{
			TheCareerTasks->SetFinishedTaskTime((int)TheCareerTasks->GetRoundElapsedTime());
			UTIL_GetLocalPlayer()->SyncRoundTimer();
		}
	}
	else if (event >= EVENT_ROUND_DRAW)
	{
		if (event > EVENT_ROUND_LOSS)
		{
			if (event == EVENT_DIE && (m_mustLive || m_crossRounds))
			{
				m_eventsSeen = 0;
				SendPartialNotification();
				m_diedThisRound = true;
			}
		}
		else if (m_mustLive)
		{
			if (m_eventsSeen >= m_eventsNeeded && !m_diedThisRound && IsTaskCompletableThisRound())
			{
				CBasePlayer *player = UTIL_GetLocalPlayer();
				EMIT_SOUND(ENT(player->pev), CHAN_VOICE, "events/task_complete.wav", VOL_NORM, ATTN_NORM);

				m_isComplete = true;
				MESSAGE_BEGIN(MSG_ALL, gmsgCZCareer);
					WRITE_STRING("TASKDONE");
					WRITE_BYTE(m_id);
				MESSAGE_END();

				UTIL_LogPrintf("Career Task Done %d\n", m_id);

				if (m_event == EVENT_ROUND_WIN && !Q_strcmp(m_name, "winfast"))
				{
					TheCareerTasks->SetFinishedTaskTime((int)TheCareerTasks->GetRoundElapsedTime());
					UTIL_GetLocalPlayer()->SyncRoundTimer();
				}

				if (TheTutor != NULL)
				{
					TheTutor->OnEvent(EVENT_CAREER_TASK_DONE);
				}
			}

			m_diedThisRound = false;

			if (m_mustLive)
			{
				m_eventsSeen = 0;
				SendPartialNotification();
			}
		}
	}
}
//---------------------------------------------------------
// Count of all the weapons in the world of my type and
// see if we have a surplus. If there is a surplus, try
// to find suitable candidates for removal.
//
// Right now we just remove the first weapons we find that
// are behind the player, or are out of the player's PVS.
// Later, we may want to score the results so that we
// removed the farthest gun that's not in the player's
// viewcone, etc.
//
// Some notes and thoughts:
//
// This code is designed NOT to remove weapons that are
// hand-placed by level designers. It should only clean
// up weapons dropped by dead NPCs, which is useful in
// situations where enemies are spawned in for a sustained
// period of time.
//
// Right now we PREFER to remove weapons that are not in the
// player's PVS, but this could be opposite of what we
// really want. We may only want to conduct the cleanup on
// weapons that are IN the player's PVS.
//---------------------------------------------------------
void CGameWeaponManager::Think()
{
    int i;

    // Don't have to think all that often.
    SetNextThink( gpGlobals->curtime + 2.0 );

    const char *pszWeaponName = STRING( m_iszWeaponName );

    CUtlVector<CBaseEntity *> candidates( 0, 64 );

    if ( m_bExpectingWeapon )
    {
        CBaseCombatWeapon *pWeapon = NULL;
        // Firstly, count the total number of weapons of this type in the world.
        // Also count how many of those can potentially be removed.
        pWeapon = assert_cast<CBaseCombatWeapon *>(gEntList.FindEntityByClassname( pWeapon, pszWeaponName ));

        while( pWeapon )
        {
            if( !pWeapon->IsEffectActive( EF_NODRAW ) && pWeapon->IsRemoveable() )
            {
                candidates.AddToTail( pWeapon );
            }

            pWeapon = assert_cast<CBaseCombatWeapon *>(gEntList.FindEntityByClassname( pWeapon, pszWeaponName ));
        }
    }
    else
    {
        for ( i = 0; i < m_ManagedNonWeapons.Count(); i++)
        {
            CBaseEntity *pEntity = m_ManagedNonWeapons[i];
            if ( pEntity )
            {
                Assert( pEntity->m_iClassname == m_iszWeaponName );
                if ( !pEntity->IsEffectActive( EF_NODRAW ) )
                {
                    candidates.AddToTail( pEntity );
                }
            }
            else
            {
                m_ManagedNonWeapons.FastRemove( i-- );
            }
        }
    }

    // Calculate the surplus.
    int surplus = candidates.Count() - m_iMaxPieces;

    // Based on what the player can see, try to clean up the world by removing weapons that
    // the player cannot see right at the moment.
    CBaseEntity *pCandidate;
    for ( i = 0; i < candidates.Count() && surplus > 0; i++ )
    {
        bool fRemovedOne = false;

        pCandidate = candidates[i];
        Assert( !pCandidate->IsEffectActive( EF_NODRAW ) );

        if ( gpGlobals->maxClients == 1 )
        {
            CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
            // Nodraw serves as a flag that this weapon is already being removed since
            // all we're really doing inside this loop is marking them for removal by
            // the entity system. We don't want to count the same weapon as removed
            // more than once.
            if( !UTIL_FindClientInPVS( pCandidate->edict() ) )
            {
                fRemovedOne = true;
            }
            else if( !pPlayer->FInViewCone( pCandidate ) )
            {
                fRemovedOne = true;
            }
            else if ( UTIL_DistApprox( pPlayer->GetAbsOrigin(), pCandidate->GetAbsOrigin() ) > (30*12) )
            {
                fRemovedOne = true;
            }
        }
        else
        {
            fRemovedOne = true;
        }

        if( fRemovedOne )
        {
            pCandidate->AddEffects( EF_NODRAW );
            UTIL_Remove( pCandidate );

            DevMsg( 2, "Surplus %s removed\n", pszWeaponName);
            surplus--;
        }
    }
}
void CNPC_Hydra::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{
	case TASK_HYDRA_DEPLOY:
		{
			m_flHeadGoalInfluence = 1.0;
			float dist = (EyePosition() - m_vecHeadGoal).Length();

			if (dist < m_idealSegmentLength)
			{
				TaskComplete();
			}

			AimHeadInTravelDirection( 0.2 );
		}
		break;

	case TASK_HYDRA_PREP_STAB:
		{
			int i;

			if (m_body.Count() < 2)
			{
				TaskFail( "hydra is too short to begin stab" );
				return;
			}

			CBaseEntity *pTarget = GetTarget();
			if (pTarget == NULL)
			{
				TaskFail( FAIL_NO_TARGET );
			}

			if (pTarget->IsPlayer())
			{
				m_vecTarget = pTarget->EyePosition( );
			}
			else
			{
				m_vecTarget = pTarget->BodyTarget( EyePosition( ) );
			}

			float distToTarget = (m_vecTarget - m_vecHeadGoal).Length();
			float distToBase = (m_vecHeadGoal - GetAbsOrigin()).Length();
			m_idealLength = distToTarget + distToBase * 0.5;

			if (m_idealLength > HYDRA_MAX_LENGTH)
				m_idealLength = HYDRA_MAX_LENGTH;

			if (distToTarget < 100.0)
			{
				m_vecTargetDir = (m_vecTarget - m_vecHeadGoal);
				VectorNormalize( m_vecTargetDir );
				m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (100 - distToTarget) * 0.5;
			}
			else if (distToTarget > 200.0)
			{
				m_vecTargetDir = (m_vecTarget - m_vecHeadGoal);
				VectorNormalize( m_vecTargetDir );
				m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (200.0 - distToTarget) * 0.5;
			}

			// face enemy
			m_vecTargetDir = (m_vecTarget - m_body[m_body.Count()-1].vecPos);
			VectorNormalize( m_vecTargetDir );
			m_vecHeadDir = m_vecHeadDir * 0.6 + m_vecTargetDir * 0.4;
			VectorNormalize( m_vecHeadDir.GetForModify() );

			// build tension towards strike time
			float influence = 1.0 - (m_flTaskEndTime - gpGlobals->curtime) / pTask->flTaskData;
			if (influence > 1)
				influence = 1.0;

			influence = influence * influence * influence;

			m_flHeadGoalInfluence = influence;

			// keep head segment straight
			i = m_body.Count() - 2;
			m_body[i].vecGoalPos = m_vecHeadGoal - m_vecHeadDir * m_body[i].flActualLength;
			m_body[i].flGoalInfluence = influence;

			// curve neck into spiral
			float distBackFromHead = m_body[i].flActualLength;
			Vector right, up;
			VectorVectors( m_vecHeadDir, right, up );

			for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--)
			{
				distBackFromHead += m_body[i].flActualLength;

				float r = (distBackFromHead / 200) * 3.1415 * 2;

				// spiral
				Vector p0 = m_vecHeadGoal 
							- m_vecHeadDir * distBackFromHead * 0.5 
							+ cos( r ) * m_body[i].flActualLength * right 
							+ sin( r ) * m_body[i].flActualLength * up;

				// base
				r = (distBackFromHead / m_idealLength) * 3.1415 * 0.2;
				r = sin( r );
				p0 = p0 * (1 - r) + r * GetAbsOrigin();

				m_body[i].vecGoalPos = p0;

				m_body[i].flGoalInfluence = influence * (1.0 - (distBackFromHead / distToTarget));

				/*
				if ( (pEnemy->EyePosition( ) - m_body[i].vecPos).Length() < distBackFromHead)
				{
					if ( gpGlobals->curtime - m_flLastAttackTime > 4.0)
					{
						TaskComplete();
					}
					return;
				}
				*/
			}

			// look to see if any of the goal positions are stuck
			for (i = i; i < m_body.Count() - 1; i++)
			{
				if (m_body[i].bStuck)
				{
					Vector delta = DotProduct( m_body[i].vecGoalPos - m_body[i].vecPos, m_vecHeadDir) * m_vecHeadDir;
					m_vecHeadGoal -= delta * m_body[i].flGoalInfluence;
					break;
				}
			}

			if ( gpGlobals->curtime >= m_flTaskEndTime )
			{
				if (distToTarget < 500)
				{
					TaskComplete( );
					return;
				}
				else
				{
					TaskFail( "target is too far away" );
					return;
				}
			}
		}
		return;

	case TASK_HYDRA_STAB:
		{
			int i;

			if (m_body.Count() < 2)
			{
				TaskFail( "hydra is too short to begin stab" );
				return;
			}

			if (m_flTaskEndTime <= gpGlobals->curtime)
			{
				TaskComplete( );
				return;
			}

			m_flHeadGoalInfluence = 1.0;

			// face enemy
			//m_vecHeadDir = (pEnemy->EyePosition( ) - m_body[m_body.Count()-1].vecPos);
			//VectorNormalize( m_vecHeadDir.GetForModify() );

			// keep head segment straight
			i = m_body.Count() - 2;
			m_body[i].vecGoalPos = m_vecHeadGoal + m_vecHeadDir * m_body[i].flActualLength;
			m_body[i].flGoalInfluence = 1.0;

			Vector vecToTarget = (m_vecTarget - EyePosition( ));

			// check to see if we went past target
			if (DotProduct( vecToTarget, m_vecHeadDir ) < 0.0)
			{
				TaskComplete( );
				return;
			}

			float distToTarget = vecToTarget.Length();
			float distToBase = (EyePosition( ) - GetAbsOrigin()).Length();
			m_idealLength = distToTarget + distToBase;

			/*
			if (distToTarget < 20)
			{
				m_vecHeadGoal = m_vecTarget;
				SetLastAttackTime( gpGlobals->curtime );
				TaskComplete();
				return;
			}
			else
			*/
			{
				// hit enemy
				m_vecHeadGoal = m_vecTarget + m_vecHeadDir * 300;
			}

			if (m_idealLength > HYDRA_MAX_LENGTH)
				m_idealLength = HYDRA_MAX_LENGTH;

			// curve neck into spiral
			float distBackFromHead = m_body[i].flActualLength;
			Vector right, up;
			VectorVectors( m_vecHeadDir, right, up );

#if 1
			for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--)
			{
				Vector p0 = m_vecHeadGoal - m_vecHeadDir * distBackFromHead * 1.0; 

				m_body[i].vecGoalPos = p0;

				if ((m_vecTarget - m_body[i].vecPos).Length() > distToTarget + distBackFromHead)
				{
					m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget);
				}
				else
				{
					m_body[i].vecGoalPos = EyePosition( ) - m_vecHeadDir * distBackFromHead;
					m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget);
				}

				distBackFromHead += m_body[i].flActualLength;
			}
#endif
		}
		return;

	case TASK_HYDRA_PULLBACK:
		{
			if (m_body.Count() < 2)
			{
				TaskFail( "hydra is too short to begin stab" );
				return;
			}
			CBaseEntity *pEnemy = (CBaseEntity *)UTIL_GetLocalPlayer();
			if (GetEnemy() != NULL)
			{
				pEnemy = GetEnemy();
			}

			AimHeadInTravelDirection( 0.2 );

			// float dist = (EyePosition() - m_vecHeadGoal).Length();

			if (m_flCurrentLength < m_idealLength + m_idealSegmentLength)
			{
				TaskComplete();
			}
		}
		break;

	default:
		BaseClass::RunTask( pTask );
		break;
	}

}
Beispiel #19
0
// CONSIDER: if player in water state, autoset and underwater soundscape? 
void CEnvSoundscape::Update()
{
	UpdatePlayersInPVS();

	if ( !IsEnabled() )
		return;

	for ( int i=0; i < m_hPlayersInPVS.Count(); i++ )
	{
		CBasePlayer *pPlayer = m_hPlayersInPVS[i];
		if ( !pPlayer )
			continue;

		if ( !InRangeOfPlayer( pPlayer ) )
			continue;

		// check to see if this is the sound entity that is 
		// currently affecting this player
		audioparams_t &audio = pPlayer->GetAudioParams();

		// if we got this far, we're looking at an entity that is contending
		// for current player sound. the closest entity to player wins.
		CEnvSoundscape *pCurrent = (CEnvSoundscape *)audio.ent.Get();
		if ( !pCurrent || 
			!pCurrent->IsEnabled() || 
			!pCurrent->InRangeOfPlayer( pPlayer ) ) 
		{
			// The old one is obscured or out of range.. take over.
			WriteAudioParamsTo( audio );
		}
		else if ( pCurrent && 
			EarPosition().DistTo( pPlayer->EarPosition() ) < pCurrent->EarPosition().DistTo( pPlayer->EarPosition() ) )
		{
			// new entity is closer to player, so it wins.
			WriteAudioParamsTo( audio );
		}
	} 

	if ( soundscape_debug.GetBool() )
	{
		CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
 		if ( pPlayer )
		{
			audioparams_t &audio = pPlayer->GetAudioParams();
			if ( audio.ent.Get() != this )
			{
				if ( InRangeOfPlayer( pPlayer ) )
				{
					NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 255, 255,255, true, 0.1 );
				}
				else
				{
					NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 255, 0,0, true, 0.1 );
				}
			}
			else
			{
				if ( InRangeOfPlayer( pPlayer ) )
				{
					NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 0, 255,0, true, 0.1 );
				}
  				else
				{
					NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 255, 170,0, true, 0.1 );
				}
			}
		}
	}
}
Beispiel #20
0
void CC_Mom_ZoneMark(const CCommand &args)
{
    if (!mom_zone_edit.GetBool()) return;

    CBasePlayer *pPlayer = UTIL_GetLocalPlayer();

    if (!pPlayer) return;


    int zonetype = -1;

    if (g_MapzoneEdit.GetBuildStage() >= BUILDSTAGE_END)
    {
        if (args.ArgC() > 1)
        {
            zonetype = g_MapzoneEdit.ShortNameToZoneType(args[1]);
        }
        else
        {
            zonetype = g_MapzoneEdit.ShortNameToZoneType(mom_zone_defzone.GetString());
        }

        if (zonetype == MOMZONETYPE_START || zonetype == MOMZONETYPE_STOP)
        {
            // Count zones to make sure we don't create multiple instances.
            int startnum = 0;
            int endnum = 0;

            CBaseEntity *pEnt;

            pEnt = gEntList.FindEntityByClassname(NULL, "trigger_momentum_timer_start");
            while (pEnt)
            {
                startnum++;
                pEnt = gEntList.FindEntityByClassname(pEnt, "trigger_momentum_timer_start");
            }

            pEnt = gEntList.FindEntityByClassname(NULL, "trigger_momentum_timer_stop");
            while (pEnt)
            {
                endnum++;
                pEnt = gEntList.FindEntityByClassname(pEnt, "trigger_momentum_timer_stop");
            }

            DevMsg("Found %i starts and %i ends (previous)\n", startnum, endnum);

            if (!mom_zone_ignorewarning.GetBool() && startnum && endnum)
            {
                g_MapzoneEdit.SetBuildStage(BUILDSTAGE_NONE);

                ConMsg("Map already has a start and an end! Use mom_zone_defzone to set another type.\n");

                return;
            }

            //The user is trying to make multiple starts?
            if (zonetype == MOMZONETYPE_START)
            {
                 // Switch between start and end.
                 zonetype = (startnum <= endnum) ? MOMZONETYPE_START : MOMZONETYPE_STOP;
            }
            //else the zonetype can be STOP, allowing for multiple stop triggers to be created
        }
    }

    trace_t tr;
    Vector vecFwd;

    AngleVectors(pPlayer->EyeAngles(), &vecFwd);

    UTIL_TraceLine(pPlayer->EyePosition(), pPlayer->EyePosition() + vecFwd * g_MapzoneEdit.GetZoom(), MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr);


    g_MapzoneEdit.Build(&tr.endpos, zonetype);
}
void CHL1NPCTalker::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
		case TASK_HL1TALKER_FOLLOW_WALK_PATH_FOR_UNITS:
			{
				float distance;

				distance = (m_vecLastPosition - GetLocalOrigin()).Length2D();

				// Walk path until far enough away
				if ( distance > pTask->flTaskData || 
					 GetNavigator()->GetGoalType() == GOALTYPE_NONE )
				{
					TaskComplete();
					GetNavigator()->ClearGoal();		// Stop moving
				}
				break;
			}



		case TASK_TALKER_CLIENT_STARE:
		case TASK_TALKER_LOOK_AT_CLIENT:
		{
			CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
			
			// track head to the client for a while.
			if ( m_NPCState == NPC_STATE_IDLE		&& 
				 !IsMoving()								&&
				 !GetExpresser()->IsSpeaking() )
			{
			
				if ( pPlayer )
				{
					IdleHeadTurn( pPlayer );
				}
			}
			else
			{
				// started moving or talking
				TaskFail( "moved away" );
				return;
			}

			if ( pTask->iTask == TASK_TALKER_CLIENT_STARE )
			{
				// fail out if the player looks away or moves away.
				if ( ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() > TALKER_STARE_DIST )
				{
					// player moved away.
					TaskFail( NO_TASK_FAILURE );
				}

				Vector vForward;
				AngleVectors( GetAbsAngles(), &vForward );
				if ( UTIL_DotPoints( pPlayer->GetAbsOrigin(), GetAbsOrigin(), vForward ) < m_flFieldOfView )
				{
					// player looked away
					TaskFail( "looked away" );
				}
			}

			if ( gpGlobals->curtime > m_flWaitFinished )
			{
				TaskComplete( NO_TASK_FAILURE );
			}

			break;
		}

		case TASK_WAIT_FOR_MOVEMENT:
		{
			if ( GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL)
			{
				// ALERT(at_console, "walking, talking\n");
				IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime );
			}
			else if ( GetEnemy() )
			{
				IdleHeadTurn( GetEnemy() );
			}

			BaseClass::RunTask( pTask );

			break;
		}

		case TASK_FACE_PLAYER:
		{
			CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
			
			if ( pPlayer )
			{
				//GetMotor()->SetIdealYaw( pPlayer->GetAbsOrigin() );
				IdleHeadTurn( pPlayer );
				if ( gpGlobals->curtime > m_flWaitFinished && GetMotor()->DeltaIdealYaw() < 10 )
				{
					TaskComplete();
				}
			}
			else
			{
				TaskFail( FAIL_NO_PLAYER );
			}

			break;
		}

		case TASK_TALKER_EYECONTACT:
		{
			if (!IsMoving() && GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL)
			{
				// ALERT( at_console, "waiting %f\n", m_flStopTalkTime - gpGlobals->time );
				IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime );
			}
			
			BaseClass::RunTask( pTask );
			
			break;

		}

				
		default:
		{
			if ( GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL)
			{
				IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime );
			}
			else if ( GetEnemy() && m_NPCState == NPC_STATE_COMBAT )
			{
				IdleHeadTurn( GetEnemy() );
			}
			else if ( GetFollowTarget() )
			{
				IdleHeadTurn( GetFollowTarget() );
			}

			BaseClass::RunTask( pTask );
			break;
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPCEventResponseSystem::FrameUpdatePreEntityThink()
{
 	if ( !m_ActiveEvents.Count() || !AI_IsSinglePlayer() || !UTIL_GetLocalPlayer() )
		return;

	if ( m_flNextEventPoll > gpGlobals->curtime )
		return;
	m_flNextEventPoll = gpGlobals->curtime + 0.2;

	// Move through all events, removing expired ones and finding NPCs for active ones.
	for ( int i = m_ActiveEvents.First(); i != m_ActiveEvents.InvalidIndex(); )
	{	
 		float flTime = m_ActiveEvents[i].flEventTime;
		const char *pResponse = m_ActiveEvents.GetElementName(i);

		// Save off the next index so we can safely remove this one
		int iNext = m_ActiveEvents.Next(i); 

		// Should it have expired by now?
		if ( !m_ActiveEvents[i].bPreventExpiration && (flTime + NPCEVENTRESPONSE_GIVEUP_TIME) < gpGlobals->curtime )
		{
			if ( ai_debug_eventresponses.GetBool() ) 
			{
				Msg( "NPCEVENTRESPONSE: (%.2f) Removing expired event named: %s\n", gpGlobals->curtime, pResponse );
			}

			m_ActiveEvents.RemoveAt(i);
		}
		else if ( m_ActiveEvents[i].flNextResponseTime < gpGlobals->curtime )
		{
			// If we've fired once, and our current event should expire now, then expire.
			if ( m_ActiveEvents[i].bPreventExpiration && (flTime + NPCEVENTRESPONSE_GIVEUP_TIME) < gpGlobals->curtime )
			{
				if ( ai_debug_eventresponses.GetBool() ) 
				{
					Msg( "NPCEVENTRESPONSE: (%.2f) Removing expired fired event named: %s\n", gpGlobals->curtime, pResponse );
				}

				m_ActiveEvents.RemoveAt(i);
			}
			else
			{
				float flNearestDist = NPCEVENTRESPONSE_DISTANCE_SQR;
				CAI_BaseNPC *pNearestNPC = NULL;
				Vector vecPlayerCenter = UTIL_GetLocalPlayer()->WorldSpaceCenter();

				// Try and find the nearest NPC to the player
				CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
				for ( int j = 0; j < g_AI_Manager.NumAIs(); j++ )
				{
					if ( ppAIs[j]->CanRespondToEvent( pResponse ))
					{
						float flDistToPlayer = ( vecPlayerCenter - ppAIs[j]->WorldSpaceCenter()).LengthSqr();
						if ( flDistToPlayer < flNearestDist )
						{
							flNearestDist = flDistToPlayer;
							pNearestNPC = ppAIs[j];
						}
					}
				}

				// Found one? 
				if ( pNearestNPC )
				{
					if ( pNearestNPC->RespondedTo( pResponse, m_ActiveEvents[i].bForce, m_ActiveEvents[i].bCancelScript ) )
					{
						// Don't remove the response yet. Leave it around until the refire time has expired.
						// This stops repeated firings of the same concept from spamming the NPCs.
						m_ActiveEvents[i].bPreventExpiration = true;
						m_ActiveEvents[i].flNextResponseTime = gpGlobals->curtime + NPCEVENTRESPONSE_REFIRE_TIME;

						if ( ai_debug_eventresponses.GetBool() ) 
						{
							Msg( "NPCEVENTRESPONSE: (%.2f) Event '%s' responded to by NPC '%s'. Refire available at: %.2f\n", gpGlobals->curtime, pResponse, pNearestNPC->GetDebugName(), m_ActiveEvents[i].flNextResponseTime );
						}

						// Don't issue multiple responses at once
						return;
					}
				}
			}
		}

		i = iNext;
	}
}
CNPCSpawnDestination *CTemplateNPCMaker::FindSpawnDestination()
{
	CNPCSpawnDestination *pDestinations[ MAX_DESTINATION_ENTS ];
	CBaseEntity *pEnt = NULL;
	CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
	int	count = 0;

	if( !pPlayer )
	{
		return NULL;
	}

	// Collect all the qualifiying destination ents
	pEnt = gEntList.FindEntityByName( NULL, m_iszDestinationGroup );

	if( !pEnt )
	{
		DevWarning("Template NPC Spawner (%s) doesn't have any spawn destinations!\n", GetDebugName() );
		return NULL;
	}
	
	while( pEnt )
	{
		CNPCSpawnDestination *pDestination;

		pDestination = dynamic_cast <CNPCSpawnDestination*>(pEnt);

		if( pDestination && pDestination->IsAvailable() )
		{
			bool fValid = true;
			Vector vecTest = pDestination->GetAbsOrigin();

			if( m_CriterionVisibility != TS_YN_DONT_CARE )
			{
				// Right now View Cone check is omitted intentionally.
				Vector vecTopOfHull = NAI_Hull::Maxs( HULL_HUMAN );
				vecTopOfHull.x = 0;
				vecTopOfHull.y = 0;
				bool fVisible = (pPlayer->FVisible( vecTest ) || pPlayer->FVisible( vecTest + vecTopOfHull ) );

				if( m_CriterionVisibility == TS_YN_YES )
				{
					if( !fVisible )
						fValid = false;
				}
				else
				{
					if( fVisible )
					{
						if ( !(pPlayer->GetFlags() & FL_NOTARGET) )
							fValid = false;
						else
							DevMsg( 2, "Spawner %s spawning even though seen due to notarget\n", STRING( GetEntityName() ) );
					}
				}
			}

			if( fValid )
			{
				pDestinations[ count ] = pDestination;
				count++;
			}
		}

		pEnt = gEntList.FindEntityByName( pEnt, m_iszDestinationGroup );
	}

	if( count < 1 )
		return NULL;

	// Now find the nearest/farthest based on distance criterion
	if( m_CriterionDistance == TS_DIST_DONT_CARE )
	{
		// Pretty lame way to pick randomly. Try a few times to find a random
		// location where a hull can fit. Don't try too many times due to performance
		// concerns.
		for( int i = 0 ; i < 5 ; i++ )
		{
			CNPCSpawnDestination *pRandomDest = pDestinations[ rand() % count ];

			if( HumanHullFits( pRandomDest->GetAbsOrigin() ) )
			{
				return pRandomDest;
			}
		}

		return NULL;
	}
	else
	{
		if( m_CriterionDistance == TS_DIST_NEAREST )
		{
			float flNearest = FLT_MAX;
			CNPCSpawnDestination *pNearest = NULL;

			for( int i = 0 ; i < count ; i++ )
			{
				Vector vecTest = pDestinations[ i ]->GetAbsOrigin();
				float flDist = ( vecTest - pPlayer->GetAbsOrigin() ).Length();

				if ( m_iMinSpawnDistance != 0 && m_iMinSpawnDistance > flDist )
					continue;

				if( flDist < flNearest && HumanHullFits( vecTest ) )
				{
					flNearest = flDist;
					pNearest = pDestinations[ i ];
				}
			}

			return pNearest;
		}
		else
		{
			float flFarthest = 0;
			CNPCSpawnDestination *pFarthest = NULL;

			for( int i = 0 ; i < count ; i++ )
			{
				Vector vecTest = pDestinations[ i ]->GetAbsOrigin();
				float flDist = ( vecTest - pPlayer->GetAbsOrigin() ).Length();

				if ( m_iMinSpawnDistance != 0 && m_iMinSpawnDistance > flDist )
					continue;

				if( flDist > flFarthest && HumanHullFits( vecTest ) )
				{
					flFarthest = flDist;
					pFarthest = pDestinations[ i ];
				}
			}

			return pFarthest;
		}
	}

	return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &data - 
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::InputCalculateType( inputdata_t &data )
{
	CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
	SpawnDynamicItem( pPlayer );
}
Beispiel #25
0
// CONSIDER: if player in water state, autoset and underwater soundscape? 
void CEnvSoundscape::UpdateForPlayer( ss_update_t &update )
{
	if ( !IsEnabled() )
	{
		if ( update.pCurrentSoundscape == this )
		{
			update.pCurrentSoundscape = NULL;
			update.currentDistance = 0;
			update.bInRange = false;
		}
		return;
	}

	// calc range from sound entity to player
	Vector target = EarPosition();
	float range = (update.playerPosition - target).Length();
	
	if ( update.pCurrentSoundscape == this )
	{
		update.currentDistance = range;
		update.bInRange = false;
		if ( m_flRadius > range || m_flRadius == -1 )
		{
			trace_t tr;

			update.traceCount++;
			UTIL_TraceLine( target, update.playerPosition, MASK_SOLID_BRUSHONLY|MASK_WATER, update.pPlayer, COLLISION_GROUP_NONE, &tr );
			if ( tr.fraction == 1 && !tr.startsolid )
			{
				update.bInRange = true;
			}
		}
	}
	else
	{
		if ( (!update.bInRange || range < update.currentDistance ) && (m_flRadius > range || m_flRadius == -1) )
		{
			trace_t tr;

			update.traceCount++;
			UTIL_TraceLine( target, update.playerPosition, MASK_SOLID_BRUSHONLY|MASK_WATER, update.pPlayer, COLLISION_GROUP_NONE, &tr );

			if ( tr.fraction == 1 && !tr.startsolid )
			{
				audioparams_t &audio = update.pPlayer->GetAudioParams();
				WriteAudioParamsTo( audio );
				update.pCurrentSoundscape = this;
				update.bInRange = true;
				update.currentDistance = range;
			}
		}
	}


	if ( soundscape_debug.GetBool() )
	{
		// draw myself
		NDebugOverlay::Box(GetAbsOrigin(), Vector(-10,-10,-10), Vector(10,10,10),  255, 0, 255, 64, NDEBUG_PERSIST_TILL_NEXT_SERVER );

#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
		CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); 
#else
// Don't use GetLocalPlayer(), because that prevents multiplayer games using this for testing with a single client in the game
		CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI 		

if ( update.pPlayer )
		{
			audioparams_t &audio = update.pPlayer->GetAudioParams();
			if ( audio.ent.Get() != this )
			{
				if ( InRangeOfPlayer( update.pPlayer ) )
				{
					NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 255, 255, 255, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
				}
				else
				{
					NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 255, 0, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER  );
				}
			}
			else
			{
				if ( InRangeOfPlayer( update.pPlayer ) )
				{
					NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 0, 255, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER  );
				}
  				else
				{
					NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 255, 170, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER  );
				}

				// also draw lines to each sound position.
				// we don't store the number of local sound positions, just a bitvector of which ones are on.
				unsigned int soundbits = audio.localBits.Get();
				float periodic = 2.0f * sin((fmod(gpGlobals->curtime,2.0f) - 1.0f) * M_PI); // = -4f .. 4f
				for (int ii = 0 ; ii < NUM_AUDIO_LOCAL_SOUNDS ; ++ii )
				{
					if ( soundbits & (1 << ii) )
					{
						const Vector &soundLoc = audio.localSound.Get(ii);
						NDebugOverlay::Line( GetAbsOrigin(), soundLoc, 0, 32 , 255 , false, NDEBUG_PERSIST_TILL_NEXT_SERVER );
						NDebugOverlay::Cross3D( soundLoc, 16.0f + periodic, 0, 0, 255, false, NDEBUG_PERSIST_TILL_NEXT_SERVER );
					}
				}
			}
		}

		NDebugOverlay::EntityTextAtPosition( GetAbsOrigin(), 0, STRING(m_soundscapeName), NDEBUG_PERSIST_TILL_NEXT_SERVER );
	}
}
void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION
{
	VPROF( "CRagdollLRURetirement::Update" );
	// Compress out dead items
	int i, next;

	int iMaxRagdollCount = m_iMaxRagdolls;

	if ( iMaxRagdollCount == -1 )
	{
		iMaxRagdollCount = g_ragdoll_maxcount.GetInt();
	}

	// fade them all for the low violence version
	if ( g_RagdollLVManager.IsLowViolence() )
	{
		iMaxRagdollCount = 0;
	}
	m_iRagdollCount = 0;
	m_iSimulatedRagdollCount = 0;

	// First, find ragdolls that are good candidates for deletion because they are not
	// visible at all, or are in a culled visibility box
	for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next )
	{
		next = m_LRU.Next(i);
		CBaseAnimating *pRagdoll = m_LRU[i].Get();
		if ( pRagdoll )
		{
			m_iRagdollCount++;
			IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject();
			if (pObject && !pObject->IsAsleep())
			{
				m_iSimulatedRagdollCount++;
			}
			if ( m_LRU.Count() > iMaxRagdollCount )
			{
				//Found one, we're done.
				if ( ShouldRemoveThisRagdoll( m_LRU[i] ) == true )
				{
#ifdef CLIENT_DLL
					m_LRU[ i ]->SUB_Remove();
#else
					m_LRU[ i ]->SUB_StartFadeOut( 0 );
#endif

					m_LRU.Remove(i);
					return;
				}
			}
		}
		else 
		{
			m_LRU.Remove(i);
		}
	}

	//////////////////////////////
	///   EPISODIC ALGORITHM   ///
	//////////////////////////////
	// If we get here, it means we couldn't find a suitable ragdoll to remove,
	// so just remove the furthest one.
	int furthestOne = m_LRU.Head();
	float furthestDistSq = 0;
#ifdef CLIENT_DLL
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
#else
	CBasePlayer  *pPlayer = UTIL_GetLocalPlayer();
#endif

	if (pPlayer && m_LRU.Count() > iMaxRagdollCount) // find the furthest one algorithm
	{
		Vector PlayerOrigin = pPlayer->GetAbsOrigin();
		// const CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
	
		for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next )
		{
			CBaseAnimating *pRagdoll = m_LRU[i].Get();

			next = m_LRU.Next(i);
			IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject();
			if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) )
				continue;

			if ( pRagdoll )
			{
				// float distToPlayer = (pPlayer->GetAbsOrigin() - pRagdoll->GetAbsOrigin()).LengthSqr();
				float distToPlayer = (PlayerOrigin - pRagdoll->GetAbsOrigin()).LengthSqr();

				if (distToPlayer > furthestDistSq)
				{
					furthestOne = i;
					furthestDistSq = distToPlayer;
				}
			}
			else // delete bad rags first.
			{
				furthestOne = i;
				break;
			}
		}

#ifdef CLIENT_DLL
		m_LRU[ furthestOne ]->SUB_Remove();
#else
		m_LRU[ furthestOne ]->SUB_StartFadeOut( 0 );
#endif

	}
	else // fall back on old-style pick the oldest one algorithm
	{
		for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next )
		{
			if ( m_LRU.Count() <=  iMaxRagdollCount )
				break;

			next = m_LRU.Next(i);

			CBaseAnimating *pRagdoll = m_LRU[i].Get();

			//Just ignore it until we're done burning/dissolving.
			IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject();
			if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) )
				continue;

	#ifdef CLIENT_DLL
			m_LRU[ i ]->SUB_Remove();
	#else
			m_LRU[ i ]->SUB_StartFadeOut( 0 );
	#endif
			m_LRU.Remove(i);
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPropAPC2::Think( void )
{
	if (!m_bSpawn) {
		if(m_fReloadTime<=gpGlobals->curtime && m_iAmmoCount<50) {
		m_iAmmoCount++;
		m_fReloadTime=gpGlobals->curtime+0.5f;
	}
	if(m_fCannonCharge<=gpGlobals->curtime && m_iCannonCount<100) {
		m_iCannonCount++;
		m_fCannonCharge=gpGlobals->curtime+0.03f;
	}
	BaseClass::Think();

	CBasePlayer	*pPlayer = UTIL_GetLocalPlayer();

	if ( m_bEngineLocked )
	{
		m_bUnableToFire = true;
		
		if ( pPlayer != NULL )
		{
			pPlayer->m_Local.m_iHideHUD |= HIDEHUD_VEHICLE_CROSSHAIR;
		}
	}
	else
	{
		// Start this as false and update it again each frame
		m_bUnableToFire = false;

		if ( pPlayer != NULL )
		{
			pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_VEHICLE_CROSSHAIR;
		}
	}

	SetNextThink( gpGlobals->curtime );

	if ( !m_bInitialHandbrake )	// after initial timer expires, set the handbrake
	{
		m_bInitialHandbrake = true;
		m_VehiclePhysics.SetHandbrake( true );
		m_VehiclePhysics.Think();
	}

	StudioFrameAdvance();

	if ( IsSequenceFinished() )
	{
		int iSequence = SelectWeightedSequence( ACT_IDLE );
		if ( iSequence > ACTIVITY_NOT_AVAILABLE )
		{
			SetCycle( 0 );
			m_flAnimTime = gpGlobals->curtime;
			ResetSequence( iSequence );
			ResetClientsideFrame();
		}
	}
	if ( m_hPlayer && !m_bExitAnimOn && !m_bEnterAnimOn )
	{
		Vector vecEyeDir, vecEyePos;
		m_hPlayer->EyePositionAndVectors( &vecEyePos, &vecEyeDir, NULL, NULL );

		// Trace out from the player's eye point.
		Vector	vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH );
		trace_t	trace;
		UTIL_TraceLine( vecEyePos, vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &trace );

		// See if we hit something, if so, adjust end position to hit location.
		if ( trace.fraction < 1.0 )
		{
   			vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH * trace.fraction );
		}

		//m_vecLookCrosshair = vecEndPos;
		m_vecGunCrosshair=vecEndPos;
		AimPrimaryWeapon( vecEndPos );
		//GetRocketShootPosition( &vecEndPos );
		if ( m_hLaserDot != NULL )
		{
			Vector	laserPos = trace.endpos;
			m_hLaserDot->SetAbsOrigin(laserPos);
			
			if ( trace.DidHitNonWorldEntity() )
			{
				CBaseEntity *pHit = trace.m_pEnt;

				if ( ( pHit != NULL ) && ( pHit->m_takedamage ) )
				{
					SetLaserDotTarget( m_hLaserDot, pHit );
					EnableLaserDot( m_hLaserDot, pHit != NULL );
					
				}
				else
				{
					SetLaserDotTarget( m_hLaserDot, NULL );
					EnableLaserDot(m_hLaserDot,true);
					
				}
			}
			else
			{
				SetLaserDotTarget( m_hLaserDot, NULL );
				EnableLaserDot(m_hLaserDot,true);
			}
		}
		
	}
	}
}