Beispiel #1
0
void CGunTarget::Wait( void )
{
	CBaseEntity *pTarget = m_hTargetEnt;
	
	if ( !pTarget )
	{
		Stop();
		return;
	}

	variant_t emptyVariant;
	pTarget->AcceptInput( "InPass", this, this, emptyVariant, 0 );
		
	m_flWait = pTarget->GetDelay();

	m_target = pTarget->m_target;
	SetMoveDone( &CGunTarget::Next );
	if (m_flWait != 0)
	{// -1 wait will wait forever!		
		SetMoveDoneTime( m_flWait );
	}
	else
	{
		Next();// do it RIGHT now!
	}
}
void CSmokeGrenadeProjectile::Think_Detonate()
{
	if ( GetAbsVelocity().Length() > 0.1 )
	{
		// Still moving. Don't detonate yet.
		SetNextThink( gpGlobals->curtime + 0.2 );
		return;
	}

	TheBots->SetGrenadeRadius( this, SmokeGrenadeRadius );

	// Ok, we've stopped rolling or whatever. Now detonate.
	ParticleSmokeGrenade *pGren = (ParticleSmokeGrenade*)CBaseEntity::Create( PARTICLESMOKEGRENADE_ENTITYNAME, GetAbsOrigin(), QAngle(0,0,0), NULL );
	if ( pGren )
	{
		pGren->FillVolume();
		pGren->SetFadeTime( 17, 22 );
		pGren->SetAbsOrigin( GetAbsOrigin() );

		//tell the hostages about the smoke!
		CBaseEntity *pEntity = NULL;
		variant_t var;	//send the location of the smoke?
		var.SetVector3D( GetAbsOrigin() );
		while ( ( pEntity = gEntList.FindEntityByClassname( pEntity, "hostage_entity" ) ) != NULL)
		{
			//send to hostages that have a resonable chance of being in it while its still smoking
			if( (GetAbsOrigin() - pEntity->GetAbsOrigin()).Length() < 1000 )
				pEntity->AcceptInput( "smokegrenade", this, this, var, 0 );
		}

		// tell the bots a smoke grenade has exploded
		CCSPlayer *player = ToCSPlayer(GetThrower());
		if ( player )
		{
			IGameEvent * event = gameeventmanager->CreateEvent( "smokegrenade_detonate" );
			if ( event )
			{
				event->SetInt( "userid", player->GetUserID() );
				event->SetFloat( "x", GetAbsOrigin().x );
				event->SetFloat( "y", GetAbsOrigin().y );
				event->SetFloat( "z", GetAbsOrigin().z );
				gameeventmanager->FireEvent( event );
			}
		}
	}

	m_hSmokeEffect = pGren;
	m_bDidSmokeEffect = true;

	EmitSound( "BaseSmokeEffect.Sound" );

	m_nRenderMode = kRenderTransColor;
	SetNextThink( gpGlobals->curtime + 5 );
	SetThink( &CSmokeGrenadeProjectile::Think_Fade );
}
Beispiel #3
0
void CTankTargetChange::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_target, NULL, pActivator, pCaller );

	// UNDONE: This should use more of the event system
	while ( pTarget )
	{
		// Change the target over
		pTarget->AcceptInput( "TargetEntity", this, this, m_newTarget, 0 );
		pTarget = gEntList.FindEntityByName( pTarget, m_target, NULL, pActivator, pCaller );
	}
}
Beispiel #4
0
//-----------------------------------------------------------------------------
// Purpose: fires off any events in the queue who's fire time is (or before) the present time
//-----------------------------------------------------------------------------
void CEventQueue::ServiceEvents( void )
{
	if (!CBaseEntity::Debug_ShouldStep())
	{
		return;
	}

	EventQueuePrioritizedEvent_t *pe = m_Events.m_pNext;

	while ( pe != NULL && pe->m_flFireTime <= gpGlobals->curtime )
	{
		MDLCACHE_CRITICAL_SECTION();

		bool targetFound = false;

		// find the targets
		if ( pe->m_iTarget != NULL_STRING )
		{
			// In the context the event, the searching entity is also the caller
			CBaseEntity *pSearchingEntity = pe->m_pCaller;
			CBaseEntity *target = NULL;
			while ( 1 )
			{
				target = gEntList.FindEntityByName( target, pe->m_iTarget, pSearchingEntity, pe->m_pActivator, pe->m_pCaller );
				if ( !target )
					break;

				// pump the action into the target
				target->AcceptInput( STRING(pe->m_iTargetInput), pe->m_pActivator, pe->m_pCaller, pe->m_VariantValue, pe->m_iOutputID );
				targetFound = true;
			}
		}

		// direct pointer
		if ( pe->m_pEntTarget != NULL )
		{
			pe->m_pEntTarget->AcceptInput( STRING(pe->m_iTargetInput), pe->m_pActivator, pe->m_pCaller, pe->m_VariantValue, pe->m_iOutputID );
			targetFound = true;
		}

		if ( !targetFound )
		{
			// See if we can find a target if we treat the target as a classname
			if ( pe->m_iTarget != NULL_STRING )
			{
				CBaseEntity *target = NULL;
				while ( 1 )
				{
					target = gEntList.FindEntityByClassname( target, STRING(pe->m_iTarget) );
					if ( !target )
						break;

					// pump the action into the target
					target->AcceptInput( STRING(pe->m_iTargetInput), pe->m_pActivator, pe->m_pCaller, pe->m_VariantValue, pe->m_iOutputID );
					targetFound = true;
				}
			}
		}

		if ( !targetFound )
		{
			const char *pClass ="", *pName = "";
			
			// might be NULL
			if ( pe->m_pCaller )
			{
				pClass = STRING(pe->m_pCaller->m_iClassname);
				pName = STRING(pe->m_pCaller->GetEntityName());
			}
			
			char szBuffer[256];
			Q_snprintf( szBuffer, sizeof(szBuffer), "unhandled input: (%s) -> (%s), from (%s,%s); target entity not found\n", STRING(pe->m_iTargetInput), STRING(pe->m_iTarget), pClass, pName );
			DevMsg( 2, "%s", szBuffer );
			ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
		}

		// remove the event from the list (remembering that the queue may have been added to)
		RemoveEvent( pe );
		delete pe;

		//
		// If we are in debug mode, exit the loop if we have fired the correct number of events.
		//
		if (CBaseEntity::Debug_IsPaused())
		{
			if (!CBaseEntity::Debug_Step())
			{
				break;
			}
		}

		// restart the list (to catch any new items have probably been added to the queue)
		pe = m_Events.m_pNext;	
	}
}
Beispiel #5
0
//-----------------------------------------------------------------------------
// Purpose: Handles USE keypress
//-----------------------------------------------------------------------------
void CBasePlayer::PlayerUse ( void )
{
#ifdef GAME_DLL
	// Was use pressed or released?
	if ( ! ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) )
		return;

	if ( IsObserver() )
	{
		// do special use operation in oberserver mode
		if ( m_afButtonPressed & IN_USE )
			ObserverUse( true );
		else if ( m_afButtonReleased & IN_USE )
			ObserverUse( false );
		
		return;
	}

#if !defined(_XBOX)
	// push objects in turbo physics mode
	if ( (m_nButtons & IN_USE) && sv_turbophysics.GetBool() )
	{
		Vector forward, up;
		EyeVectors( &forward, NULL, &up );

		trace_t tr;
		// Search for objects in a sphere (tests for entities that are not solid, yet still useable)
		Vector searchCenter = EyePosition();

		CUsePushFilter filter;

		UTIL_TraceLine( searchCenter, searchCenter + forward * 96.0f, MASK_SOLID, &filter, &tr );

		// try the hit entity if there is one, or the ground entity if there isn't.
		CBaseEntity *entity = tr.m_pEnt;

		if ( entity )
		{
			IPhysicsObject *pObj = entity->VPhysicsGetObject();

			if ( pObj )
			{
				Vector vPushAway = (entity->WorldSpaceCenter() - WorldSpaceCenter());
				vPushAway.z = 0;

				float flDist = VectorNormalize( vPushAway );
				flDist = max( flDist, 1 );

				float flForce = sv_pushaway_force.GetFloat() / flDist;
				flForce = min( flForce, sv_pushaway_max_force.GetFloat() );

				pObj->ApplyForceOffset( vPushAway * flForce, WorldSpaceCenter() );
			}
		}
	}
#endif

	if ( m_afButtonPressed & IN_USE )
	{
		// Controlling some latched entity?
		if ( ClearUseEntity() )
		{
			return;
		}
		else
		{
			if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE )
			{
				m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE;
				m_iTrain = TRAIN_NEW|TRAIN_OFF;
				return;
			}
			else
			{	// Start controlling the train!
				CBaseEntity *pTrain = GetGroundEntity();
				if ( pTrain && !(m_nButtons & IN_JUMP) && (GetFlags() & FL_ONGROUND) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) && pTrain->OnControls(this) )
				{
					m_afPhysicsFlags |= PFLAG_DIROVERRIDE;
					m_iTrain = TrainSpeed(pTrain->m_flSpeed, ((CFuncTrackTrain*)pTrain)->GetMaxSpeed());
					m_iTrain |= TRAIN_NEW;
					EmitSound( "Player.UseTrain" );
					return;
				}
			}
		}
	}

	CBaseEntity *pUseEntity = FindUseEntity();

	// Found an object
	if ( pUseEntity )
	{

		//!!!UNDONE: traceline here to prevent +USEing buttons through walls			

		int caps = pUseEntity->ObjectCaps();
		variant_t emptyVariant;
		if ( ( (m_nButtons & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) || ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) )
		{
			if ( caps & FCAP_CONTINUOUS_USE )
			{
				m_afPhysicsFlags |= PFLAG_USING;
			}

			if ( pUseEntity->ObjectCaps() & FCAP_ONOFF_USE )
			{
				pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_ON );
			}
			else
			{
				pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );
			}
		}
		// UNDONE: Send different USE codes for ON/OFF.  Cache last ONOFF_USE object to send 'off' if you turn away
		else if ( (m_afButtonReleased & IN_USE) && (pUseEntity->ObjectCaps() & FCAP_ONOFF_USE) )	// BUGBUG This is an "off" use
		{
			pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_OFF );
		}
	}
	else if ( m_afButtonPressed & IN_USE )
	{
		PlayUseDenySound();
	}
#endif
}
Beispiel #6
0
void RadiusFlash(
    Vector vecSrc,
    CBaseEntity *pevInflictor,
    CBaseEntity *pevAttacker,
    float flDamage,
    int iClassIgnore,
    int bitsDamageType)
{
    vecSrc.z += 1;// in case grenade is lying on the ground

    if (!pevAttacker)
        pevAttacker = pevInflictor;

    trace_t		tr;
    float		flAdjustedDamage;
    variant_t	var;
    Vector		vecEyePos;
    float		fadeTime, fadeHold;
    Vector		vForward;
    Vector		vecLOS;
    float		flDot;

    CBaseEntity		*pEntity = NULL;
    static float	flRadius = 1500;
    float			falloff = flDamage / flRadius;

    bool bInWater = (UTIL_PointContents(vecSrc) == CONTENTS_WATER);

    // iterate on all entities in the vicinity.
    while ((pEntity = gEntList.FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL)
    {
        bool bPlayer = pEntity->IsPlayer();
        bool bHostage = (Q_stricmp(pEntity->GetClassname(), "hostage_entity") == 0);

        if (!bPlayer && !bHostage)
            continue;

        vecEyePos = pEntity->EyePosition();

        // blasts don't travel into or out of water
        if (bInWater && pEntity->GetWaterLevel() == 0)
            continue;
        if (!bInWater && pEntity->GetWaterLevel() == 3)
            continue;

        float percentageOfFlash = PercentageOfFlashForPlayer(pEntity, vecSrc, pevInflictor);

        if (percentageOfFlash > 0.0)
        {
            // decrease damage for an ent that's farther from the grenade
            flAdjustedDamage = flDamage - (vecSrc - pEntity->EyePosition()).Length() * falloff;

            if (flAdjustedDamage > 0)
            {
                // See if we were facing the flash
                AngleVectors(pEntity->EyeAngles(), &vForward);

                vecLOS = (vecSrc - vecEyePos);

                //float flDistance = vecLOS.Length();

                // Normalize both vectors so the dotproduct is in the range -1.0 <= x <= 1.0 
                vecLOS.NormalizeInPlace();

                flDot = DotProduct(vecLOS, vForward);

                float startingAlpha = 255;

                // if target is facing the bomb, the effect lasts longer
                if (flDot >= 0.5)
                {
                    // looking at the flashbang
                    fadeTime = flAdjustedDamage * 2.5f;
                    fadeHold = flAdjustedDamage * 1.25f;
                }
                else if (flDot >= -0.5)
                {
                    // looking to the side
                    fadeTime = flAdjustedDamage * 1.75f;
                    fadeHold = flAdjustedDamage * 0.8f;
                }
                else
                {
                    // facing away
                    fadeTime = flAdjustedDamage * 1.0f;
                    fadeHold = flAdjustedDamage * 0.75f;
                    startingAlpha = 200;
                }

                fadeTime *= percentageOfFlash;
                fadeHold *= percentageOfFlash;

                if (bPlayer)
                {
                    //MOM_TODO: do we want this functionality?
                    // blind players and bots
                    //CMomentumPlayer *player = static_cast<CMomentumPlayer *>(pEntity);
                    //player->Blind( fadeHold, fadeTime, startingAlpha );

                    // deafen players and bots
                    //player->Deafen( flDistance );
                }
                else if (bHostage)
                {
                    variant_t val;
                    val.SetFloat(fadeTime);
                    pEntity->AcceptInput("flashbang", pevInflictor, pevAttacker, val, 0);
                }
            }
        }
    }

    CPVSFilter filter(vecSrc);
    te->DynamicLight(filter, 0.0, &vecSrc, 255, 255, 255, 2, 400, 0.1, 768);
}
bool CSDKPlayer::PlayerUse()
{
#ifdef GAME_DLL
	// Was use pressed or released?
	if ( ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) && !IsObserver() )
	{
		Vector forward, up;
		EyeVectors( &forward, NULL, &up );

		Vector vecSearchCenter = EyePosition();
		CBaseEntity *pObject = nullptr;
		CBaseEntity *pNearest = nullptr;
		float flNearest = FLT_MAX;

		// Look for grenades so we can prioritize picking them up first.
		for ( CEntitySphereQuery sphere( vecSearchCenter, PLAYER_USE_RADIUS ); ( pObject = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
		{
			if ( !pObject )
				continue;

			if ( !IsUseableEntity( pObject, FCAP_USE_IN_RADIUS ) )
				continue;

			CWeaponSDKBase* pWeapon = dynamic_cast<CWeaponSDKBase*>(pObject);
			if (!pWeapon)
				continue;

			if (pWeapon->GetWeaponID() != SDK_WEAPON_GRENADE)
				continue;

			// If we're full up on grenades, pass over to whatever other weapons are lying around.
			if (!g_pGameRules->CanHavePlayerItem(this, pWeapon))
				continue;

			// see if it's more roughly in front of the player than previous guess
			Vector point;
			pObject->CollisionProp()->CalcNearestPoint( vecSearchCenter, &point );

			Vector dir = point - vecSearchCenter;
			VectorNormalize(dir);
			float dot = DotProduct( dir, forward );

			// Need to be looking at the object more or less
			if ( dot < 0.8 )
				continue;

			float dist = CalcDistanceToLine( point, vecSearchCenter, forward );

			ConVarRef sv_debug_player_use("sv_debug_player_use");
			if ( sv_debug_player_use.GetBool() )
			{
				Msg("Radius found %s, dist %.2f\n", pObject->GetClassname(), dist );
			}

			// Not worried about shit being behind a wall at this point.
			// Just greedily gobble up all nearby grenades since there's
			// no penalty to the player for doing so.

			if ( dist < flNearest )
			{
				pNearest = pObject;
				flNearest = dist;
			}
		}

		if (pNearest)
		{
			// This is a grenade. Use it to pick it up.
			variant_t emptyVariant;
			pNearest->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );
			return true;
		}
	}
#endif

	bool bUsed = BaseClass::PlayerUse();

	if (bUsed)
		return bUsed;

	if (!(m_afButtonPressed & IN_USE))
		return false;

	if (!IsAlive())
		return false;

	return false;
}
	// Regular explosions
	void CPlantedC4::Explode( trace_t *pTrace, int bitsDamageType )
	{
		// Check to see if the round is over after the bomb went off...
		CSGameRules()->m_bTargetBombed = true;
		m_bBombTicking = false;
		CSGameRules()->CheckWinConditions();

		// Do the Damage
		float flBombRadius = 500;
		if ( g_pMapInfo )
			flBombRadius = g_pMapInfo->m_flBombRadius;

		// Output to the bomb target ent
		CBaseEntity *pTarget = NULL;
		variant_t emptyVariant;
		while ((pTarget = gEntList.FindEntityByClassname( pTarget, "func_bomb_target" )) != NULL)
		{
			//Adrian - But only to the one we want!
			if ( pTarget->entindex() != m_iBombSiteIndex )
				 continue;
			
			pTarget->AcceptInput( "BombExplode", this, this, emptyVariant, 0 );
				break;
		}	

		// Pull out of the wall a bit
		if ( pTrace->fraction != 1.0 )
		{
			SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) );
		}

		{
			Vector pos = GetAbsOrigin() + Vector( 0,0,8 );

			// add an explosion TE so it affects clientside physics
			CPASFilter filter( pos );
			te->Explosion( filter, 0.0,
				&pos, 
				g_sModelIndexFireball,
				50.0, 
				25,
				TE_EXPLFLAG_NONE,
				flBombRadius * 3.5,
				200 );
		}
		
		// Fireball sprite and sound!!
		{
			Vector fireballPos = GetAbsOrigin();
			CPVSFilter filter( fireballPos );
			te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 );
		}

		{
			Vector fireballPos = GetAbsOrigin() + Vector( 
				random->RandomFloat( -512, 512 ), 
				random->RandomFloat( -512, 512 ),
				random->RandomFloat( -10, 10 ) );

			CPVSFilter filter( fireballPos );
			te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 );
		}

		{
			Vector fireballPos = GetAbsOrigin() + Vector( 
				random->RandomFloat( -512, 512 ), 
				random->RandomFloat( -512, 512 ),
				random->RandomFloat( -10, 10 ) );

			CPVSFilter filter( fireballPos );
			te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 );
		}

		// Sound! for everyone
		CBroadcastRecipientFilter filter;
		EmitSound( filter, entindex(), "c4.explode" );


		// Decal!
		UTIL_DecalTrace( pTrace, "Scorch" );

		
		// Shake!
		UTIL_ScreenShake( pTrace->endpos, 25.0, 150.0, 1.0, 3000, SHAKE_START );


		SetOwnerEntity( NULL ); // can't traceline attack owner if this is set

		CSGameRules()->RadiusDamage( 
			CTakeDamageInfo( this, GetOwnerEntity(), flBombRadius, bitsDamageType ),
			GetAbsOrigin(),
			flBombRadius * 3.5,	//Matt - don't ask me, this is how CS does it.
			CLASS_NONE,
			true );	// IGNORE THE WORLD!!

		// send director message, that something important happed here
		/*
		MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR );
			WRITE_BYTE ( 9 );	// command length in bytes
			WRITE_BYTE ( DRC_CMD_EVENT );	// bomb explode
			WRITE_SHORT( ENTINDEX(this->edict()) );	// index number of primary entity
			WRITE_SHORT( 0 );	// index number of secondary entity
			WRITE_LONG( 15 | DRC_FLAG_FINAL );   // eventflags (priority and flags)
		MESSAGE_END();
		*/

		UTIL_Remove( this );
	}
Beispiel #9
0
void CSDKPlayer::PlayerUse ( void )
{
	// Was use pressed or released?
	if ( ! ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) )
		return;

	if ( m_afButtonPressed & IN_USE )
	{
		// Currently using a latched entity?
		if ( ClearUseEntity() )
		{
			if (m_bPlayerPickedUpObject)
			{
				m_bPlayerPickedUpObject = false;
			}
			return;
		}
		else
		{
			if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE )
			{
				m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE;
				m_iTrain = TRAIN_NEW|TRAIN_OFF;
				return;
			}
		}

		// Tracker 3926:  We can't +USE something if we're climbing a ladder
		if ( GetMoveType() == MOVETYPE_LADDER )
		{
			return;
		}
	}

	if( m_flTimeUseSuspended > gpGlobals->curtime )
	{
		// Something has temporarily stopped us being able to USE things.
		// Obviously, this should be used very carefully.(sjb)
		return;
	}

	CBaseEntity *pUseEntity = FindUseEntity();

	bool usedSomething = false;

	// Found an object
	if ( pUseEntity )
	{
		//!!!UNDONE: traceline here to prevent +USEing buttons through walls			
		int caps = pUseEntity->ObjectCaps();
		variant_t emptyVariant;

		if ( m_afButtonPressed & IN_USE )
		{
			// Robin: Don't play sounds for NPCs, because NPCs will allow respond with speech.
			if ( !pUseEntity->MyNPCPointer() )
			{
				EmitSound( SOUND_USE );
			}
		}

		if ( ( (m_nButtons & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) ||
			 ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) )
		{
			if ( caps & FCAP_CONTINUOUS_USE )
				m_afPhysicsFlags |= PFLAG_USING;

			pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );

			usedSomething = true;
		}
		// UNDONE: Send different USE codes for ON/OFF.  Cache last ONOFF_USE object to send 'off' if you turn away
		else if ( (m_afButtonReleased & IN_USE) && (pUseEntity->ObjectCaps() & FCAP_ONOFF_USE) )	// BUGBUG This is an "off" use
		{
			pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );

			usedSomething = true;
		}
	}

	else if ( m_afButtonPressed & IN_USE )
	{
		// Signal that we want to play the deny sound, unless the user is +USEing on a ladder!
		// The sound is emitted in ItemPostFrame, since that occurs after GameMovement::ProcessMove which
		// lets the ladder code unset this flag.
		m_bPlayUseDenySound = true;
	}

	// Debounce the use key
	if ( usedSomething && pUseEntity )
	{
		m_Local.m_nOldButtons |= IN_USE;
		m_afButtonPressed &= ~IN_USE;
	}
}