Пример #1
0
//-----------------------------------------------------------------------------
// Draws all the debugging info
//-----------------------------------------------------------------------------
void CDebugViewRender::Draw2DDebuggingInfo( const CViewSetup &view )
{
	if ( IsX360() && IsRetail() )
		return;

	// HDRFIXME: Assert NULL rendertarget
	if ( mat_yuv.GetInt() && (engine->GetDXSupportLevel() >= 80) )
	{
		IMaterial *pMaterial;
		pMaterial = materials->FindMaterial( "debug/yuv", TEXTURE_GROUP_OTHER, true );
		if( !IsErrorMaterial( pMaterial ) )
		{
			DrawScreenEffectMaterial( pMaterial, view.x, view.y, view.width, view.height );
		}
	}

	if ( mat_hsv.GetInt() && (engine->GetDXSupportLevel() >= 90) )
	{
		IMaterial *pMaterial;
		pMaterial = materials->FindMaterial( "debug/hsv", TEXTURE_GROUP_OTHER, true );
		if( !IsErrorMaterial( pMaterial ) )
		{
			DrawScreenEffectMaterial( pMaterial, view.x, view.y, view.width, view.height );
		}
	}

	// Draw debugging lightmaps
	if ( mat_showlightmappage.GetInt() != -1 )
	{
		CLightmapDebugView clientView( assert_cast<CViewRender *>( ::view ) );
		clientView.Setup( view );
		clientView.Draw();
	}

	if ( cl_drawshadowtexture.GetInt() )
	{
		int nSize = cl_shadowtextureoverlaysize.GetInt();
		g_pClientShadowMgr->RenderShadowTexture( nSize, nSize );
	}

	const char *pDrawMaterial = cl_drawmaterial.GetString();
	if ( pDrawMaterial && pDrawMaterial[0] )
	{
		RenderMaterial( pDrawMaterial ); 
	}

	if ( mat_showwatertextures.GetBool() )
	{
		OverlayWaterTextures();
	}

	if ( mat_showcamerarendertarget.GetBool() )
	{
		float w = mat_wateroverlaysize.GetFloat();
		float h = mat_wateroverlaysize.GetFloat();
#ifdef PORTAL
		g_pPortalRender->OverlayPortalRenderTargets( w, h );
#else
		OverlayCameraRenderTarget( "debug/debugcamerarendertarget", 0, 0, w, h );
#endif
	}

	if ( mat_showframebuffertexture.GetBool() )
	{
		// HDRFIXME: Get rid of these rendertarget sets assuming that the assert at the top of this function is true.
		CMatRenderContextPtr pRenderContext( materials );
		pRenderContext->PushRenderTargetAndViewport( NULL );
		OverlayFrameBufferTexture( 0 );
		OverlayFrameBufferTexture( 1 );
		pRenderContext->PopRenderTargetAndViewport( );
	}

	const char *pDrawTexture = mat_drawTexture.GetString();
	if ( pDrawTexture && pDrawTexture[0] )
	{		
		OverlayShowTexture( pDrawTexture, mat_drawTextureScale.GetFloat() );
	}

#ifdef _X360
	if ( mat_drawColorRamp.GetBool() )
	{
		OverlayColorRamp( mat_drawColorRamp.GetInt() == 2 );
	}
#endif

	if ( r_flashlightdrawdepth.GetBool() )
	{
		shadowmgr->DrawFlashlightDepthTexture( );
	}

	if ( mat_drawTitleSafe.GetBool() )
	{
		OverlayTitleSafe();
	}
}
//-----------------------------------------------------------------------------
// Purpose: Give the buster a slight attraction to striders.
//			Ported back from the magnade.
//-----------------------------------------------------------------------------
void CWeaponStriderBuster::BusterFlyThink()
{
	if (IsAttachedToStrider())
		return; // early out. Think no more.

	// If we're nosediving, forget about magnetism.
	if ( m_bNoseDiving )
	{
		if ( VPhysicsGetObject() )
			VPhysicsGetObject()->ApplyForceCenter( Vector( 0, 0, striderbuster_dive_force.GetFloat() ) );
		SetNextThink(gpGlobals->curtime + 0.01f);
		return;
	}

	// seek?	
	const float magradius = 38.0 * sk_striderbuster_magnet_multiplier.GetFloat(); // radius of strider hull times multiplier
	if (magradius > 0 &&
		GetMoveType() == MOVETYPE_VPHYSICS &&
		VPhysicsGetObject()
		)
	{
		// find the nearest enemy.
		CBaseEntity *pList[16];
		Vector origin = GetAbsOrigin();

		// do a find in box ( a little faster than sphere )
		int count;
		{
			Vector mins,maxs;
			mins = origin; 
			mins -= magradius;
			
			maxs = origin; 
			maxs += magradius;

			count = UTIL_EntitiesInBox(pList, 16, mins, maxs, FL_NPC); 
		}

		float magradiusSq = Square( magradius );	
		float nearestDistSq = magradiusSq + 1;
		int bestFit = -1;
		Vector toTarget; // will be garbage unless something good is found
		CNPC_Strider *pBestStrider  = NULL;

		for ( int ii = 0 ; ii < count ; ++ii )
		{
			CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pList[ii]);
			if ( pStrider && !pStrider->CarriedByDropship() ) // ShouldStickToEntity() doesn't work because the strider NPC isn't what we glue to
			{
				// get distance squared
				VectorSubtract( pStrider->GetAdjustedOrigin(), GetAbsOrigin(), toTarget );

				//NDebugOverlay::Line( GetAbsOrigin(), GetAbsOrigin() + toTarget, 128, 0, 128, false, 0.1 );

				float dSq = toTarget.LengthSqr();
				if (dSq < nearestDistSq)
				{
					bestFit = ii; nearestDistSq = dSq;
					pBestStrider = pStrider;
				}
			}
		}

		if (bestFit >= 0) // we found something and should attract towards it. (hysterisis later?)
		{
			if ( striderbuster_debugseek.GetBool() )
			{
				NDebugOverlay::Circle( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, 255, true, .1 );
				NDebugOverlay::Cross3D( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, true, .1 );
			}

			// force magnitude. 
			float magnitude = GetMass() * striderbuster_magnetic_force_strider.GetFloat();
			int falloff = striderbuster_falloff_power.GetInt();
			switch (falloff) 
			{
			case 1:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / nearestDistSq) ); // dividing through by distance squared normalizes toTarget and gives a linear falloff
				break;
			case 2:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * sqrtf(nearestDistSq))) ); // dividing through by distance cubed normalizes toTarget and gives a quadratic falloff
				break;
			case 3:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * nearestDistSq)) ); // dividing through by distance fourth normalizes toTarget and gives a cubic falloff
				break;
			case 4:
				{
					Vector toTarget;
					pBestStrider->GetAttachment( "buster_target", toTarget );

					if ( striderbuster_debugseek.GetBool() )
					{
						NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 );
						NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 );
					}

					toTarget -= GetAbsOrigin();
					toTarget.NormalizeInPlace();
					VPhysicsGetObject()->ApplyForceCenter( toTarget * magnitude );

				}
				break;
			default: // arbitrary powers
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude * powf(nearestDistSq,(falloff+1.0f)/2)) );  // square root for distance instead of squared, add one to normalize toTarget 
				break;
			}
		}

		SetNextThink(gpGlobals->curtime + 0.01f);
	}
}
Пример #3
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
C_ASW_Prop_Physics::C_ASW_Prop_Physics( void ) :
	m_MotionBlurObject( this, asw_phys_prop_motion_blur_scale.GetFloat() )
{
	m_bClientOnFire = false;
}
Пример #4
0
// -----------------------------------------------------------------------------
// Purpose:
// Note: Think function to delay the impact decal until the animation is finished 
//       playing.
// -----------------------------------------------------------------------------
void CTFWeaponBaseMelee::Smack( void )
{
	trace_t trace;

	CBasePlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

#if !defined (CLIENT_DLL)
	// Move other players back to history positions based on local player's lag
	lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() );
#endif

	// We hit, setup the smack.
	if ( DoSwingTrace( trace ) )
	{
		// Hit sound - immediate.
		if( trace.m_pEnt->IsPlayer()  )
		{
			WeaponSound( MELEE_HIT );
		}
		else
		{
			WeaponSound( MELEE_HIT_WORLD );
		}

		// Get the current player.
		CTFPlayer *pPlayer = GetTFPlayerOwner();
		if ( !pPlayer )
			return;

		Vector vecForward; 
		AngleVectors( pPlayer->EyeAngles(), &vecForward );
		Vector vecSwingStart = pPlayer->Weapon_ShootPosition();
		Vector vecSwingEnd = vecSwingStart + vecForward * 48;

#ifndef CLIENT_DLL
		// Do Damage.
		int iCustomDamage = TF_DMG_CUSTOM_NONE;
		float flDamage = GetMeleeDamage( trace.m_pEnt, iCustomDamage );
		int iDmgType = DMG_BULLET | DMG_NEVERGIB | DMG_CLUB;
		if ( IsCurrentAttackACrit() )
		{
			// TODO: Not removing the old critical path yet, but the new custom damage is marking criticals as well for melee now.
			iDmgType |= DMG_CRITICAL;
		}

		CTakeDamageInfo info( pPlayer, pPlayer, flDamage, iDmgType, iCustomDamage );
		CalculateMeleeDamageForce( &info, vecForward, vecSwingEnd, 1.0f / flDamage * tf_meleeattackforcescale.GetFloat() );
		trace.m_pEnt->DispatchTraceAttack( info, vecForward, &trace ); 
		ApplyMultiDamage();

		OnEntityHit( trace.m_pEnt );
#endif
		// Don't impact trace friendly players or objects
		if ( trace.m_pEnt && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber() )
		{
#ifdef CLIENT_DLL
			UTIL_ImpactTrace( &trace, DMG_CLUB );
#endif
			m_bConnected = true;
		}

	}

#if !defined (CLIENT_DLL)
	lagcompensation->FinishLagCompensation( pPlayer );
#endif
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &forward - 
//			flMass - 
// Output : Vector
//-----------------------------------------------------------------------------
Vector CWeaponStriderBuster::PhysGunLaunchVelocity( const Vector &forward, float flMass )
{
	return ( striderbuster_shot_velocity.GetFloat() * forward );
}
void CWeaponIFMSteadyCam::ItemPostFrame()
{
	CBasePlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;
	
	float flSensitivity = ifm_steadycam_sensitivity.GetFloat();

	Vector2D vecOldActualViewOffset = m_vecActualViewOffset.AsVector2D();
	if ( pPlayer->m_nButtons & IN_ATTACK )
	{
		const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand();
		m_vecActualViewOffset.x += pUserCmd->mousedx * flSensitivity;
		m_vecActualViewOffset.y += pUserCmd->mousedy * flSensitivity;
	}
	else
	{
		if ( !m_bIsLocked && !m_bInDirectMode )
		{
			float flDamp = ifm_steadycam_rotatedamp.GetFloat();
			m_vecActualViewOffset.x *= flDamp;
			m_vecActualViewOffset.y *= flDamp;
		}
	}
	
	// Add noise
	if ( !m_bIsLocked )
	{
		float flNoise = ifm_steadycam_noise.GetFloat();
		if ( flNoise > 0.0f )
		{
			CUniformRandomStream stream;
			stream.SetSeed( (int)(gpGlobals->curtime * 100) );

			CGaussianRandomStream gauss( &stream );
			float dx = gauss.RandomFloat( 0.0f, flNoise );
			float dy = gauss.RandomFloat( 0.0f, flNoise );

			m_vecActualViewOffset.x += dx;
			m_vecActualViewOffset.y += dy;
		}
	}

	ComputeViewOffset();

	if ( pPlayer->m_nButtons & IN_ZOOM )
	{
		const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand();
		m_flFOVOffsetY += pUserCmd->mousedy * flSensitivity;
	}
	else
	{
		float flDamp = ifm_steadycam_zoomdamp.GetFloat();
		m_flFOVOffsetY *= flDamp;
	}			    
	m_flFOV += m_flFOVOffsetY * ifm_steadycam_zoomspeed.GetFloat() / 1000.0f;
	m_flFOV = clamp( m_flFOV, 0.5f, 160.0f ); 

	if ( pPlayer->m_nButtons & IN_WALK )
	{
		const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand();
		m_flArmLength -= ifm_steadycam_armspeed.GetFloat() * pUserCmd->mousedy;
	}

	if ( pPlayer->GetImpulse() == 87 )
	{
		ToggleDirectMode();
	}

	if ( pPlayer->GetImpulse() == 89 )
	{
		m_bInSpringMode = !m_bInSpringMode;
	}

	if ( pPlayer->m_afButtonPressed & IN_USE )
	{
		LockCamera();
	}

	if ( pPlayer->m_afButtonPressed & IN_ATTACK2 )
	{
		m_bFullScreen = !m_bFullScreen;
	}

	if ( pPlayer->GetImpulse() == 88 )
	{
		// Make the view angles exactly match the player
		m_vecViewOffset.Init();
		m_vecActualViewOffset.Init();
		m_vecOffset.Init();
		m_vec2DVelocity.Init();
		m_hLockTarget.Set( NULL );
		m_flArmLength = 0.0f;
		if ( m_bIsLocked )
		{
			LockCamera();
		}
		m_angRelativeAngles = pPlayer->EyeAngles();
		m_flFOV = pPlayer->GetFOV();
	}

	UpdateRelativeOrientation();
	TransmitRenderInfo();
}
void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{ 
	// if it's not a player, ignore
	if ( !pActivator->IsPlayer() )
		return;

	// if there is no juice left, turn it off
	if (m_iJuice <= 0)
	{
		SetTextureFrameIndex( 1 );
		Off();
	}

	// if the player doesn't have the suit, or there is no juice left, make the deny noise
	if ( m_iJuice <= 0 )
	{
		if (m_flSoundTime <= gpGlobals->curtime)
		{
			m_flSoundTime = gpGlobals->curtime + 0.62;
			EmitSound( "SuitRecharge.Deny" );
		}
		return;
	}

	SetNextThink( gpGlobals->curtime + 0.25 );
	SetThink(Off);

	// Time to recharge yet?

	if (m_flNextCharge >= gpGlobals->curtime)
		return;

	// Make sure that we have a caller
	if (!pActivator)
		return;

	m_hActivator = pActivator;

	//only recharge the player

	if (!m_hActivator->IsPlayer() )
		return;
	
	// Play the on sound or the looping charging sound
	if (!m_iOn)
	{
		m_iOn++;
		EmitSound( "SuitRecharge.Start" );
		m_flSoundTime = 0.56 + gpGlobals->curtime;
	}
	if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime))
	{
		m_iOn++;
		CPASAttenuationFilter filter( this, "SuitRecharge.ChargingLoop" );
		filter.MakeReliable();
		EmitSound( filter, entindex(), "SuitRecharge.ChargingLoop" );
	}

	CBasePlayer *pl = (CBasePlayer *) m_hActivator.Get();

	// charge the player
	if (pl->ArmorValue() < 100)
	{
		m_iJuice--;
		pl->IncrementArmorValue( 1, 100 );
	}

	// Send the output.
	float flRemaining = m_iJuice / sk_suitcharger.GetFloat();
	m_OutRemainingCharge.Set(flRemaining, pActivator, this);

	// govern the rate of charge
	m_flNextCharge = gpGlobals->curtime + 0.1;
}
Пример #8
0
bool C_PhysPropClientside::Initialize()
{
	if ( InitializeAsClientEntity( STRING(GetModelName()), RENDER_GROUP_OPAQUE_ENTITY ) == false )
	{
		return false;
	}

	const model_t *mod = GetModel();
	if ( mod )
	{
		Vector mins, maxs;
		modelinfo->GetModelBounds( mod, mins, maxs );
		SetCollisionBounds( mins, maxs );
	}

	solid_t tmpSolid;

	// Create the object in the physics system

	if ( !PhysModelParseSolid( tmpSolid, this, GetModelIndex() ) )
	{
		DevMsg("C_PhysPropClientside::Initialize: PhysModelParseSolid failed for entity %i.\n", GetModelIndex() );
		return false;
	}
	else
	{
		m_pPhysicsObject = VPhysicsInitNormal( SOLID_VPHYSICS, 0, m_spawnflags & SF_PHYSPROP_START_ASLEEP, &tmpSolid );
	
		if ( !m_pPhysicsObject )
		{
			// failed to create a physics object
		DevMsg(" C_PhysPropClientside::Initialize: VPhysicsInitNormal() failed for %s.\n", STRING(GetModelName()) );
			return false;
		}
	}

	// We want touch calls when we hit the world
	unsigned int flags = VPhysicsGetObject()->GetCallbackFlags();
	VPhysicsGetObject()->SetCallbackFlags( flags | CALLBACK_GLOBAL_TOUCH_STATIC );

	if ( m_spawnflags & SF_PHYSPROP_MOTIONDISABLED )
	{
		m_pPhysicsObject->EnableMotion( false );
	}
		
	Spawn(); // loads breakable & prop data

	if ( m_iPhysicsMode == PHYSICS_MULTIPLAYER_AUTODETECT )
	{
		m_iPhysicsMode = GetAutoMultiplayerPhysicsMode( 
			CollisionProp()->OBBSize(), m_pPhysicsObject->GetMass() );
	}

	if 	( m_spawnflags & SF_PHYSPROP_FORCE_SERVER_SIDE )
	{
		// forced to be server-side by map maker
		return false;
	}
		

	
	if ( m_iPhysicsMode != PHYSICS_MULTIPLAYER_CLIENTSIDE )
	{
		// spawn only clientside entities
		return false;
	}
	else 
	{
		if ( engine->IsInEditMode() )
		{
			// don't spawn in map edit mode
			return false;
		}
	}

	if ( m_fadeMinDist < 0 )
	{
		// start fading out at 75% of r_propsmaxdist
		m_fadeMaxDist = r_propsmaxdist.GetFloat();
		m_fadeMinDist = r_propsmaxdist.GetFloat() * 0.75f;
	}

	// player can push it away
	SetCollisionGroup( COLLISION_GROUP_PUSHAWAY );

	UpdatePartitionListEntry();

	CollisionProp()->UpdatePartition();

	SetBlocksLOS( false ); // this should be a small object

	// Set up shadows; do it here so that objects can change shadowcasting state
	CreateShadow();

	UpdateVisibility();

	SetNextClientThink( CLIENT_THINK_NEVER );

	return true;
}
Пример #9
0
void C_SDKRagdoll::CreateRagdoll()
{
	// First, initialize all our data. If we have the player's entity on our client,
	// then we can make ourselves start out exactly where the player is.
	C_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( m_hPlayer.Get() );

	if ( pPlayer && !pPlayer->IsDormant() )
	{
		// move my current model instance to the ragdoll's so decals are preserved.
		pPlayer->SnatchModelInstance( this );

		VarMapping_t *varMap = GetVarMapping();

		// Copy all the interpolated vars from the player entity.
		// The entity uses the interpolated history to get bone velocity.
		if ( !pPlayer->IsLocalPlayer() && pPlayer->IsInterpolationEnabled() )
		{
			Interp_Copy( pPlayer );

			SetAbsAngles( pPlayer->GetRenderAngles() );
			GetRotationInterpolator().Reset(0.0f);

			m_flAnimTime = pPlayer->m_flAnimTime;
			SetSequence( pPlayer->GetSequence() );
			m_flPlaybackRate = pPlayer->GetPlaybackRate();
		}
		else
		{
			// This is the local player, so set them in a default
			// pose and slam their velocity, angles and origin
			SetAbsOrigin( m_vecRagdollOrigin );

			SetAbsAngles( pPlayer->GetRenderAngles() );

			SetAbsVelocity( m_vecRagdollVelocity );

			int iSeq = LookupSequence( "RagdollSpawn" );	// hax, find a neutral standing pose
			if ( iSeq == -1 )
			{
				Assert( false );	// missing look_idle?
				iSeq = 0;
			}
			
			SetSequence( iSeq );	// look_idle, basic pose
			SetCycle( 0.0 );

			Interp_Reset( varMap );
		}		

		m_nBody = pPlayer->GetBody();
	}
	else
	{
		// overwrite network origin so later interpolation will
		// use this position
		SetNetworkOrigin( m_vecRagdollOrigin );

		SetAbsOrigin( m_vecRagdollOrigin );
		SetAbsVelocity( m_vecRagdollVelocity );

		Interp_Reset( GetVarMapping() );

	}

	SetModelIndex( m_nModelIndex );
	
	// Turn it into a ragdoll.
	if ( cl_ragdoll_physics_enable.GetInt() )
	{
		// Make us a ragdoll..
		//m_nRenderFX = kRenderFxRagdoll;
		//SetRenderMode(kRenderFxRagdoll);

		matrix3x4a_t boneDelta0[MAXSTUDIOBONES];
		matrix3x4a_t boneDelta1[MAXSTUDIOBONES];
		matrix3x4a_t currentBones[MAXSTUDIOBONES];
		const float boneDt = 0.05f;

		if ( pPlayer && pPlayer == C_BasePlayer::GetLocalPlayer() )
		{
			pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
		}
		else
		{
			GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
		}

		InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt );
	}
	else
	{
		//ClientLeafSystem()->SetRenderGroup( GetRenderHandle(), RENDER_GROUP_TRANSLUCENT_ENTITY );
	}		

	// Fade out the ragdoll in a while
	StartFadeOut( cl_ragdoll_fade_time.GetFloat() );
	SetNextClientThink( gpGlobals->curtime + 5.0f );
}
void C_SDKRootPanel::RenderDeathFrame( void )
{
	int iWidth = ScreenWidth();
	int iHeight = ScreenHeight();

	int iTopBarHeight = 150;
	int iBottomBarHeight = 75;

	surface()->DrawSetColor(Color(0, 0, 0, 255));
	surface()->DrawFilledRect( 0, 0, iWidth, iTopBarHeight );
	surface()->DrawFilledRect( 0, iHeight-iBottomBarHeight, iWidth, iHeight );

	if (m_hDeathFrameLarge == vgui::INVALID_FONT)
	{
		vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
		vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( scheme );
		m_hDeathFrameLarge = pScheme->GetFont("DeathFrameLarge", false);
		m_hDeathFrameMedium = pScheme->GetFont("DeathFrameMedium", false);
		m_hDeathFrameSmall = pScheme->GetFont("DeathFrameSmall", false);
	}

	std::wstring sKilledBy;

	C_SDKPlayer* pPlayer = C_SDKPlayer::GetLocalOrSpectatedPlayer();
	C_SDKPlayer* pKiller = pPlayer->GetKiller();

	if (!m_flKilledByStartTime)
		m_flKilledByStartTime = gpGlobals->curtime;

	float flLerpTime = da_deathframe_lerp_time.GetFloat();

	wchar_t* pszScreenshot = g_pVGuiLocalize->Find("#DA_DeathFrame_Screenshot");

	if (pszScreenshot)
	{
		wchar_t szScreenshot[512];
		UTIL_ReplaceKeyBindings( pszScreenshot, wcslen(pszScreenshot)*sizeof(wchar_t), szScreenshot, sizeof( szScreenshot ) );

		float flXOffset = RemapValClamped(Bias(RemapValClamped(gpGlobals->curtime, m_flKilledByStartTime + 0.5f, m_flKilledByStartTime + 0.5f + flLerpTime, 0, 1), 0.8f), 0, 1, -iWidth*2/3, 0);

		int iWide, iTall;
		surface()->GetTextSize(m_hDeathFrameSmall, pszScreenshot, iWide, iTall);
		surface()->DrawSetTextFont(m_hDeathFrameSmall);
		surface()->DrawSetTextPos(10 + flXOffset, 10);
		surface()->DrawSetTextColor(Color(255, 255, 255, 255));
		surface()->DrawPrintText(szScreenshot, wcslen(szScreenshot));
	}

	if (pKiller != pPlayer)
	{
		wchar_t* pszKilledBy = g_pVGuiLocalize->Find("#DA_DeathFrame_KilledBy");

		float flKilledByXOffset = RemapValClamped(Bias(RemapValClamped(gpGlobals->curtime, m_flKilledByStartTime, m_flKilledByStartTime + flLerpTime, 0, 1), 0.8f), 0, 1, -iWidth*2/3, 0);

		if (pszKilledBy)
		{
			int iWide, iTall;
			surface()->GetTextSize(m_hDeathFrameLarge, pszKilledBy, iWide, iTall);
			surface()->DrawSetTextFont(m_hDeathFrameLarge);
			surface()->DrawSetTextPos(flKilledByXOffset + iWidth/2 - iWide/2, 10);
			surface()->DrawSetTextColor(Color(255, 255, 255, 255));
			surface()->DrawPrintText(pszKilledBy, wcslen(pszKilledBy));
		}

		wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
		if (pKiller)
			g_pVGuiLocalize->ConvertANSIToUnicode( pKiller->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) );
		else
		{
			wchar_t* pszTheGround;
			switch (((int)m_flKilledByStartTime)%3) // Effectively a random number.
			{
			case 0:
			default:
				pszTheGround = g_pVGuiLocalize->Find("#DA_DeathFrame_TheGround");
				break;

			case 1:
				pszTheGround = g_pVGuiLocalize->Find("#DA_DeathFrame_SuddenStop");
				break;

			case 2:
				pszTheGround = g_pVGuiLocalize->Find("#DA_DeathFrame_Gravity");
				break;
			}

			if (pszTheGround)
				wcscpy(wszPlayerName, pszTheGround);
			else
				wcscpy(wszPlayerName, L"The Ground");
		}

		int iWide, iTall;
		surface()->GetTextSize(m_hDeathFrameLarge, wszPlayerName, iWide, iTall);
		surface()->DrawSetTextFont(m_hDeathFrameLarge);
		surface()->DrawSetTextPos(flKilledByXOffset + iWidth/2 - iWide/2, 20 + surface()->GetFontTall(m_hDeathFrameLarge));
		surface()->DrawSetTextColor(Color(255, 255, 255, 255));
		surface()->DrawPrintText(wszPlayerName, wcslen(wszPlayerName));
	}

	float flWeaponXOffset = RemapValClamped(Bias(RemapValClamped(gpGlobals->curtime, m_flKilledByStartTime + 0.2f, m_flKilledByStartTime + 0.2f + flLerpTime, 0, 1), 0.8f), 0, 1, iWidth*2/3, 0);

	wchar_t* pszWeaponOfChoice = g_pVGuiLocalize->Find("#DA_DeathFrame_WeaponOfChoice");

	if (pKiller && pszWeaponOfChoice && pKiller->GetActiveSDKWeapon())
	{
		wchar_t* pszWeaponName = g_pVGuiLocalize->Find(pKiller->GetActiveSDKWeapon()->GetPrintName());
		if (pszWeaponName)
		{
			std::wstring sMessage = std::wstring(pszWeaponOfChoice) + pszWeaponName;

			int iWide, iTall;
			surface()->GetTextSize(m_hDeathFrameMedium, sMessage.c_str(), iWide, iTall);
			surface()->DrawSetTextFont(m_hDeathFrameMedium);
			surface()->DrawSetTextPos(flWeaponXOffset + iWidth/2 - iWide/2, iHeight - iTall - 20);
			surface()->DrawSetTextColor(Color(255, 255, 255, 255));
			surface()->DrawPrintText(sMessage.c_str(), sMessage.length());
		}
	}
}
Пример #11
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_FuncPhysicsRespawnZone::ClientThink( void )
{
	RespawnProps();

	SetNextClientThink( gpGlobals->curtime + (cl_phys_props_respawnrate.GetFloat() * RandomFloat(1.0,1.1)) );
}
Пример #12
0
//-----------------------------------------------------------------------------
// Purpose: Breaks the breakable. m_hBreaker is the entity that caused us to break.
//-----------------------------------------------------------------------------
void CBreakable::Die( void )
{
	Vector vecVelocity;// shard velocity
	char cFlag = 0;
	int pitch;
	float fvol;
	
	pitch = 95 + random->RandomInt(0,29);

	if (pitch > 97 && pitch < 103)
	{
		pitch = 100;
	}

	// The more negative m_iHealth, the louder
	// the sound should be.

	fvol = random->RandomFloat(0.85, 1.0) + (abs(m_iHealth.Get()) / 100.0);
	if (fvol > 1.0)
	{
		fvol = 1.0;
	}

	const char *soundname = NULL;

	switch (m_Material)
	{
	default:
		break;

	case matGlass:
		soundname = "Breakable.Glass";
		cFlag = BREAK_GLASS;
		break;

	case matWood:
		soundname = "Breakable.Crate";
		cFlag = BREAK_WOOD;
		break;

	case matComputer:
		soundname = "Breakable.Computer";
		cFlag = BREAK_METAL;
		break;

	case matMetal:
		soundname = "Breakable.Metal";
		cFlag = BREAK_METAL;
		break;

	case matFlesh:
	case matWeb:
		soundname = "Breakable.Flesh";
		cFlag = BREAK_FLESH;
		break;

	case matRocks:
	case matCinderBlock:
		soundname = "Breakable.Concrete";
		cFlag = BREAK_CONCRETE;
		break;

	case matCeilingTile:
		soundname = "Breakable.Ceiling";
		break;
	}
    
	if ( soundname )
	{
		if ( m_hBreaker && m_hBreaker->IsPlayer() )
		{
			IGameEvent * event = gameeventmanager->CreateEvent( "break_breakable" );
			if ( event )
			{
				event->SetInt( "userid", ToBasePlayer( m_hBreaker )->GetUserID() );
				event->SetInt( "entindex", entindex() );
				event->SetInt( "material", cFlag );
				gameeventmanager->FireEvent( event );
			}
		}

		CSoundParameters params;
		if ( GetParametersForSound( soundname, params, NULL ) )
		{
			CPASAttenuationFilter filter( this );

			EmitSound_t ep;
			ep.m_nChannel = params.channel;
			ep.m_pSoundName = params.soundname;
			ep.m_flVolume = fvol;
			ep.m_SoundLevel = params.soundlevel;
			ep.m_nPitch = pitch;

			EmitSound( filter, entindex(), ep );	
		}
	}
		
	switch( m_Explosion )
	{
	case expDirected:
		vecVelocity = g_vecAttackDir * -200;
		break;

	case expUsePrecise:
		{
			AngleVectors( m_GibDir, &vecVelocity, NULL, NULL );
			vecVelocity *= 200;
		}
		break;

	case expRandom:
		vecVelocity.x = 0;
		vecVelocity.y = 0;
		vecVelocity.z = 0;
		break;

	default:
		DevMsg("**ERROR - Unspecified gib dir method in func_breakable!\n");
		break;
	}

	Vector vecSpot = WorldSpaceCenter();
	CPVSFilter filter2( vecSpot );

	int iModelIndex = 0;
	CCollisionProperty *pCollisionProp = CollisionProp();

	Vector vSize = pCollisionProp->OBBSize();
	int iCount = ( vSize[0] * vSize[1] + vSize[1] * vSize[2] + vSize[2] * vSize[0] ) / ( 3 * 12 * 12 );

	if ( iCount > func_break_max_pieces.GetInt() )
	{
		iCount = func_break_max_pieces.GetInt();
	}

	if ( !breakable_disable_gib_limit.GetBool() && iCount )
	{
		if ( m_PerformanceMode == PM_NO_GIBS )
		{
			iCount = 0;
		}
		else if ( m_PerformanceMode == PM_REDUCED_GIBS )
		{
			int iNewCount = iCount * func_break_reduction_factor.GetFloat();
			iCount = MAX( iNewCount, 1 );
		}
	}

	if ( m_iszModelName != NULL_STRING )
	{
		for ( int i = 0; i < iCount; i++ )
		{
			iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel(  STRING( m_iszModelName ) ) );

			// All objects except the first one in this run are marked as slaves...
			int slaveFlag = 0;
			if ( i != 0 )
			{
				slaveFlag = BREAK_SLAVE;
			}

			te->BreakModel( filter2, 0.0, 
				vecSpot, pCollisionProp->GetCollisionAngles(), vSize, 
				vecVelocity, iModelIndex, 100, 1, 2.5, cFlag | slaveFlag );
		}
	}

	ResetOnGroundFlags();

	// Don't fire something that could fire myself
	SetName( NULL_STRING );

	AddSolidFlags( FSOLID_NOT_SOLID );
	
	// Fire targets on break
	m_OnBreak.FireOutput( m_hBreaker, this );

	VPhysicsDestroyObject();
	SetThink( &CBreakable::SUB_Remove );
	SetNextThink( gpGlobals->curtime + 0.1f );
	if ( m_iszSpawnObject != NULL_STRING )
	{
		CBaseEntity::Create( STRING(m_iszSpawnObject), vecSpot, pCollisionProp->GetCollisionAngles(), this );
	}

	if ( Explodable() )
	{
		ExplosionCreate( vecSpot, pCollisionProp->GetCollisionAngles(), this, GetExplosiveDamage(), GetExplosiveRadius(), true );
	}
}
Пример #13
0
void CASW_Health_Regen::Think()
{
	BaseClass::Think();
	CBaseEntity* pEntity = NULL;
	while ((pEntity = gEntList.FindEntityByClassname( pEntity, "asw_marine" )) != NULL)
	{
		CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(pEntity);
		if (pMarine)
		{
			int cur_health = pMarine->GetHealth();
			int max_health = pMarine->GetMaxHealth();
			int regen_ammount = rm_health_regen_amount.GetInt();

			if (cur_health < max_health)
			{
				//Check if this marine is dead.
				if (cur_health < 1)
					continue;
				
				int result_health = cur_health + regen_ammount;
				if (result_health > max_health)
					result_health = max_health;
				
// 				if (pMarine->m_bKnockedOut)
// 				{
// 					result_health = cur_health - 3;
// 					if (result_health <= 0)
// 					{
// 						CTakeDamageInfo info(
// 							pMarine, 
// 							pMarine, 
// 							Vector(0,0,0), 
// 							GetAbsOrigin(), 
// 							100, 
// 							DMG_NEVERGIB);
// 						pMarine->TakeDamage(info);
// 					}
// 					else
// 					{
// 						pMarine->SetHealth(result_health);
// 					}
// 				}
// 				else
// 				{
					if (!pMarine->m_bKnockedOut && ASWGameRules()->m_iHpRegen)
						pMarine->SetHealth(result_health);

					// riflemod: incapacitated marines have decreasing hp
					if (pMarine->m_bKnockedOut)
					{
						int decreased_hp = pMarine->GetHealth() - rm_health_decrease_amount.GetInt();
						if (decreased_hp <= 0)
						{
							pMarine->SetKnockedOut(false);
							pMarine->SetHealth(1);
							// HACK
							int allow_revive = ASWGameRules()->m_iAllowRevive;
							ASWGameRules()->m_iAllowRevive = 0;
							CTakeDamageInfo info(this, this, Vector(0, 0, 0), GetAbsOrigin(), 100,
								DMG_NEVERGIB);
							pMarine->TakeDamage(info);
							ASWGameRules()->m_iAllowRevive = allow_revive;
						}
						else
							pMarine->SetHealth(decreased_hp);

					}
//				}
			}
		}
	}

	SetNextThink( gpGlobals->curtime + rm_health_regen_interval.GetFloat());
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponLaserRifle::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = ToBaseTFPlayer( m_hOwner );
	if ( !pPlayer )
		return;
	
	if ( !ComputeEMPFireState() )
		return;

	WeaponSound(SINGLE);

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	pPlayer->m_fEffects |= EF_MUZZLEFLASH;

	// Fire the beam: BLOW OFF AUTOAIM
	Vector vecSrc	 = pPlayer->Weapon_ShootPosition( pPlayer->GetOrigin() );
	Vector vecAiming, right, up;
	pPlayer->EyeVectors( &vecAiming, &right, &up);

	Vector vecSpread = VECTOR_CONE_4DEGREES;

	// Get endpoint
	float x, y, z;
	do {
		x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
		y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
		z = x*x+y*y;
	} while (z > 1);
	Vector vecDir = vecAiming + x * vecSpread.x * right + y * vecSpread.y * up;
	Vector vecEnd = vecSrc + vecDir * weapon_laserrifle_range.GetFloat();

	trace_t tr;
	float damagefactor = TFGameRules()->WeaponTraceLine(vecSrc, vecEnd, MASK_SHOT, pPlayer, DMG_ENERGYBEAM, &tr);

	// Hit target?
	if (tr.fraction != 1.0)
	{
		CBaseEntity *pEntity = CBaseEntity::Instance(tr.u.ent);
		if ( pEntity )
		{
			ClearMultiDamage();
			float flDamage = GetDamage( (tr.endpos - vecSrc).Length(), tr.hitgroup );
			flDamage *= damagefactor;  
			pEntity->TraceAttack( CTakeDamageInfo( pPlayer, pPlayer, flDamage, DMG_ENERGYBEAM ), vecDir, &tr );
			ApplyMultiDamage( pPlayer, pPlayer );
		}

		g_pEffects->EnergySplash( tr.endpos, tr.plane.normal );
	}

	// Get hacked gun position
	AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL );
	Vector vecTracerSrc = vecSrc + Vector (0,0,-8) + right * 12 + vecDir * 16;

	// Laser beam
	CBroadcastRecipientFilter filter;
	te->BeamPoints( filter, 0.0,
					&vecTracerSrc, 
					&tr.endpos, 
					m_iSpriteTexture, 
					0,		// Halo index
					0,		// Start frame
					0,		// Frame rate
					0.2,	// Life
					15,		// Width
					15,		// EndWidth
					0,		// FadeLength
					0,		// Amplitude
					200,	// r
					200,	// g
					255,	// b
					255,	// a
					255	);	// speed

	pPlayer->m_iAmmo[m_iPrimaryAmmoType]--;
	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();

	CheckRemoveDisguise();
}
Пример #15
0
void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd )
{
	if ( m_hClosestNPC == NULL )
	{
		if ( m_flSpeedMod != cl_forwardspeed.GetFloat() )
		{
			float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
			m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() );
		}
	}
	else
	{
		C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() );

		if ( pNPC )
		{
			float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();
			bool bShouldModSpeed = false; 

			// Within range?
			if ( flDist < pNPC->GetSpeedModifyRadius() )
			{
				// Now, only slowdown if we're facing & running parallel to the target's movement
				// Facing check first (in 2D)
				Vector vecTargetOrigin = pNPC->GetAbsOrigin();
				Vector los = ( vecTargetOrigin - EyePosition() );
				los.z = 0;
				VectorNormalize( los );
				Vector facingDir;
				AngleVectors( GetAbsAngles(), &facingDir );
				float flDot = DotProduct( los, facingDir );
				if ( flDot > 0.8 )
				{
					/*
					// Velocity check (abort if the target isn't moving)
					Vector vecTargetVelocity;
					pNPC->EstimateAbsVelocity( vecTargetVelocity );
					float flSpeed = VectorNormalize(vecTargetVelocity);
					Vector vecMyVelocity = GetAbsVelocity();
					VectorNormalize(vecMyVelocity);
					if ( flSpeed > 1.0 )
					{
						// Velocity roughly parallel?
						if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4  )
						{
							bShouldModSpeed = true;
						}
					} 
					else
					{
						// NPC's not moving, slow down if we're moving at him
						//Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) );
						if ( DotProduct( los, vecMyVelocity ) > 0.8 )
						{
							bShouldModSpeed = true;
						} 
					}
					*/

					bShouldModSpeed = true;
				}
			}

			if ( !bShouldModSpeed )
			{
				m_hClosestNPC = NULL;
				m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat();
				m_flExitSpeedMod = m_flSpeedMod;
				return;
			}
			else 
			{
				if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() )
				{
					float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
					m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() );
				}
			}
		}
	}

	if ( pCmd->forwardmove > 0.0f )
	{
		pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
	}
	else
	{
		pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
	}
	pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod );
   
	//Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove );
}
Пример #16
0
void C_SDKPlayer::AvoidPlayers( CUserCmd *pCmd )
{
// Player Avoidance is only active with teams
#if defined ( SDK_USE_TEAMS )
	// Don't test if the player doesn't exist or is dead.
	if ( IsAlive() == false )
		return;

	C_SDKTeam *pTeam = ( C_SDKTeam * )GetTeam();
	if ( !pTeam )
		return;

	// Up vector.
	static Vector vecUp( 0.0f, 0.0f, 1.0f );

	Vector vecSDKPlayerCenter = GetAbsOrigin();
	Vector vecSDKPlayerMin = GetPlayerMins();
	Vector vecSDKPlayerMax = GetPlayerMaxs();
	float flZHeight = vecSDKPlayerMax.z - vecSDKPlayerMin.z;
	vecSDKPlayerCenter.z += 0.5f * flZHeight;
	VectorAdd( vecSDKPlayerMin, vecSDKPlayerCenter, vecSDKPlayerMin );
	VectorAdd( vecSDKPlayerMax, vecSDKPlayerCenter, vecSDKPlayerMax );

	// Find an intersecting player or object.
	int nAvoidPlayerCount = 0;
	C_SDKPlayer *pAvoidPlayerList[MAX_PLAYERS];

	C_SDKPlayer *pIntersectPlayer = NULL;
	float flAvoidRadius = 0.0f;

	Vector vecAvoidCenter, vecAvoidMin, vecAvoidMax;
	for ( int i = 0; i < pTeam->GetNumPlayers(); ++i )
	{
		C_SDKPlayer *pAvoidPlayer = static_cast< C_SDKPlayer * >( pTeam->GetPlayer( i ) );
		if ( pAvoidPlayer == NULL )
			continue;
		// Is the avoid player me?
		if ( pAvoidPlayer == this )
			continue;

		// Save as list to check against for objects.
		pAvoidPlayerList[nAvoidPlayerCount] = pAvoidPlayer;
		++nAvoidPlayerCount;

		// Check to see if the avoid player is dormant.
		if ( pAvoidPlayer->IsDormant() )
			continue;

		// Is the avoid player solid?
		if ( pAvoidPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) )
			continue;

		Vector t1, t2;

		vecAvoidCenter = pAvoidPlayer->GetAbsOrigin();
		vecAvoidMin = pAvoidPlayer->GetPlayerMins();
		vecAvoidMax = pAvoidPlayer->GetPlayerMaxs();
		flZHeight = vecAvoidMax.z - vecAvoidMin.z;
		vecAvoidCenter.z += 0.5f * flZHeight;
		VectorAdd( vecAvoidMin, vecAvoidCenter, vecAvoidMin );
		VectorAdd( vecAvoidMax, vecAvoidCenter, vecAvoidMax );

		if ( IsBoxIntersectingBox( vecSDKPlayerMin, vecSDKPlayerMax, vecAvoidMin, vecAvoidMax ) )
		{
			// Need to avoid this player.
			if ( !pIntersectPlayer )
			{
				pIntersectPlayer = pAvoidPlayer;
				break;
			}
		}
	}

	// Anything to avoid?
	if ( !pIntersectPlayer )
		return;

	// Calculate the push strength and direction.
	Vector vecDelta;

	// Avoid a player - they have precedence.
	if ( pIntersectPlayer )
	{
		VectorSubtract( pIntersectPlayer->WorldSpaceCenter(), vecSDKPlayerCenter, vecDelta );

		Vector vRad = pIntersectPlayer->WorldAlignMaxs() - pIntersectPlayer->WorldAlignMins();
		vRad.z = 0;

		flAvoidRadius = vRad.Length();
	}

	float flPushStrength = RemapValClamped( vecDelta.Length(), flAvoidRadius, 0, 0, sdk_max_separation_force.GetInt() ); //flPushScale;

	//Msg( "PushScale = %f\n", flPushStrength );

	// Check to see if we have enough push strength to make a difference.
	if ( flPushStrength < 0.01f )
		return;

	Vector vecPush;
	if ( GetAbsVelocity().Length2DSqr() > 0.1f )
	{
		Vector vecVelocity = GetAbsVelocity();
		vecVelocity.z = 0.0f;
		CrossProduct( vecUp, vecVelocity, vecPush );
		VectorNormalize( vecPush );
	}
	else
	{
		// We are not moving, but we're still intersecting.
		QAngle angView = pCmd->viewangles;
		angView.x = 0.0f;
		AngleVectors( angView, NULL, &vecPush, NULL );
	}

	// Move away from the other player/object.
	Vector vecSeparationVelocity;
	if ( vecDelta.Dot( vecPush ) < 0 )
	{
		vecSeparationVelocity = vecPush * flPushStrength;
	}
	else
	{
		vecSeparationVelocity = vecPush * -flPushStrength;
	}

	// Don't allow the MAX push speed to be greater than the MAX player speed.
	float flMaxPlayerSpeed = MaxSpeed();
	float flCropFraction = 1.33333333f;

	if ( ( GetFlags() & FL_DUCKING ) && ( GetGroundEntity() != NULL ) )
	{	
		flMaxPlayerSpeed *= flCropFraction;
	}	

	float flMaxPlayerSpeedSqr = flMaxPlayerSpeed * flMaxPlayerSpeed;

	if ( vecSeparationVelocity.LengthSqr() > flMaxPlayerSpeedSqr )
	{
		vecSeparationVelocity.NormalizeInPlace();
		VectorScale( vecSeparationVelocity, flMaxPlayerSpeed, vecSeparationVelocity );
	}

	QAngle vAngles = pCmd->viewangles;
	vAngles.x = 0;
	Vector currentdir;
	Vector rightdir;

	AngleVectors( vAngles, &currentdir, &rightdir, NULL );

	Vector vDirection = vecSeparationVelocity;

	VectorNormalize( vDirection );

	float fwd = currentdir.Dot( vDirection );
	float rt = rightdir.Dot( vDirection );

	float forward = fwd * flPushStrength;
	float side = rt * flPushStrength;

	//Msg( "fwd: %f - rt: %f - forward: %f - side: %f\n", fwd, rt, forward, side );

	pCmd->forwardmove	+= forward;
	pCmd->sidemove		+= side;

	// Clamp the move to within legal limits, preserving direction. This is a little
	// complicated because we have different limits for forward, back, and side

	//Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );

	float flForwardScale = 1.0f;
	if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
	{
		flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
	}
	else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
	{
		flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
	}

	float flSideScale = 1.0f;
	if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
	{
		flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
	}

	float flScale = MIN( flForwardScale, flSideScale );
	pCmd->forwardmove *= flScale;
	pCmd->sidemove *= flScale;

	//Msg( "Pforwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
#endif
}
void CWeaponIFMSteadyCam::UpdateRelativeOrientation()
{
	if ( m_bIsLocked )
		return;

	if ( m_bInDirectMode )
	{
		UpdateDirectRelativeOrientation();
		return;
	}

	if ( ( m_vecViewOffset.x == 0.0f ) && ( m_vecViewOffset.y == 0.0f ) )
		return;

	// Compute a player to steadycam matrix
	VMatrix steadyCamToPlayer;
	MatrixFromAngles( m_angRelativeAngles, steadyCamToPlayer );
	MatrixSetColumn( steadyCamToPlayer, 3, m_vecRelativePosition );

	Vector vecCurrentForward;
	MatrixGetColumn( steadyCamToPlayer, 0, &vecCurrentForward );

	// Create a ray in steadycam space
	float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f );

	// Remap offsets into normalized space
	float flViewX = m_vecViewOffset.x / ( 384 / 2 );
	float flViewY = m_vecViewOffset.y / ( 288 / 2 );

	flViewX *= flMaxD * ifm_steadycam_mousefactor.GetFloat();
	flViewY *= flMaxD * ifm_steadycam_mousefactor.GetFloat();
				    
	Vector vecSelectionDir( 1.0f, -flViewX, -flViewY );
	VectorNormalize( vecSelectionDir );

	// Rotate the ray into player coordinates
	Vector vecDesiredDirection;
	Vector3DMultiply( steadyCamToPlayer, vecSelectionDir, vecDesiredDirection );

	float flDot = DotProduct( vecDesiredDirection, vecCurrentForward );
	flDot = clamp( flDot, -1.0f, 1.0f );
	float flAngle = 180.0f * acos( flDot ) / M_PI;
	if ( flAngle < 1e-3 )
	{
		matrix3x4_t mat;
		MatrixFromForwardDirection( vecDesiredDirection, mat );
		MatrixAngles( mat, m_angRelativeAngles );
		return;
	}

	Vector vecAxis;
	CrossProduct( vecCurrentForward, vecDesiredDirection, vecAxis );
	VectorNormalize( vecAxis );
	
	float flRotateRate = ifm_steadycam_rotaterate.GetFloat();
	if ( flRotateRate < 1.0f )
	{
		flRotateRate = 1.0f;
	}

	float flRateFactor = flAngle / flRotateRate;
	flRateFactor *= flRateFactor * flRateFactor;
	float flRate = flRateFactor * 30.0f;
	float flMaxAngle = gpGlobals->frametime * flRate;
	flAngle = clamp( flAngle, 0.0f, flMaxAngle );

	Vector vecNewForard;
	VMatrix rotation;
	MatrixBuildRotationAboutAxis( rotation, vecAxis, flAngle ); 
	Vector3DMultiply( rotation, vecCurrentForward, vecNewForard );

	matrix3x4_t mat;
	MatrixFromForwardDirection( vecNewForard, mat );
	MatrixAngles( mat, m_angRelativeAngles );

	Assert( m_angRelativeAngles.IsValid() );
}
Пример #18
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CASW_PropJeep::CanExitVehicle( CBaseEntity *pEntity )
{
	return ( !m_bEnterAnimOn && !m_bExitAnimOn && !m_bLocked && (m_nSpeed <= asw_g_jeepexitspeed.GetFloat() ) );
}
ActionResult<CTFBot> CTFBotCapturePoint::Update(CTFBot *actor, float dt)
{
	if (TFGameRules()->InSetup()) {
		this->m_PathFollower.Invalidate();
		this->m_ctRecomputePath.Start(RandomFloat(1.0f, 2.0f));
		
		return ActionResult<CTFBot>::Continue();
	}
	
	CTeamControlPoint *point = actor->GetMyControlPoint();
	if (point == nullptr) {
		return ActionResult<CTFBot>::SuspendFor(new CTFBotSeekAndDestroy(10.0f),
			"Seek and destroy until a point becomes available");
	}
	
	if (point->GetTeamNumber() == actor->GetTeamNumber()) {
		return ActionResult<CTFBot>::ChangeTo(new CTFBotDefendPoint(),
			"We need to defend our point(s)");
	}
	
	const CKnownEntity *threat = actor->GetVisionInterface()->GetPrimaryKnownThreat(false);
	if (threat != nullptr && threat->IsVisibleRecently()) {
		actor->EquipBestWeaponForThreat(threat);
	}
	
	if ((!actor->IsPointBeingCaptured(point) || actor->GetTimeSinceWeaponFired() < 2.0f) &&
		!actor->IsCapturingPoint() && !TFGameRules()->InOvertime() &&
		actor->GetTimeLeftToCapture() >= tf_bot_offense_must_push_time.GetFloat() &&
		!TFGameRules()->IsInTraining() && !actor->IsNearPoint(point) &&
		threat != nullptr && threat->IsVisibleRecently()) {
		float duration = RandomFloat(tf_bot_capture_seek_and_destroy_min_duration.GetFloat(),
			tf_bot_capture_seek_and_destroy_max_duration.GetFloat());
		
		return ActionResult<CTFBot>::SuspendFor(new CTFBotSeekAndDestroy(duration),
			"Too early to capture - hunting");
	}
	
	if (actor->IsCapturingPoint()) {
		if (point->GetPointIndex() > 7) {
			return ActionResult<CTFBot>::Continue();
		}
		
		// TODO
		
		// ...
		
		// Path::Compute
	}
	
	if (this->m_ctRecomputePath.IsElapsed()) {
		VPROF_BUDGET("CTFBotCapturePoint::Update( repath )", "NextBot");
		
		CTFBotPathCost cost_func(actor, SAFEST_ROUTE);
		this->m_PathFollower.Compute(actor, point->GetAbsOrigin(), cost_func, 0.0f, true);
		
		this->m_ctRecomputePath.Start(RandomFloat(2.0f, 3.0f));
	}
	
	if (TFGameRules()->IsInTraining() && !actor->IsAnyPointBeingCaptured() &&
		this->m_PathFollower.GetLength() < 1000.0f) {
		actor->SpeakConceptIfAllowed(MP_CONCEPT_PLAYER_GO);
	} else {
		this->m_PathFollower.Update(actor);
	}
	
	return ActionResult<CTFBot>::Continue();
}
Пример #20
0
static void ScaleChangeCallback_f( ConVar *var, char const *pOldString )
{
	g_ViewportScale = mat_viewportscale.GetFloat();
	g_ViewportOOScale = 1.0f / g_ViewportScale;
	g_nFrameBuffersToClear = 3;
}
void CRecharge::Recharge(void)
{
	m_iJuice = sk_suitcharger.GetFloat();
	SetTextureFrameIndex( 0 );
	SetThink( SUB_DoNothing );
}
Пример #22
0
//-----------------------------------------------------------------------------
// Purpose: Returns a pointer to a healable target
//-----------------------------------------------------------------------------
bool CWeaponMedigun::FindAndHealTargets( void )
{
	CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() );
	if ( !pOwner )
		return false;

	bool bFound = false;

	// Maintaining beam to existing target?
	CBaseEntity *pTarget = m_hHealingTarget;
	if ( pTarget && pTarget->IsAlive() )
	{
		MaintainTargetInSlot();
	}
	else
	{	
		FindNewTargetForSlot();
	}

	CBaseEntity *pNewTarget = m_hHealingTarget;
	if ( pNewTarget && pNewTarget->IsAlive() )
	{
		CTFPlayer *pTFPlayer = ToTFPlayer( pNewTarget );

#ifdef GAME_DLL
		// HACK: For now, just deal with players
		if ( pTFPlayer )
		{
			if ( pTarget != pNewTarget && pNewTarget->IsPlayer() )
			{
				pTFPlayer->m_Shared.Heal( pOwner, GetHealRate() );
			}

			pTFPlayer->m_Shared.RecalculateChargeEffects( false );
		}

		if ( m_flReleaseStartedAt && m_flReleaseStartedAt < (gpGlobals->curtime + 0.2) )
		{
			// When we start the release, everyone we heal rockets to full health
			pNewTarget->TakeHealth( pNewTarget->GetMaxHealth(), DMG_GENERIC );
		}
#endif
	
		bFound = true;

		// Charge up our power if we're not releasing it, and our target
		// isn't receiving any benefit from our healing.
		if ( !m_bChargeRelease )
		{
			if ( pTFPlayer )
			{
				int iBoostMax = floor( pTFPlayer->m_Shared.GetMaxBuffedHealth() * 0.95);

				if ( weapon_medigun_charge_rate.GetFloat() )
				{
					float flChargeAmount = gpGlobals->frametime / weapon_medigun_charge_rate.GetFloat();

					// Reduced charge for healing fully healed guys
					if ( pNewTarget->GetHealth() >= iBoostMax && ( TFGameRules() && !TFGameRules()->InSetup() ) )
					{
						flChargeAmount *= 0.5;
					}

					int iTotalHealers = pTFPlayer->m_Shared.GetNumHealers();
					if ( iTotalHealers > 1 )
					{
						flChargeAmount /= (float)iTotalHealers;
					}

					float flNewLevel = min( m_flChargeLevel + flChargeAmount, 1.0 );
#ifdef GAME_DLL
					if ( flNewLevel >= 1.0 && m_flChargeLevel < 1.0 )
					{
						pOwner->SpeakConceptIfAllowed( MP_CONCEPT_MEDIC_CHARGEREADY );

						if ( pTFPlayer )
						{
							pTFPlayer->SpeakConceptIfAllowed( MP_CONCEPT_HEALTARGET_CHARGEREADY );
						}
					}
#endif
					m_flChargeLevel = flNewLevel;
				}
			}
		}
	}

	return bFound;
}
Пример #23
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Crow::Spawn( void )
{
	BaseClass::Spawn();

#ifdef _XBOX
	// Always fade the corpse
	AddSpawnFlags( SF_NPC_FADE_CORPSE );
#endif // _XBOX

	char *szModel = (char *)STRING( GetModelName() );
	if (!szModel || !*szModel)
	{
		szModel = "models/crow.mdl";
		SetModelName( AllocPooledString(szModel) );
	}

	Precache();
	SetModel( szModel );

	m_iHealth = sk_crow_health.GetFloat();

	SetHullType(HULL_TINY);
	SetHullSizeNormal();

	SetSolid( SOLID_BBOX );
	SetMoveType( MOVETYPE_STEP );

	m_flFieldOfView = VIEW_FIELD_FULL;
	SetViewOffset( Vector(6, 0, 11) );		// Position of the eyes relative to NPC's origin.

	m_flGroundIdleMoveTime = gpGlobals->curtime + random->RandomFloat( 0.0f, 5.0f );

	SetBloodColor( BLOOD_COLOR_RED );
	m_NPCState = NPC_STATE_NONE;

	m_nMorale = random->RandomInt( 0, 12 );
	
	SetCollisionGroup( HL2COLLISION_GROUP_CROW );

	CapabilitiesClear();

	bool bFlying = ( ( m_spawnflags & SF_CROW_FLYING ) != 0 );
	SetFlyingState( bFlying ? FlyState_Flying : FlyState_Walking );

	// We don't mind zombies so much. They smell good!
	AddClassRelationship( CLASS_ZOMBIE, D_NU, 0 );

	m_bSoar = false;
	m_bOnJeep = false;
	m_flSoarTime = gpGlobals->curtime;

	NPCInit();

	m_iBirdType = BIRDTYPE_CROW;

	m_vLastStoredOrigin = vec3_origin;
	m_flLastStuckCheck = gpGlobals->curtime;

	m_flDangerSoundTime = gpGlobals->curtime;

	SetGoalEnt( NULL );
}
Пример #24
0
//-----------------------------------------------------------------------------
// Purpose: Overloaded to handle the hold-down healing
//-----------------------------------------------------------------------------
void CWeaponMedigun::ItemPostFrame( void )
{
	CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() );
	if ( !pOwner )
		return;

	// If we're lowered, we're not allowed to fire
	if ( CanAttack() == false )
	{
		RemoveHealingTarget( true );
		return;
	}

#if !defined( CLIENT_DLL )
	if ( AppliesModifier() )
	{
		m_DamageModifier.SetModifier( weapon_medigun_damage_modifier.GetFloat() );
	}
#endif

	// Try to start healing
	m_bAttacking = false;
	if ( pOwner->GetMedigunAutoHeal() )
	{
		if ( pOwner->m_nButtons & IN_ATTACK )
		{
			if ( m_bCanChangeTarget )
			{
				RemoveHealingTarget();
#if defined( CLIENT_DLL )
				m_bPlayingSound = false;
				StopHealSound();
#endif
				// can't change again until we release the attack button
				m_bCanChangeTarget = false;
			}
		}
		else
		{
			m_bCanChangeTarget = true;
		}

		if ( m_bHealing || ( pOwner->m_nButtons & IN_ATTACK ) )
		{
			PrimaryAttack();
			m_bAttacking = true;
		}
	}
	else
	{
		if ( /*m_bChargeRelease || */ pOwner->m_nButtons & IN_ATTACK )
		{
			PrimaryAttack();
			m_bAttacking = true;
		}
 		else if ( m_bHealing )
 		{
 			// Detach from the player if they release the attack button.
 			RemoveHealingTarget();
 		}
	}

	if ( pOwner->m_nButtons & IN_ATTACK2 )
	{
		SecondaryAttack();
	}

	WeaponIdle();
}
	virtual float	GetAutoAimRadius( void ) { return striderbuster_autoaim_radius.GetFloat(); }
Пример #26
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAI_FearBehavior::GatherConditions()
{
	BaseClass::GatherConditions();

	ClearCondition( COND_FEAR_ENEMY_CLOSE );
	ClearCondition( COND_FEAR_ENEMY_TOO_CLOSE );
	if( GetEnemy() )
	{
		float flEnemyDistSqr = GetAbsOrigin().DistToSqr(GetEnemy()->GetAbsOrigin());

		if( flEnemyDistSqr < FEAR_ENEMY_TOLERANCE_TOO_CLOSE_DIST_SQR )
		{
			SetCondition( COND_FEAR_ENEMY_TOO_CLOSE );
			if( IsInASafePlace() )
			{
				SpoilSafePlace();
			}
		}
		else if( flEnemyDistSqr < FEAR_ENEMY_TOLERANCE_CLOSE_DIST_SQR && GetEnemy()->GetEnemy() == GetOuter() )	
		{
			// Only become scared of an enemy at this range if they're my enemy, too
			SetCondition( COND_FEAR_ENEMY_CLOSE );
			if( IsInASafePlace() )
			{
				SpoilSafePlace();
			}
		}
	}

	ClearCondition(COND_FEAR_SEPARATED_FROM_PLAYER);

	// Check for separation from the player
	//	-The player is farther away than 60 feet
	//  -I haven't seen the player in 2 seconds
	//
	// Here's the distance check:
	CBasePlayer *pPlayer = AI_GetSinglePlayer();
	if( pPlayer != NULL && GetAbsOrigin().DistToSqr(pPlayer->GetAbsOrigin()) >= Square( ai_fear_player_dist.GetFloat() * 1.5f )  )
	{
		SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER);
	}

	// Here's the visibility check. We can't skip this because it's time-sensitive
	if( GetOuter()->FVisible(pPlayer) )
	{
		m_flTimePlayerLastVisible = gpGlobals->curtime;
	}
	else
	{
		if( gpGlobals->curtime - m_flTimePlayerLastVisible >= 2.0f )
		{
			SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER);
		}
	}

	if( HasCondition(COND_FEAR_SEPARATED_FROM_PLAYER) )
	{
		//Msg("I am separated from player\n");

		if( IsInASafePlace() )
		{
			SpoilSafePlace();
		}
	}
}
Пример #27
0
float DM_GetRespawnWait()
{
	return cssdm_respawn_wait.GetFloat();
}
Пример #28
0
//-----------------------------------------------------------------------------
// Client-side obstacle avoidance
//-----------------------------------------------------------------------------
void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
{
	// Don't avoid if noclipping or in movetype none
	switch ( GetMoveType() )
	{
	case MOVETYPE_NOCLIP:
	case MOVETYPE_NONE:
	case MOVETYPE_OBSERVER:
		return;
	default:
		break;
	}

	// Try to steer away from any objects/players we might interpenetrate
	Vector size = WorldAlignSize();

	float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
	float curspeed = GetLocalVelocity().Length2D();

	//int slot = 1;
	//engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
	//engine->Con_NPrintf( slot++, "radius %f\n", radius );

	// If running, use a larger radius
	float factor = 1.0f;

	if ( curspeed > 150.0f )
	{
		curspeed = MIN( 2048.0f, curspeed );
		factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );

		//engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );

		radius = radius * factor;
	}

	Vector currentdir;
	Vector rightdir;

	QAngle vAngles = pCmd->viewangles;
	vAngles.x = 0;

	AngleVectors( vAngles, &currentdir, &rightdir, NULL );
		
	bool istryingtomove = false;
	bool ismovingforward = false;
	if ( fabs( pCmd->forwardmove ) > 0.0f || 
		fabs( pCmd->sidemove ) > 0.0f )
	{
		istryingtomove = true;
		if ( pCmd->forwardmove > 1.0f )
		{
			ismovingforward = true;
		}
	}

	if ( istryingtomove == true )
		 radius *= 1.3f;

	CPlayerAndObjectEnumerator avoid( radius );
	partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );

	// Okay, decide how to avoid if there's anything close by
	int c = avoid.GetObjectCount();
	if ( c <= 0 )
		return;

	//engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false"  );

	float adjustforwardmove = 0.0f;
	float adjustsidemove	= 0.0f;

	for ( int i = 0; i < c; i++ )
	{
		C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));

		if( !obj )
			continue;

		Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();

		float flDist = vecToObject.Length2D();
		
		// Figure out a 2D radius for the object
		Vector vecWorldMins, vecWorldMaxs;
		obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
		Vector objSize = vecWorldMaxs - vecWorldMins;

		float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );

		//Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
		if ( !obj->IsMoving() && flDist > objectradius )
			  continue;

		if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
		{
			obj->RemoveEffects( EF_NODRAW );
		}

		Vector vecNPCVelocity;
		obj->EstimateAbsVelocity( vecNPCVelocity );
		float flNPCSpeed = VectorNormalize( vecNPCVelocity );

		Vector vPlayerVel = GetAbsVelocity();
		VectorNormalize( vPlayerVel );

		float flHit1, flHit2;
		Vector vRayDir = vecToObject;
		VectorNormalize( vRayDir );

		float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
		float flDirProduct = DotProduct( vRayDir, vPlayerVel );

		if ( !IntersectInfiniteRayWithSphere(
				GetAbsOrigin(),
				vRayDir,
				obj->GetAbsOrigin(),
				radius,
				&flHit1,
				&flHit2 ) )
			continue;

        Vector dirToObject = -vecToObject;
		VectorNormalize( dirToObject );

		float fwd = 0;
		float rt = 0;

		float sidescale = 2.0f;
		float forwardscale = 1.0f;
		bool foundResult = false;

		Vector vMoveDir = vecNPCVelocity;
		if ( flNPCSpeed > 0.001f )
		{
			// This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
			// Start with whatever side they're on relative to the NPC's velocity.
			Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
			int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
			for ( int nTries = 0; nTries < 2; nTries++ )
			{
				Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
				VectorNormalize( vecTryMove );
				
				Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;

				if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
				{
					fwd = currentdir.Dot( vecTryMove );
					rt = rightdir.Dot( vecTryMove );
					
					//Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
					
					foundResult = true;
					break;
				}
				else
				{
					// Try the other direction.
					iDirection *= -1;
				}
			}
		}
		else
		{
			// the object isn't moving, so try moving opposite the way it's facing
			Vector vecNPCForward;
			obj->GetVectors( &vecNPCForward, NULL, NULL );
			
			Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
			if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
			{
				fwd = currentdir.Dot( -vecNPCForward );
				rt = rightdir.Dot( -vecNPCForward );

				if ( flDist < objectradius )
				{
					obj->AddEffects( EF_NODRAW );
				}

				//Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );

				foundResult = true;
			}
		}

		if ( !foundResult )
		{
			// test if we can move in the direction the object is moving
			Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
			if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
			{
				fwd = currentdir.Dot( vMoveDir );
				rt = rightdir.Dot( vMoveDir );

				if ( flDist < objectradius )
				{
					obj->AddEffects( EF_NODRAW );
				}

				//Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );

				foundResult = true;
			}
			else
			{
				// try moving directly away from the object
				Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
				if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
				{
					fwd = currentdir.Dot( -dirToObject );
					rt = rightdir.Dot( -dirToObject );
					foundResult = true;

					//Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
				}
			}
		}

		if ( !foundResult )
		{
			// test if we can move through the object
			Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
			fwd = currentdir.Dot( -vMoveDir );
			rt = rightdir.Dot( -vMoveDir );

			if ( flDist < objectradius )
			{
				obj->AddEffects( EF_NODRAW );
			}

			//Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );

			foundResult = true;
		}

		// If running, then do a lot more sideways veer since we're not going to do anything to
		//  forward velocity
		if ( istryingtomove )
		{
			sidescale = 6.0f;
		}

		if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
		{
			sidescale = 0.1f;
		}

		float force = 1.0f;
		float forward = forwardscale * fwd * force * AVOID_SPEED;
		float side = sidescale * rt * force * AVOID_SPEED;

		adjustforwardmove	+= forward;
		adjustsidemove		+= side;
	}

	pCmd->forwardmove	+= adjustforwardmove;
	pCmd->sidemove		+= adjustsidemove;
	
	// Clamp the move to within legal limits, preserving direction. This is a little
	// complicated because we have different limits for forward, back, and side

	//Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );

	float flForwardScale = 1.0f;
	if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
	{
		flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
	}
	else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
	{
		flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
	}
	
	float flSideScale = 1.0f;
	if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
	{
		flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
	}
	
	float flScale = MIN( flForwardScale, flSideScale );
	pCmd->forwardmove *= flScale;
	pCmd->sidemove *= flScale;

	//Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
}
Пример #29
0
//-----------------------------------------------------------------------------
// Purpose: Render current view into specified rectangle
// Input  : *rect - is computed by CVideoMode_Common::GetClientViewRect()
//-----------------------------------------------------------------------------
void CViewRender::Render( vrect_t *rect )
{
	Assert(s_DbgSetupOrigin == m_View.origin);
	Assert(s_DbgSetupAngles == m_View.angles);

	VPROF_BUDGET( "CViewRender::Render", "CViewRender::Render" );
	tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );

	vrect_t vr = *rect;

	// Stub out the material system if necessary.
	CMatStubHandler matStub;

	engine->EngineStats_BeginFrame();
	
	// Assume normal vis
	m_bForceNoVis			= false;
	
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();


    // Set for console commands, etc.
    render->SetMainView ( m_View.origin, m_View.angles );

    for( StereoEye_t eEye = GetFirstEye(); eEye <= GetLastEye(); eEye = (StereoEye_t)(eEye+1) )
	{
		CViewSetup &view = GetView( eEye );

		#if 0 && defined( CSTRIKE_DLL )
			const bool bPlayingBackReplay = g_pEngineClientReplay && g_pEngineClientReplay->IsPlayingReplayDemo();
			if ( pPlayer && !bPlayingBackReplay )
			{
				C_BasePlayer *pViewTarget = pPlayer;

				if ( pPlayer->IsObserver() && pPlayer->GetObserverMode() == OBS_MODE_IN_EYE )
				{
					pViewTarget = dynamic_cast<C_BasePlayer*>( pPlayer->GetObserverTarget() );
				}

				if ( pViewTarget )
				{
					float targetFOV = (float)pViewTarget->m_iFOV;

					if ( targetFOV == 0 )
					{
						// FOV of 0 means use the default FOV
						targetFOV = g_pGameRules->DefaultFOV();
					}

					float deltaFOV = view.fov - m_flLastFOV;
					float FOVDirection = targetFOV - pViewTarget->m_iFOVStart;

					// Clamp FOV changes to stop FOV oscillation
					if ( ( deltaFOV < 0.0f && FOVDirection > 0.0f ) ||
						( deltaFOV > 0.0f && FOVDirection < 0.0f ) )
					{
						view.fov = m_flLastFOV;
					}

					// Catch case where FOV overshoots its target FOV
					if ( ( view.fov < targetFOV && FOVDirection <= 0.0f ) ||
						( view.fov > targetFOV && FOVDirection >= 0.0f ) )
					{
						view.fov = targetFOV;
					}

					m_flLastFOV = view.fov;
				}
			}
		#endif

	    static ConVarRef sv_restrict_aspect_ratio_fov( "sv_restrict_aspect_ratio_fov" );
	    float aspectRatio = engine->GetScreenAspectRatio() * 0.75f;	 // / (4/3)
	    float limitedAspectRatio = aspectRatio;
	    if ( ( sv_restrict_aspect_ratio_fov.GetInt() > 0 && engine->IsWindowedMode() && gpGlobals->maxClients > 1 ) ||
		    sv_restrict_aspect_ratio_fov.GetInt() == 2 )
	    {
		    limitedAspectRatio = MIN( aspectRatio, 1.85f * 0.75f ); // cap out the FOV advantage at a 1.85:1 ratio (about the widest any legit user should be)
	    }

	    view.fov = ScaleFOVByWidthRatio( view.fov, limitedAspectRatio );
	    view.fovViewmodel = ScaleFOVByWidthRatio( view.fovViewmodel, aspectRatio );

	    // Let the client mode hook stuff.
	    g_pClientMode->PreRender(&view);

	    g_pClientMode->AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height );

	    ToolFramework_AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height );

	    float flViewportScale = mat_viewportscale.GetFloat();

		view.m_nUnscaledX = vr.x;
		view.m_nUnscaledY = vr.y;
		view.m_nUnscaledWidth = vr.width;
		view.m_nUnscaledHeight = vr.height;

        switch( eEye )
		{
			case STEREO_EYE_MONO:
			{
#if 0
                // Good test mode for debugging viewports that are not full-size.
	            view.width			= vr.width * flViewportScale * 0.75f;
	            view.height			= vr.height * flViewportScale * 0.75f;
	            view.x				= vr.x + view.width * 0.10f;
	            view.y				= vr.y + view.height * 0.20f;
#else
	            view.x				= vr.x * flViewportScale;
				view.y				= vr.y * flViewportScale;
				view.width			= vr.width * flViewportScale;
				view.height			= vr.height * flViewportScale;
#endif
			    float engineAspectRatio = engine->GetScreenAspectRatio();
			    view.m_flAspectRatio	= ( engineAspectRatio > 0.0f ) ? engineAspectRatio : ( (float)view.width / (float)view.height );
			}
			break;

			case STEREO_EYE_RIGHT:
			case STEREO_EYE_LEFT:
			{
				g_pSourceVR->GetViewportBounds( (ISourceVirtualReality::VREye)(eEye - 1 ), &view.x, &view.y, &view.width, &view.height );
				view.m_nUnscaledWidth = view.width;
				view.m_nUnscaledHeight = view.height;
				view.m_nUnscaledX = view.x;
				view.m_nUnscaledY = view.y;
			}
			break;

            default:
                Assert ( false );
                break;
		}

		// if we still don't have an aspect ratio, compute it from the view size
		if( view.m_flAspectRatio <= 0.f )
		    view.m_flAspectRatio	= (float)view.width / (float)view.height;

	    int nClearFlags = VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL;

	    if( gl_clear_randomcolor.GetBool() )
	    {
		    CMatRenderContextPtr pRenderContext( materials );
		    pRenderContext->ClearColor3ub( rand()%256, rand()%256, rand()%256 );
		    pRenderContext->ClearBuffers( true, false, false );
		    pRenderContext->Release();
	    }
	    else if ( gl_clear.GetBool() )
	    {
		    nClearFlags |= VIEW_CLEAR_COLOR;
	    }
	    else if ( IsPosix() )
	    {
		    MaterialAdapterInfo_t adapterInfo;
		    materials->GetDisplayAdapterInfo( materials->GetCurrentAdapter(), adapterInfo );

		    // On Posix, on ATI, we always clear color if we're antialiasing
		    if ( adapterInfo.m_VendorID == 0x1002 )
		    {
			    if ( g_pMaterialSystem->GetCurrentConfigForVideoCard().m_nAASamples > 0 )
			    {
				    nClearFlags |= VIEW_CLEAR_COLOR;
			    }
		    }
	    }

	    // Determine if we should draw view model ( client mode override )
	    bool drawViewModel = g_pClientMode->ShouldDrawViewModel();

	    if ( cl_leveloverview.GetFloat() > 0 )
	    {
		    SetUpOverView();		
		    nClearFlags |= VIEW_CLEAR_COLOR;
		    drawViewModel = false;
	    }

	    // Apply any player specific overrides
	    if ( pPlayer )
	    {
		    // Override view model if necessary
		    if ( !pPlayer->m_Local.m_bDrawViewmodel )
		    {
			    drawViewModel = false;
		    }
	    }

	    int flags = 0;
		if( eEye == STEREO_EYE_MONO || eEye == STEREO_EYE_LEFT || ( g_ClientVirtualReality.ShouldRenderHUDInWorld() ) )
		{
			flags = RENDERVIEW_DRAWHUD;
		}
	    if ( drawViewModel )
	    {
		    flags |= RENDERVIEW_DRAWVIEWMODEL;
	    }
		if( eEye == STEREO_EYE_RIGHT )
		{
			// we should use the monitor view from the left eye for both eyes
			flags |= RENDERVIEW_SUPPRESSMONITORRENDERING;
		}

	    RenderView( view, nClearFlags, flags );

		if ( UseVR() )
		{
			bool bDoUndistort = ! engine->IsTakingScreenshot();

			if ( bDoUndistort )
			{
				g_ClientVirtualReality.PostProcessFrame( eEye );
			}

			// logic here all cloned from code in viewrender.cpp around RenderHUDQuad:

			// figure out if we really want to draw the HUD based on freeze cam
			bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM );

			// draw the HUD after the view model so its "I'm closer" depth queues work right.
			if( !bInFreezeCam && g_ClientVirtualReality.ShouldRenderHUDInWorld() )
			{
				// TODO - a bit of a shonky test - basically trying to catch the main menu, the briefing screen, the loadout screen, etc.
				bool bTranslucent = !g_pMatSystemSurface->IsCursorVisible();
				g_ClientVirtualReality.OverlayHUDQuadWithUndistort( view, bDoUndistort, g_pClientMode->ShouldBlackoutAroundHUD(), bTranslucent );
			}
		}
    }


	// TODO: should these be inside or outside the stereo eye stuff?
	g_pClientMode->PostRender();
	engine->EngineStats_EndFrame();

#if !defined( _X360 )
	// Stop stubbing the material system so we can see the budget panel
	matStub.End();
#endif


	// Draw all of the UI stuff "fullscreen"
    // (this is not health, ammo, etc. Nor is it pre-game briefing interface stuff - this is the stuff that appears when you hit Esc in-game)
	// In stereo mode this is rendered inside of RenderView so it goes into the render target
	if( !g_ClientVirtualReality.ShouldRenderHUDInWorld() )
	{
		CViewSetup view2d;
		view2d.x				= rect->x;
		view2d.y				= rect->y;
		view2d.width			= rect->width;
		view2d.height			= rect->height;

		render->Push2DView( view2d, 0, NULL, GetFrustum() );
		render->VGui_Paint( PAINT_UIPANELS | PAINT_CURSOR );
		render->PopView( GetFrustum() );
	}


}
Пример #30
0
void CFlextalkActor::ProcessSceneEvents( void )
{
	if ( HasSceneEvents() )
	{
		BaseClass::ProcessSceneEvents( );
		return;
	}
	
	// only do this if they have more than eyelid movement
	if (GetNumFlexControllers() > 2)
	{
		const char *pszExpression = flex_expression.GetString();

		if (pszExpression && pszExpression[0] == '+' && pszExpression[1] != '\0')
		{
			int i;
			int j = atoi( &pszExpression[1] );
			for (i = 0; i < GetNumFlexControllers(); i++)
			{
				m_flextarget[m_flexnum] = 0;
			}

			for (i = 0; i < 35 && predef_flexcontroller_names[i]; i++)
			{
				m_flexnum = LookupFlex( predef_flexcontroller_names[i] );
				m_flextarget[m_flexnum] = predef_flexcontroller_values[j][i];
				// Msg( "%s %.3f\n", predef_flexcontroller_names[i], predef_flexcontroller_values[j][i] );
			}
		}
		else if (pszExpression && pszExpression[0] != '\0' && strcmp(pszExpression, "+") != 0)
		{
			char szExpression[128];
			char szTemp[32];

			Q_strncpy( szExpression, pszExpression ,sizeof(szExpression));
			char *pszExpression = szExpression;

			while (*pszExpression != '\0')
			{
				if (*pszExpression == '+')
					*pszExpression = ' ';
				
				pszExpression++;
			}

			pszExpression = szExpression;

			while (*pszExpression)
			{
				if (*pszExpression != ' ')
				{
					if (*pszExpression == '-')
					{
						for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++)
						{
							m_flextarget[i] = 0;
						}
					}
					else if (*pszExpression == '?')
					{
						for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++)
						{
							Msg( "\"%s\" ", GetFlexControllerName( i ) );
						}
						Msg( "\n" );
						flex_expression.SetValue( "" );
					}
					else
					{
						if (sscanf( pszExpression, "%31s", szTemp ) == 1)
						{
							m_flexnum = LookupFlex( szTemp );

							if (m_flexnum != LocalFlexController_t(-1) && m_flextarget[m_flexnum] != 1)
							{
								m_flextarget[m_flexnum] = 1.0;
								// SetFlexTarget( m_flexnum );
							}
							pszExpression += strlen( szTemp ) - 1;
						}
					}
				}
				pszExpression++;
			}
		} 
		else if (m_flextime < gpGlobals->curtime)
		{
			m_flextime = gpGlobals->curtime + random->RandomFloat( 0.3, 0.5 ) * (30.0 / GetNumFlexControllers());
			m_flexnum = (LocalFlexController_t)random->RandomInt( 0, GetNumFlexControllers() - 1 );

			if (m_flextarget[m_flexnum] == 1)
			{
				m_flextarget[m_flexnum] = 0;
			}
			else if (stricmp( GetFlexControllerType( m_flexnum ), "phoneme" ) != 0)
			{
				if (strstr( GetFlexControllerName( m_flexnum ), "upper_raiser" ) == NULL)
				{
					Msg( "%s:%s\n", GetFlexControllerType( m_flexnum ), GetFlexControllerName( m_flexnum ) );
					SetFlexTarget( m_flexnum, random->RandomFloat( 0.5, 1.0 ) );
				}
			}
		}

		// slide it up.
		for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++)
		{
			float weight = GetFlexWeight( i );

			if (weight != m_flextarget[i])
			{
				weight = weight + (m_flextarget[i] - weight) / random->RandomFloat( 2.0, 4.0 );
			}
			weight = clamp( weight, 0.0f, 1.0f );
			SetFlexWeight( i, weight );
		}

		if (flex_talk.GetInt() == -1)
		{
			m_istalking = 1;

			char pszSentence[256];
			Q_snprintf( pszSentence,sizeof(pszSentence), "%s%d", STRING(m_iszSentence), m_sentence++ );
			int sentenceIndex = engine->SentenceIndexFromName( pszSentence );
			if (sentenceIndex >= 0)
			{
				Msg( "%d : %s\n", sentenceIndex, pszSentence );
				CPASAttenuationFilter filter( this );
				CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, SNDLVL_TALKING, 0, PITCH_NORM );
			}
			else
			{
				m_sentence = 0;
			}

			flex_talk.SetValue( "0" );
		}
		else if (flex_talk.GetInt() == -2)
		{
			m_flNextEyeLookTime = gpGlobals->curtime + 1000.0;
		}
		else if (flex_talk.GetInt() == -3)
		{
			m_flNextEyeLookTime = gpGlobals->curtime;
			flex_talk.SetValue( "0" );
		}
		else if (flex_talk.GetInt() == -4)
		{
			AddLookTarget( UTIL_PlayerByIndex( 1 ), 0.5, flex_looktime.GetFloat()  );
			flex_talk.SetValue( "0" );
		}
		else if (flex_talk.GetInt() == -5)
		{
			PickLookTarget( true );
			flex_talk.SetValue( "0" );
		}
	}
}